Skip to content

Commit a790fb5

Browse files
feat(adms): add get-by-id and update (PATCH) to all config entities
AllowedDomain, DocumentType, BusinessObjectNodeType, and DocumentTypeBusinessObjectTypeMap were each missing two operations visible in the live API (GET by key, PATCH): config.get_allowed_domain(id) → GET AllowedDomain(id) config.update_allowed_domain(id, input) → PATCH AllowedDomain(id) config.get_document_type(id) config.update_document_type(id, input) config.get_business_object_type(id) config.update_business_object_type(id, input) config.get_type_mapping(id) → GET TypeMap(id) All 8 methods have sync + async variants. Three new Update*Input dataclasses model the PATCH payload (only non-None fields sent). Eight new Operation enum entries; total adms operations 33 → 40 → 131.
1 parent 7ae233f commit a790fb5

5 files changed

Lines changed: 252 additions & 2 deletions

File tree

src/sap_cloud_sdk/adms/__init__.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,10 @@
7979
JobStatus,
8080
JobType,
8181
ScanStatus,
82+
UpdateAllowedDomainInput,
83+
UpdateBusinessObjectNodeTypeInput,
8284
UpdateDocumentInput,
85+
UpdateDocumentTypeInput,
8386
ZipDownloadJobParameters,
8487
)
8588
from sap_cloud_sdk.adms._query_options import (
@@ -131,6 +134,9 @@
131134
"BusinessObjectNodeType",
132135
"CreateAllowedDomainInput",
133136
"CreateBusinessObjectNodeTypeInput",
137+
"UpdateAllowedDomainInput",
138+
"UpdateBusinessObjectNodeTypeInput",
139+
"UpdateDocumentTypeInput",
134140
"CreateDocumentTypeBoTypeMapInput",
135141
"CreateDocumentTypeInput",
136142
"DocumentType",

src/sap_cloud_sdk/adms/_configuration_api.py

Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@
2020
CreateDocumentTypeInput,
2121
DocumentType,
2222
DocumentTypeBusinessObjectTypeMap,
23+
UpdateAllowedDomainInput,
24+
UpdateBusinessObjectNodeTypeInput,
25+
UpdateDocumentTypeInput,
2326
)
2427
from sap_cloud_sdk.adms._query_options import ConfigQueryOptions
2528
from sap_cloud_sdk.adms.config import _CONFIG_SERVICE_PATH
@@ -57,6 +60,27 @@ def create_allowed_domain(self, payload: CreateAllowedDomainInput) -> AllowedDom
5760
)
5861
return AllowedDomain.from_dict(resp.json())
5962

63+
@record_metrics(Module.ADMS, Operation.ADMS_CONFIG_GET_ALLOWED_DOMAIN)
64+
def get_allowed_domain(self, allowed_domain_id: str) -> AllowedDomain:
65+
"""Fetch a single AllowedDomain by its UUID."""
66+
resp = self._http.get(
67+
build_allowed_domain_key_path(allowed_domain_id),
68+
service_base=_CONFIG_SERVICE_PATH,
69+
)
70+
return AllowedDomain.from_dict(resp.json())
71+
72+
@record_metrics(Module.ADMS, Operation.ADMS_CONFIG_UPDATE_ALLOWED_DOMAIN)
73+
def update_allowed_domain(
74+
self, allowed_domain_id: str, payload: UpdateAllowedDomainInput
75+
) -> AllowedDomain:
76+
"""Update an existing AllowedDomain entry (PATCH — only sent fields change)."""
77+
resp = self._http.patch(
78+
build_allowed_domain_key_path(allowed_domain_id),
79+
json=payload.to_odata_dict(),
80+
service_base=_CONFIG_SERVICE_PATH,
81+
)
82+
return AllowedDomain.from_dict(resp.json())
83+
6084
@record_metrics(Module.ADMS, Operation.ADMS_CONFIG_DELETE_ALLOWED_DOMAIN)
6185
def delete_allowed_domain(self, allowed_domain_id: str) -> None:
6286
"""Remove an entry from the domain allow-list."""
@@ -87,6 +111,27 @@ def create_document_type(self, payload: CreateDocumentTypeInput) -> DocumentType
87111
)
88112
return DocumentType.from_dict(resp.json())
89113

114+
@record_metrics(Module.ADMS, Operation.ADMS_CONFIG_GET_DOCUMENT_TYPE)
115+
def get_document_type(self, document_type_id: str) -> DocumentType:
116+
"""Fetch a single DocumentType by its ID."""
117+
resp = self._http.get(
118+
build_document_type_key_path(document_type_id),
119+
service_base=_CONFIG_SERVICE_PATH,
120+
)
121+
return DocumentType.from_dict(resp.json())
122+
123+
@record_metrics(Module.ADMS, Operation.ADMS_CONFIG_UPDATE_DOCUMENT_TYPE)
124+
def update_document_type(
125+
self, document_type_id: str, payload: UpdateDocumentTypeInput
126+
) -> DocumentType:
127+
"""Update an existing DocumentType (PATCH — only sent fields change)."""
128+
resp = self._http.patch(
129+
build_document_type_key_path(document_type_id),
130+
json=payload.to_odata_dict(),
131+
service_base=_CONFIG_SERVICE_PATH,
132+
)
133+
return DocumentType.from_dict(resp.json())
134+
90135
@record_metrics(Module.ADMS, Operation.ADMS_CONFIG_DELETE_DOCUMENT_TYPE)
91136
def delete_document_type(self, document_type_id: str) -> None:
92137
"""Delete a document type classification."""
@@ -122,6 +167,35 @@ def create_business_object_type(
122167
)
123168
return BusinessObjectNodeType.from_dict(resp.json())
124169

170+
@record_metrics(Module.ADMS, Operation.ADMS_CONFIG_GET_BUSINESS_OBJECT_TYPE)
171+
def get_business_object_type(
172+
self, business_object_node_type_unique_id: str
173+
) -> BusinessObjectNodeType:
174+
"""Fetch a single BusinessObjectNodeType by its unique ID."""
175+
resp = self._http.get(
176+
build_business_object_node_type_key_path(
177+
business_object_node_type_unique_id
178+
),
179+
service_base=_CONFIG_SERVICE_PATH,
180+
)
181+
return BusinessObjectNodeType.from_dict(resp.json())
182+
183+
@record_metrics(Module.ADMS, Operation.ADMS_CONFIG_UPDATE_BUSINESS_OBJECT_TYPE)
184+
def update_business_object_type(
185+
self,
186+
business_object_node_type_unique_id: str,
187+
payload: UpdateBusinessObjectNodeTypeInput,
188+
) -> BusinessObjectNodeType:
189+
"""Update an existing BusinessObjectNodeType (PATCH)."""
190+
resp = self._http.patch(
191+
build_business_object_node_type_key_path(
192+
business_object_node_type_unique_id
193+
),
194+
json=payload.to_odata_dict(),
195+
service_base=_CONFIG_SERVICE_PATH,
196+
)
197+
return BusinessObjectNodeType.from_dict(resp.json())
198+
125199
@record_metrics(Module.ADMS, Operation.ADMS_CONFIG_DELETE_BUSINESS_OBJECT_TYPE)
126200
def delete_business_object_type(
127201
self, business_object_node_type_unique_id: str
@@ -163,6 +237,17 @@ def create_type_mapping(
163237
)
164238
return DocumentTypeBusinessObjectTypeMap.from_dict(resp.json())
165239

240+
@record_metrics(Module.ADMS, Operation.ADMS_CONFIG_GET_DOCTYPE_BOTYPE_MAP)
241+
def get_type_mapping(
242+
self, document_type_bo_type_map_id: str
243+
) -> DocumentTypeBusinessObjectTypeMap:
244+
"""Fetch a single DocumentType ↔ BusinessObjectNodeType mapping by its UUID."""
245+
resp = self._http.get(
246+
build_doctype_botype_map_key_path(document_type_bo_type_map_id),
247+
service_base=_CONFIG_SERVICE_PATH,
248+
)
249+
return DocumentTypeBusinessObjectTypeMap.from_dict(resp.json())
250+
166251
@record_metrics(Module.ADMS, Operation.ADMS_CONFIG_DELETE_DOCTYPE_BOTYPE_MAP)
167252
def delete_type_mapping(self, document_type_bo_type_map_id: str) -> None:
168253
"""Delete a DocumentType ↔ BusinessObjectNodeType mapping."""
@@ -205,6 +290,27 @@ async def create_allowed_domain(
205290
)
206291
return AllowedDomain.from_dict(resp.json())
207292

293+
@record_metrics(Module.ADMS, Operation.ADMS_CONFIG_GET_ALLOWED_DOMAIN)
294+
async def get_allowed_domain(self, allowed_domain_id: str) -> AllowedDomain:
295+
"""Async variant of :meth:`_ConfigurationApi.get_allowed_domain` — same semantics."""
296+
resp = await self._http.get(
297+
build_allowed_domain_key_path(allowed_domain_id),
298+
service_base=_CONFIG_SERVICE_PATH,
299+
)
300+
return AllowedDomain.from_dict(resp.json())
301+
302+
@record_metrics(Module.ADMS, Operation.ADMS_CONFIG_UPDATE_ALLOWED_DOMAIN)
303+
async def update_allowed_domain(
304+
self, allowed_domain_id: str, payload: UpdateAllowedDomainInput
305+
) -> AllowedDomain:
306+
"""Async variant of :meth:`_ConfigurationApi.update_allowed_domain` — same semantics."""
307+
resp = await self._http.patch(
308+
build_allowed_domain_key_path(allowed_domain_id),
309+
json=payload.to_odata_dict(),
310+
service_base=_CONFIG_SERVICE_PATH,
311+
)
312+
return AllowedDomain.from_dict(resp.json())
313+
208314
@record_metrics(Module.ADMS, Operation.ADMS_CONFIG_DELETE_ALLOWED_DOMAIN)
209315
async def delete_allowed_domain(self, allowed_domain_id: str) -> None:
210316
"""Async variant of :meth:`_ConfigurationApi.delete_allowed_domain` — same semantics."""
@@ -237,6 +343,27 @@ async def create_document_type(
237343
)
238344
return DocumentType.from_dict(resp.json())
239345

346+
@record_metrics(Module.ADMS, Operation.ADMS_CONFIG_GET_DOCUMENT_TYPE)
347+
async def get_document_type(self, document_type_id: str) -> DocumentType:
348+
"""Async variant of :meth:`_ConfigurationApi.get_document_type` — same semantics."""
349+
resp = await self._http.get(
350+
build_document_type_key_path(document_type_id),
351+
service_base=_CONFIG_SERVICE_PATH,
352+
)
353+
return DocumentType.from_dict(resp.json())
354+
355+
@record_metrics(Module.ADMS, Operation.ADMS_CONFIG_UPDATE_DOCUMENT_TYPE)
356+
async def update_document_type(
357+
self, document_type_id: str, payload: UpdateDocumentTypeInput
358+
) -> DocumentType:
359+
"""Async variant of :meth:`_ConfigurationApi.update_document_type` — same semantics."""
360+
resp = await self._http.patch(
361+
build_document_type_key_path(document_type_id),
362+
json=payload.to_odata_dict(),
363+
service_base=_CONFIG_SERVICE_PATH,
364+
)
365+
return DocumentType.from_dict(resp.json())
366+
240367
@record_metrics(Module.ADMS, Operation.ADMS_CONFIG_DELETE_DOCUMENT_TYPE)
241368
async def delete_document_type(self, document_type_id: str) -> None:
242369
"""Async variant of :meth:`_ConfigurationApi.delete_document_type` — same semantics."""
@@ -272,6 +399,35 @@ async def create_business_object_type(
272399
)
273400
return BusinessObjectNodeType.from_dict(resp.json())
274401

402+
@record_metrics(Module.ADMS, Operation.ADMS_CONFIG_GET_BUSINESS_OBJECT_TYPE)
403+
async def get_business_object_type(
404+
self, business_object_node_type_unique_id: str
405+
) -> BusinessObjectNodeType:
406+
"""Async variant of :meth:`_ConfigurationApi.get_business_object_type` — same semantics."""
407+
resp = await self._http.get(
408+
build_business_object_node_type_key_path(
409+
business_object_node_type_unique_id
410+
),
411+
service_base=_CONFIG_SERVICE_PATH,
412+
)
413+
return BusinessObjectNodeType.from_dict(resp.json())
414+
415+
@record_metrics(Module.ADMS, Operation.ADMS_CONFIG_UPDATE_BUSINESS_OBJECT_TYPE)
416+
async def update_business_object_type(
417+
self,
418+
business_object_node_type_unique_id: str,
419+
payload: UpdateBusinessObjectNodeTypeInput,
420+
) -> BusinessObjectNodeType:
421+
"""Async variant of :meth:`_ConfigurationApi.update_business_object_type` — same semantics."""
422+
resp = await self._http.patch(
423+
build_business_object_node_type_key_path(
424+
business_object_node_type_unique_id
425+
),
426+
json=payload.to_odata_dict(),
427+
service_base=_CONFIG_SERVICE_PATH,
428+
)
429+
return BusinessObjectNodeType.from_dict(resp.json())
430+
275431
@record_metrics(Module.ADMS, Operation.ADMS_CONFIG_DELETE_BUSINESS_OBJECT_TYPE)
276432
async def delete_business_object_type(
277433
self, business_object_node_type_unique_id: str
@@ -313,6 +469,17 @@ async def create_type_mapping(
313469
)
314470
return DocumentTypeBusinessObjectTypeMap.from_dict(resp.json())
315471

472+
@record_metrics(Module.ADMS, Operation.ADMS_CONFIG_GET_DOCTYPE_BOTYPE_MAP)
473+
async def get_type_mapping(
474+
self, document_type_bo_type_map_id: str
475+
) -> DocumentTypeBusinessObjectTypeMap:
476+
"""Async variant of :meth:`_ConfigurationApi.get_type_mapping` — same semantics."""
477+
resp = await self._http.get(
478+
build_doctype_botype_map_key_path(document_type_bo_type_map_id),
479+
service_base=_CONFIG_SERVICE_PATH,
480+
)
481+
return DocumentTypeBusinessObjectTypeMap.from_dict(resp.json())
482+
316483
@record_metrics(Module.ADMS, Operation.ADMS_CONFIG_DELETE_DOCTYPE_BOTYPE_MAP)
317484
async def delete_type_mapping(self, document_type_bo_type_map_id: str) -> None:
318485
"""Async variant of :meth:`_ConfigurationApi.delete_type_mapping` — same semantics."""

src/sap_cloud_sdk/adms/_models.py

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -631,6 +631,34 @@ def to_odata_dict(self) -> dict:
631631
return d
632632

633633

634+
@dataclass
635+
class UpdateAllowedDomainInput:
636+
"""Input for updating an existing :class:`AllowedDomain` entry (PATCH).
637+
638+
Only non-``None`` fields are included in the PATCH payload.
639+
640+
Attributes:
641+
host_name: New hostname.
642+
protocol: New protocol (``"https"`` or ``"http"``).
643+
port: New port. Pass ``0`` to explicitly clear an existing port.
644+
"""
645+
646+
host_name: str | None = None
647+
protocol: str | None = None
648+
port: int | None = None
649+
650+
def to_odata_dict(self) -> dict:
651+
"""Serialise only non-None fields to the OData PATCH payload."""
652+
d: dict = {}
653+
if self.host_name is not None:
654+
d["AllowedDomainHostName"] = self.host_name
655+
if self.protocol is not None:
656+
d["AllowedDomainProtocol"] = self.protocol
657+
if self.port is not None:
658+
d["AllowedDomainPort"] = self.port
659+
return d
660+
661+
634662
@dataclass
635663
class DocumentTypeText:
636664
"""Localization entry for a :class:`DocumentType` (CAP ``texts`` deep-insert).
@@ -753,6 +781,29 @@ def to_odata_dict(self) -> dict:
753781
return d
754782

755783

784+
@dataclass
785+
class UpdateDocumentTypeInput:
786+
"""Input for updating an existing :class:`DocumentType` (PATCH).
787+
788+
Only non-``None`` fields are included in the PATCH payload.
789+
790+
Attributes:
791+
document_type_name: New human-readable label.
792+
document_type_description: New description.
793+
"""
794+
795+
document_type_name: str | None = None
796+
document_type_description: str | None = None
797+
798+
def to_odata_dict(self) -> dict:
799+
d: dict = {}
800+
if self.document_type_name is not None:
801+
d["DocumentTypeName"] = self.document_type_name
802+
if self.document_type_description is not None:
803+
d["DocumentTypeDescription"] = self.document_type_description
804+
return d
805+
806+
756807
@dataclass
757808
class BusinessObjectNodeType:
758809
"""Tenant-configured business object node type.
@@ -832,6 +883,25 @@ def to_odata_dict(self) -> dict:
832883
return d
833884

834885

886+
@dataclass
887+
class UpdateBusinessObjectNodeTypeInput:
888+
"""Input for updating an existing :class:`BusinessObjectNodeType` (PATCH).
889+
890+
Only non-``None`` fields are included in the PATCH payload.
891+
892+
Attributes:
893+
business_object_node_type_name: New human-readable label.
894+
"""
895+
896+
business_object_node_type_name: str | None = None
897+
898+
def to_odata_dict(self) -> dict:
899+
d: dict = {}
900+
if self.business_object_node_type_name is not None:
901+
d["BusinessObjectNodeTypeName"] = self.business_object_node_type_name
902+
return d
903+
904+
835905
@dataclass
836906
class DocumentTypeBusinessObjectTypeMap:
837907
"""Mapping that controls which document types are allowed for a business object node type.

src/sap_cloud_sdk/core/telemetry/operation.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,14 @@ class Operation(str, Enum):
115115
ADMS_CONFIG_DELETE_BUSINESS_OBJECT_TYPE = "config_delete_business_object_type"
116116
ADMS_CONFIG_GET_ALL_DOCTYPE_BOTYPE_MAPS = "config_get_all_doctype_botype_maps"
117117
ADMS_CONFIG_CREATE_DOCTYPE_BOTYPE_MAP = "config_create_doctype_botype_map"
118+
ADMS_CONFIG_GET_DOCTYPE_BOTYPE_MAP = "config_get_doctype_botype_map"
118119
ADMS_CONFIG_DELETE_DOCTYPE_BOTYPE_MAP = "config_delete_doctype_botype_map"
120+
ADMS_CONFIG_GET_ALLOWED_DOMAIN = "config_get_allowed_domain"
121+
ADMS_CONFIG_UPDATE_ALLOWED_DOMAIN = "config_update_allowed_domain"
122+
ADMS_CONFIG_GET_DOCUMENT_TYPE = "config_get_document_type"
123+
ADMS_CONFIG_UPDATE_DOCUMENT_TYPE = "config_update_document_type"
124+
ADMS_CONFIG_GET_BUSINESS_OBJECT_TYPE = "config_get_business_object_type"
125+
ADMS_CONFIG_UPDATE_BUSINESS_OBJECT_TYPE = "config_update_business_object_type"
119126

120127
# AI Core Operations
121128
AICORE_SET_CONFIG = "set_aicore_config"

tests/core/unit/telemetry/test_operation.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -202,5 +202,5 @@ def test_operation_count(self):
202202
all_operations = list(Operation)
203203
# 3 auditlog + 11 destination + 10 certificate + 10 fragment + 8 objectstore
204204
# + 2 extensibility + 2 aicore + 23 dms + 4 agentgateway + 13 agent_memory
205-
# + 5 data_anonymization + 33 adms = 124
206-
assert len(all_operations) == 124
205+
# + 5 data_anonymization + 40 adms = 131
206+
assert len(all_operations) == 131

0 commit comments

Comments
 (0)