Provide a high-performance, async-first, and metadata-driven Python SDK for SAP Business One Service Layer.
- Package Manager: Use
uvexclusively. - Virtual Env: Located at
.venv/in the repository root. - Python Version: 3.11+.
- Main Commands:
uv sync: Install dependencies.make test: Run unit tests.make test-vcr: Run integration tests with recorded cassettes.make lint: Run Ruff and Mypy.
src/b1sl/: The core package. This is what gets published to PyPI.src/b1sl/b1sl/is the Service Layer SDK;src/b1sl/api_gateway/is the companion API Gateway client (Crystal Reports → PDF, sync + async, opt-in import — seedocs/20-api-gateway.md).scripts/sap_metadata_generator/: The engine that generates models and resources from OData XML/JSON metadata.metadata/: Versioned SAP metadata files (XML, JSON, HTML)._generated/folders: NEVER edit files inside these. Any change must be done in the generator script or as an override in_overrides/.
- GitHub vs PyPI: Documentation, examples, scripts, agents context, and skills are excluded from the PyPI wheel.
- Versioning: Uses Semantic Versioning (SemVer)
vMAJOR.MINOR.PATCH. - Release Flow:
make release v=X.Y.Z(Commits, tags, and pushes).- GitHub Actions (
publish.yml) triggers on tag to publish to PyPI.
-
English Only: All comments, documentation, and commits must be in English.
-
Metadata Priority: If the user asks for a new field or entity, check if it's in the metadata first. If missing, update metadata and regenerate.
-
Pydantic v2: Everything is built on Pydantic v2.
-
Testing: Always run
make testbefore proposing a change. Integration tests (make test-vcr) should be verified if network logic changes. -
Linting & Typing:
- Use
make lintto validate the entire repository (parity with CI). _generatedfolders are excluded from strict checking; any errors should be fixed in the generator or via overrides.
- Use
-
Resource Access (Elite vs Generic):
- Tier 1 (Elite Aliases): Only a core subset of entities with direct SAP ETag support (e.g.,
client.items,client.business_partners) have direct properties on the client. - Standard (Generic Access): All other entities MUST use the
get_resource(Model, "Path")pattern. This signals that ETag concurrency protection is NOT guaranteed.
- Tier 1 (Elite Aliases): Only a core subset of entities with direct SAP ETag support (e.g.,
-
Architectural Principles:
- Vanilla Policy: Models must be version-agnostic (Vanilla) and compatible with Generic Resource Access.
- Async/Sync Symmetry: Every
GenericResourcemust have anAsyncGenericResourcecounterpart. FluentQueryBuilderandAsyncQueryBuildermust support the same parameters. - Reliable Mutation (ETag Invalidation): SAP SL returns
204 No Contenton PATCH/DELETE without a new ETag header. Everyupdate()must proactively invalidate (clear) the cached ETag in the adapter. - Status-Code Mapping: Adapters must map HTTP status codes to semantic exceptions (e.g., 404 ->
B1NotFoundError) using a standardized mapping dictionary. - Surgical Deltas: Encourage users (and agents) to create fresh, minimal model instances for updates to ensure clean PATCH payloads.
-
Generated Code Policy:
- NEVER edit files in
_generated/folders. - Use overrides in
_overrides/to inject custom logic or fix model resolution issues (e.g., usingmodel_rebuild()).
- NEVER edit files in
-
Batch & Transactional Context:
- Proxy-Recording Pattern:
BatchClientuses aResourceProxyto intercept resource calls. It stores them in a_pendingqueue instead of executing them immediately. - Atomic vs. Independent: $batch supports both independent operations (partial success) and
changeset()(atomic rollback). - No-Exception Policy:
batch.execute()MUST NOT raise exceptions for individual operation failures. This is the "Defensive Analysis" pattern essential for handling partial successes. - Future Maintenance:
- Streaming Parser: The current
BatchParseruses line-scanning. For extremely large batches (>100 operations), consider implementing a streaming multipart parser to reduce memory overhead. - Binary/Media Support: Currently, batch handles JSON payloads. Future agents should consider how to handle multipart/form-data attachments inside a $batch if SAP supports it.
- Traceability: Always maintain the
r.indexproperty in results to allow mapping back to the original request order.
- Streaming Parser: The current
- Proxy-Recording Pattern: