Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
76 commits
Select commit Hold shift + click to select a range
833312e
feat(adms): add SAP ADMS module with sync/async clients and BDD tests
adwitiyasushant May 26, 2026
13e5a5d
chore: bump version to 0.20.0 for ADMS module
adwitiyasushant May 26, 2026
197ed7b
chore(adms): scope pytest config to ADMS and extract mount-path constant
adwitiyasushant May 26, 2026
74a9909
chore: bump version to 0.20.1 after rebase onto upstream
adwitiyasushant May 26, 2026
9d9aba2
fix(adms/tests): mark async http client tests with pytest.mark.asyncio
adwitiyasushant May 26, 2026
d18d875
docs(adms): replace stale "DMS" references with "ADMS" in module docs…
adwitiyasushant May 27, 2026
d66078f
docs(adms): document integration test env vars and fix wrong field names
adwitiyasushant May 27, 2026
6d85c69
refactor(adms): address PR review feedback
adwitiyasushant May 29, 2026
b7d37e5
docs(adms): merge ADMS integration test docs into canonical guide
adwitiyasushant May 29, 2026
c06d43d
chore(adms): drop scripts/adms_cli.py from repo
adwitiyasushant May 29, 2026
5e43295
refactor(adms): align integration tests with standard CLOUD_SDK_CFG_*…
adwitiyasushant May 29, 2026
27a9ccc
fix(adms/tests): build concurrent coroutines inside the run_async loop
adwitiyasushant May 29, 2026
75f7736
docs(adms): replace personal name with generic placeholder in config …
adwitiyasushant May 29, 2026
5c0fa30
docs(adms): replace internal provisioning references in module docstring
adwitiyasushant May 29, 2026
7ad3b54
refactor(adms): properly type IasTokenFetcher.config parameter
adwitiyasushant May 29, 2026
a25bb0c
refactor(adms): remove duplicate HttpError import in _http.py
adwitiyasushant May 29, 2026
f32b705
style(adms): sort ScanStatus enum members alphabetically
adwitiyasushant May 29, 2026
3ee3da3
style(adms): sort JobType and JobStatus enum members alphabetically
adwitiyasushant May 29, 2026
76015c2
refactor(adms): import TokenCache from public core.auth path
adwitiyasushant May 29, 2026
d445fb9
docs(adms): minor wording cleanups in _models and user-guide
adwitiyasushant May 29, 2026
02a3df7
refactor(core/auth): rename mTLS* classes and drop unused client param
adwitiyasushant May 29, 2026
f13b833
refactor(core/auth): remove private constants from public __all__
adwitiyasushant May 29, 2026
ac41b57
Merge remote-tracking branch 'upstream/main' into contrib/adms
adwitiyasushant May 29, 2026
a2a9446
fix(ci): narrow async closure types and bump version to 0.22.0
adwitiyasushant May 29, 2026
042dde7
docs(adms): add docstrings to async API methods and align module naming
adwitiyasushant May 29, 2026
af71018
docs(core/auth): generalize mTLS module docstring wording
adwitiyasushant May 29, 2026
5e373dc
docs(adms): fix AdmsConfig parameter names in user-guide example
adwitiyasushant May 29, 2026
52e870f
Merge branch 'main' into contrib/adms
adwitiyasushant May 29, 2026
ac2794d
chore: bump version to 0.23.0
adwitiyasushant May 29, 2026
886b5f5
refactor(adms): drop redundant TokenCache re-export
adwitiyasushant May 29, 2026
b0e1089
chore(core/auth): add py.typed marker for PEP 561
adwitiyasushant Jun 2, 2026
16a6ec8
fix(adms): retry once on 403 with fresh CSRF token
adwitiyasushant Jun 2, 2026
12baf5c
fix(adms): share httpx client in with_user_jwt to prevent connection …
adwitiyasushant Jun 2, 2026
8c13585
refactor(core/auth): extract IAS token request timeout to named constant
adwitiyasushant Jun 2, 2026
ec9a502
refactor(adms): tidy __all__ ordering and drop defensive getattr
adwitiyasushant Jun 2, 2026
da70d1c
fix(adms): add use_admin_service parameter to async get_status
adwitiyasushant Jun 2, 2026
49e17e6
fix(adms): escape OData V4 string keys to prevent injection
adwitiyasushant Jun 2, 2026
0aa92bc
fix(adms): guard CSRF token cache for thread/coroutine safety
adwitiyasushant Jun 2, 2026
d31d1ea
fix(core/adms): harden error handling in IAS, async HTTP, and CSRF paths
adwitiyasushant Jun 2, 2026
43b4271
fix(core/auth): log Redis cache failures at WARNING
adwitiyasushant Jun 2, 2026
7a2ed1d
docs(adms/models): add docstrings to public to_odata_dict methods
adwitiyasushant Jun 2, 2026
61fe629
refactor(adms): drop broad except in factories, simplify _BindingData
adwitiyasushant Jun 2, 2026
9d7b5ca
refactor(core/auth): add explicit close() and context manager to MTLS…
adwitiyasushant Jun 2, 2026
d3db579
test(core,adms): cover aclose idempotency, exception-path cleanup, OB…
adwitiyasushant Jun 2, 2026
d89c64c
fix(adms): validate Edm.Guid keys before URL interpolation
adwitiyasushant Jun 3, 2026
3d1ed4a
Merge remote-tracking branch 'upstream/main' into contrib/adms
adwitiyasushant Jun 3, 2026
8185542
chore: bump version to 0.23.2 and reformat adms client imports
adwitiyasushant Jun 3, 2026
341c857
refactor(adms): move infrastructure from core/ into adms/ package
adwitiyasushant Jun 4, 2026
bf5d0ce
refactor(adms): drop vestigial _auth wrapper around IasTokenFetcher
adwitiyasushant Jun 4, 2026
50a551a
refactor(adms): encapsulate OData query params in tiered options classes
adwitiyasushant Jun 9, 2026
4b482b9
revert(objectstore): restore conftest.py from upstream/main
adwitiyasushant Jun 9, 2026
e82c583
refactor(adms): drop RedisTokenCache; keep pluggable TokenCache only
adwitiyasushant Jun 9, 2026
e67c0e7
refactor(adms): centralize OData entity-key URL builders in _http.py
adwitiyasushant Jun 9, 2026
ba153a0
refactor(adms): split client.py by entity for navigability
adwitiyasushant Jun 9, 2026
2f4f8c1
style(adms): apply ruff format; revert other-module test changes
adwitiyasushant Jun 9, 2026
646d77e
revert(dms): restore conftest.py # ty: ignore comment per reviewer
adwitiyasushant Jun 9, 2026
9fa11c9
style(adms): remove unused imports flagged by ruff F401
adwitiyasushant Jun 9, 2026
976df88
fix(adms): route documents.get_all() via DocumentRelation?$expand=Doc…
adwitiyasushant Jun 9, 2026
37b1d84
chore: merge upstream/main (bump version 0.23.2 → 0.25.0)
adwitiyasushant Jun 9, 2026
2fd61ba
fix(adms): narrow dict type in get_all to satisfy ty; bump to 0.25.1
adwitiyasushant Jun 9, 2026
8a9be26
feat(adms): add missing DocumentRelation fields visible in live API r…
adwitiyasushant Jun 10, 2026
ec11d75
feat(adms): surface ADM error messages; add audit fields to config mo…
adwitiyasushant Jun 10, 2026
7ae233f
feat(adms): add DraftAdministrativeData model to DocumentRelation
adwitiyasushant Jun 10, 2026
a790fb5
feat(adms): add get-by-id and update (PATCH) to all config entities
adwitiyasushant Jun 10, 2026
09ec712
fix(adms): return full Document after update; add DocumentStateText +…
adwitiyasushant Jun 10, 2026
1b376d7
fix(adms): align config entity models with CDS — remove phantom audit…
adwitiyasushant Jun 10, 2026
e7e3434
feat(adms): implement 6 missing APIs + full-upload CLI command
adwitiyasushant Jun 10, 2026
e1a4c33
fix(adms): correct BusinessObjectNodeType field name and required fields
adwitiyasushant Jun 10, 2026
b153300
style(adms): apply ruff format to _configuration_api.py
adwitiyasushant Jun 10, 2026
796ce64
Merge branch 'main' into contrib/adms
ArthurTonial Jun 11, 2026
9755bf7
fix(adms): resolve pre-commit ty errors after ty version upgrade
adwitiyasushant Jun 11, 2026
144e727
fix(adms): use ty: ignore syntax; restore .gitignore ADMS entries
adwitiyasushant Jun 11, 2026
5b55049
fix(adms): change size_in_byte fields from float to int
adwitiyasushant Jun 11, 2026
ff33498
chore: trim .gitignore — remove machine-specific and cross-repo entries
adwitiyasushant Jun 11, 2026
37a86f9
chore: remove redundant .env.adms from .gitignore
adwitiyasushant Jun 11, 2026
3d69bfb
fix(deps): update greenlet to 3.5.1 and add missing wheel URLs
ArthurTonial Jun 11, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .env_integration_tests.example
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,14 @@ CLOUD_SDK_CFG_SDM_DEFAULT_UAA='{"url":"https://your-auth-url","clientid":"your-c
CLOUD_SDK_CFG_HANA_AGENT_MEMORY_DEFAULT_APPLICATION_URL=https://your-agent-memory-api-url-here
CLOUD_SDK_CFG_HANA_AGENT_MEMORY_DEFAULT_UAA='{"url":"https://your-auth-url","clientid":"your-client-id","clientsecret":"your-client-secret"}'

# ADMS (Advanced Document Management Service) — integration tests against
# a deployed ADM instance. Tests are skipped when any of these are missing.
CLOUD_SDK_CFG_ADMS_DEFAULT_CLIENTID=your-adms-client-id-here
CLOUD_SDK_CFG_ADMS_DEFAULT_CLIENTSECRET=your-adms-client-secret-here
CLOUD_SDK_CFG_ADMS_DEFAULT_URL=https://your-tenant.accounts.ondemand.com
CLOUD_SDK_CFG_ADMS_DEFAULT_URI=https://your-adm-host.cfapps.eu20.hana.ondemand.com
CLOUD_SDK_CFG_ADMS_DEFAULT_RESOURCE=urn:sap:identity:application:provider:name:your-adm-app-name

APPFND_CONHOS_LANDSCAPE=your-landscape-here
TENANT_SUBDOMAIN=your-tenant-subdomain-here
AGW_USER_TOKEN=your-user-jwt-here
Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,6 @@ mocks/
# Generated files
PULL_REQUEST.md
RELEASE.md

# macOS metadata
.DS_Store
16 changes: 16 additions & 0 deletions docs/INTEGRATION_TESTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,21 @@ CLOUD_SDK_CFG_DATA_ANONYMIZATION_DEFAULT_DESTINATION_NAME=your-client-certificat

The destination must be configured with `ClientCertificateAuthentication` and reference a certificate bundle containing the client certificate and private key.

### ADMS Integration Tests

For ADMS (Advanced Document Management Service) integration tests, configure the following variables in `.env_integration_tests`:

```bash
# ADMS Configuration
CLOUD_SDK_CFG_ADMS_DEFAULT_URL=https://your-tenant.accounts.ondemand.com
CLOUD_SDK_CFG_ADMS_DEFAULT_URI=https://your-adm-instance.cfapps.eu20.hana.ondemand.com
CLOUD_SDK_CFG_ADMS_DEFAULT_CLIENTID=your-ias-client-id
CLOUD_SDK_CFG_ADMS_DEFAULT_CLIENTSECRET=your-ias-client-secret
CLOUD_SDK_CFG_ADMS_DEFAULT_RESOURCE=urn:sap:identity:application:provider:name:your-app
```

`CLOUD_SDK_CFG_ADMS_DEFAULT_URI` points the tests at the target ADM service. The other `CLOUD_SDK_CFG_ADMS_DEFAULT_*` variables hold the IAS service-binding credentials used by the SDK to fetch Bearer tokens. Tests are skipped automatically when any of these are missing.

### Agent Gateway Integration Tests

Agent Gateway integration tests use the LoB agent flow via the Destination Service. Configure the following variables in `.env_integration_tests`:
Expand Down Expand Up @@ -131,6 +146,7 @@ uv run pytest tests/core/integration/data_anonymization -v
uv run pytest tests/objectstore/integration/ -v
uv run pytest tests/destination/integration/ -v
uv run pytest tests/agent_memory/integration/ -v
uv run pytest tests/adms/integration/ -v
uv run pytest tests/agentgateway/integration/ -v
```

Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "sap-cloud-sdk"
version = "0.25.2"
version = "0.26.0"
description = "SAP Cloud SDK for Python"
readme = "README.md"
license = "Apache-2.0"
Expand Down
152 changes: 152 additions & 0 deletions src/sap_cloud_sdk/adms/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
"""SAP Cloud SDK for Python — ADMS (Advanced Document Management Service) module.

Provides a typed, high-level Python client for the SAP ADM OData V4 service.

ADM is a **BTP Shared SaaS Application** (IAS-based multi-tenant service).
It must be provisioned as a BTP service instance before use.

Quick start::

from sap_cloud_sdk.adms import (
create_client,
BaseType,
CreateDocumentInput,
CreateDocumentRelationInput,
)

# Reads binding from /etc/secrets/appfnd/adms/default/ or env vars
client = create_client("default")

# Link a document to a business object
relation = client.relations.create(
CreateDocumentRelationInput(
business_object_node_type_unique_id="PurchaseOrder",
host_business_object_node_id="PO-4500012345",
document=CreateDocumentInput(
document_name="Invoice.pdf",
document_base_type=BaseType.DOCUMENT,
document_type_id="INVOICE",
),
is_active_entity=False,
)
)
# Upload bytes to presigned URL (outside SDK)
import requests
requests.put(relation.document.document_content_upload_urls[0], data=open("f.pdf","rb"))
"""

from __future__ import annotations

from sap_cloud_sdk.adms.client import (
AdmsClient,
AsyncAdmsClient,
create_client,
create_async_client,
)
from sap_cloud_sdk.adms.config import AdmsConfig
from sap_cloud_sdk.adms.exceptions import (
AuthError,
ClientCreationError,
ConfigError,
AdmsError,
AdmsOperationError,
DocumentNotFoundError,
HttpError,
ScanNotCleanError,
)
from sap_cloud_sdk.adms._models import (
AllowedDomain,
BaseType,
BusinessObjectNodeType,
CreateAllowedDomainInput,
CreateBusinessObjectNodeTypeInput,
CreateDocumentTypeBoTypeMapInput,
CreateDocumentInput,
CreateDocumentRelationInput,
CreateDocumentTypeInput,
DeleteUserDataJobParameters,
Document,
DocumentContentVersion,
DocumentRelation,
DocumentType,
DocumentTypeBusinessObjectTypeMap,
DocumentTypeText,
DraftActivateInput,
DraftAdministrativeData,
DraftInput,
JobInput,
JobOutput,
JobStatus,
JobType,
ScanStatus,
UpdateAllowedDomainInput,
UpdateBusinessObjectNodeTypeInput,
UpdateDocumentInput,
UpdateDocumentTypeInput,
ZipDownloadJobParameters,
)
from sap_cloud_sdk.adms._query_options import (
ConfigQueryOptions,
DocumentQueryOptions,
RelationQueryOptions,
)
from sap_cloud_sdk.adms._token_cache import InMemoryTokenCache, TokenCache


__all__ = [
# factories
"create_client",
"create_async_client",
# clients
"AdmsClient",
"AsyncAdmsClient",
# config
"AdmsConfig",
# exceptions
"AdmsError",
"AdmsOperationError",
"AuthError",
"ClientCreationError",
"ConfigError",
"DocumentNotFoundError",
"HttpError",
"ScanNotCleanError",
# models — core
"BaseType",
"CreateDocumentInput",
"CreateDocumentRelationInput",
"DeleteUserDataJobParameters",
"Document",
"DocumentContentVersion",
"DocumentRelation",
"DraftActivateInput",
"DraftAdministrativeData",
"DraftInput",
"JobInput",
"JobOutput",
"JobStatus",
"JobType",
"ScanStatus",
"UpdateDocumentInput",
"ZipDownloadJobParameters",
# models — config
"AllowedDomain",
"BusinessObjectNodeType",
"CreateAllowedDomainInput",
"CreateBusinessObjectNodeTypeInput",
"UpdateAllowedDomainInput",
"UpdateBusinessObjectNodeTypeInput",
"UpdateDocumentTypeInput",
"CreateDocumentTypeBoTypeMapInput",
"CreateDocumentTypeInput",
"DocumentType",
"DocumentTypeBusinessObjectTypeMap",
"DocumentTypeText",
# query options
"ConfigQueryOptions",
"DocumentQueryOptions",
"RelationQueryOptions",
# token cache
"TokenCache",
"InMemoryTokenCache",
]
Loading
Loading