Skip to content

Commit 3f849e0

Browse files
committed
fix: extensions management with the discovery
1 parent 4f82fe5 commit 3f849e0

File tree

1 file changed

+33
-48
lines changed

1 file changed

+33
-48
lines changed

scim2_client/client.py

Lines changed: 33 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
from scim2_models import AnyResource
1010
from scim2_models import Context
1111
from scim2_models import Error
12+
from scim2_models import Extension
1213
from scim2_models import ListResponse
1314
from scim2_models import PatchOp
1415
from scim2_models import Resource
@@ -513,6 +514,28 @@ def modify(
513514
) -> Optional[Union[AnyResource, dict]]:
514515
raise NotImplementedError()
515516

517+
def _discover(self, resource_types, schemas):
518+
self.resource_types = resource_types
519+
resource_types_by_schema = {
520+
resource_type.schema_: resource_type for resource_type in resource_types
521+
}
522+
schema_objs_by_schema = {schema_obj.id: schema_obj for schema_obj in schemas}
523+
524+
resource_models = []
525+
for schema, resource_type in resource_types_by_schema.items():
526+
schema_obj = schema_objs_by_schema[schema]
527+
model = Resource.from_schema(schema_obj)
528+
extensions = []
529+
for ext_schema in resource_type.schema_extensions or []:
530+
schema_obj = schema_objs_by_schema[ext_schema.schema_]
531+
extension = Extension.from_schema(schema_obj)
532+
extensions.append(extension)
533+
if extensions:
534+
model = model[tuple(extensions)]
535+
resource_models.append(model)
536+
537+
self.resource_models = tuple(resource_models)
538+
516539

517540
class BaseSyncSCIMClient(BaseSCIMClient):
518541
"""Base class for synchronous request clients."""
@@ -771,29 +794,10 @@ def replace(
771794
raise NotImplementedError()
772795

773796
def discover(self):
774-
"""Dynamically discover the server models :class:`~scim2_models.Schema` and :class:`~scim2_models.ResourceType`.
775-
776-
This is a shortcut for :meth:`BaseSyncSCIMClient.discover_models`
777-
and :meth:`BaseSyncSCIMClient.discover_resource_types`.
778-
"""
779-
self.discover_models()
780-
self.discover_resource_types()
781-
782-
def discover_models(self):
783-
"""Dynamically register resource models by reading the server :class:`~scim2_models.Schema` endpoint.
784-
785-
Internally it performs a request to the SCIM server to get all the schemas,
786-
generate classes from those schemas, and register them in the client.
787-
"""
788-
schemas = self.query(Schema)
789-
self.resource_models = tuple(
790-
Resource.from_schema(schema) for schema in schemas.resources
791-
)
792-
793-
def discover_resource_types(self):
794-
"""Dynamically register resource types by reading the server :class:`~scim2_models.ResourceType` endpoint."""
795-
schemas = self.query(ResourceType)
796-
self.resource_types = schemas.resources
797+
"""Dynamically discover the server models :class:`~scim2_models.Schema` and :class:`~scim2_models.ResourceType`."""
798+
resource_types_response = self.query(ResourceType)
799+
schemas_response = self.query(Schema)
800+
self._discover(resource_types_response.resources, schemas_response.resources)
797801

798802

799803
class BaseAsyncSCIMClient(BaseSCIMClient):
@@ -1053,28 +1057,9 @@ async def replace(
10531057
raise NotImplementedError()
10541058

10551059
async def discover(self):
1056-
"""Dynamically discover the server models :class:`~scim2_models.Schema` and :class:`~scim2_models.ResourceType`.
1057-
1058-
This is a shortcut for the parallel execution of :meth:`BaseAsyncSCIMClient.discover_models`
1059-
and :meth:`BaseAsyncSCIMClient.discover_resource_types`.
1060-
"""
1061-
models_task = asyncio.create_task(self.discover_models())
1062-
resources_task = asyncio.create_task(self.discover_resource_types())
1063-
await models_task
1064-
await resources_task
1065-
1066-
async def discover_models(self):
1067-
"""Dynamically register resource models by reading the server :class:`~scim2_models.Schema` endpoint.
1068-
1069-
Internally it performs a request to the SCIM server to get all the schemas,
1070-
generate classes from those schemas, and register them in the client.
1071-
"""
1072-
schemas = await self.query(Schema)
1073-
self.resource_models = tuple(
1074-
Resource.from_schema(schema) for schema in schemas.resources
1075-
)
1076-
1077-
async def discover_resource_types(self):
1078-
"""Dynamically register resource types by reading the server :class:`~scim2_models.ResourceType` endpoint."""
1079-
schemas = await self.query(ResourceType)
1080-
self.resource_types = schemas.resources
1060+
"""Dynamically discover the server models :class:`~scim2_models.Schema` and :class:`~scim2_models.ResourceType`."""
1061+
resources_task = asyncio.create_task(self.query(ResourceType))
1062+
schemas_task = asyncio.create_task(self.query(Schema))
1063+
resource_types_response = await resources_task
1064+
schemas_response = await schemas_task
1065+
self._discover(resource_types_response.resources, schemas_response.resources)

0 commit comments

Comments
 (0)