Skip to content

feat: reusable odata#173

Draft
NicoleMGomes wants to merge 8 commits into
mainfrom
feat/poc-odata
Draft

feat: reusable odata#173
NicoleMGomes wants to merge 8 commits into
mainfrom
feat/poc-odata

Conversation

@NicoleMGomes

@NicoleMGomes NicoleMGomes commented Jun 19, 2026

Copy link
Copy Markdown
Contributor

Disclaimer: Do not include SAP-internal or customer-specific information in this PR (e.g. internal system URLs, customer names, tenant IDs, or confidential configurations). This is a public repository.

Description

Introduces a new sap_cloud_sdk.core.odata module that provides reusable, destination-aware OData v4 abstractions for the SAP Cloud SDK for Python. This PoC lays the foundation for typed, fluent OData clients without requiring code generation at runtime.

Key additions:

  • ODataHttpTransport — synchronous HTTP transport (requests-based) with automatic CSRF token fetching, retry on 403, and status-code–to-exception mapping.
  • AsyncODataHttpTransport — async mirror using httpx.AsyncClient, usable as an async context manager with concurrency-safe CSRF token caching.
  • odata_transport_from_destination — factory that wires a resolved BTP Destination into an ODataHttpTransport, inheriting its auth tokens and ERP headers.
  • ODataEntity — base dataclass for typed entity models (_entity_set, _key_fields, to_dict(), key_dict()).
  • Request builders — generic fluent CRUD builders: GetAllRequestBuilder, GetByKeyRequestBuilder, CreateRequestBuilder, UpdateRequestBuilder, DeleteRequestBuilder.
  • StructuredQuery — immutable OData v4 query parameter builder ($select, $filter, $orderby, $top, $skip, $expand, custom params).
  • FilterExpression — composable $filter DSL with field comparisons (eq, ne, lt, le, gt, ge, contains, startswith, endswith) and logical combinators (and_, or_, not_).
  • ODataPageIterator — server-driven pagination following @odata.nextLink.
  • CsrfTokenProvider — synchronous CSRF token provider with lazy fetch and invalidation.
  • Exception hierarchyODataError, ODataRequestError, ODataNotFoundError, ODataAuthError, ODataDeserializationError, ODataCsrfError.
  • Module.ODATA telemetry enum value added.
  • Two design proposal documents in docs/proposals/.
  • Unit test suite covering all components.

Related Issue

Closes #

Type of Change

  • Bug fix (non-breaking change that fixes an issue)
  • New feature (non-breaking change that adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation update
  • Code refactoring
  • Dependency update

How to Test

  1. Install the package: uv sync
  2. Run the OData unit tests:
    uv run pytest tests/core/unit/odata/ -v
    
  3. To exercise the transport manually, construct an ODataHttpTransport with a requests.Session pointing at any OData v4 service and call GetAllRequestBuilder(transport, MyEntity).top(5).execute().
  4. To test the destination integration, resolve a BTP HTTP destination and call odata_transport_from_destination(destination).
  5. Verify all existing tests still pass: uv run pytest

Checklist

  • I have read the Contributing Guidelines
  • I have verified that my changes solve the issue
  • I have added/updated automated tests to cover my changes
  • All tests pass locally
  • I have verified that my code follows the Code Guidelines
  • I have updated documentation (if applicable)
  • I have added type hints for all public APIs
  • My code does not contain sensitive information (credentials, tokens, etc.)
  • I have followed Conventional Commits for commit messages

Additional Notes

This is a PoC / foundational PR. The public API surface (especially request builders and entity base class) is intentionally minimal and may evolve based on feedback before a stable release. The docs/proposals/ documents capture the longer-term vision for code generation and client abstractions.

@NicoleMGomes NicoleMGomes changed the title feat: Reusable OData feat: reusable odata Jun 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant