|
9 | 9 | from scim2_models import AnyResource |
10 | 10 | from scim2_models import Context |
11 | 11 | from scim2_models import Error |
| 12 | +from scim2_models import Extension |
12 | 13 | from scim2_models import ListResponse |
13 | 14 | from scim2_models import PatchOp |
14 | 15 | from scim2_models import Resource |
@@ -513,6 +514,28 @@ def modify( |
513 | 514 | ) -> Optional[Union[AnyResource, dict]]: |
514 | 515 | raise NotImplementedError() |
515 | 516 |
|
| 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 | + |
516 | 539 |
|
517 | 540 | class BaseSyncSCIMClient(BaseSCIMClient): |
518 | 541 | """Base class for synchronous request clients.""" |
@@ -771,29 +794,10 @@ def replace( |
771 | 794 | raise NotImplementedError() |
772 | 795 |
|
773 | 796 | 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) |
797 | 801 |
|
798 | 802 |
|
799 | 803 | class BaseAsyncSCIMClient(BaseSCIMClient): |
@@ -1053,28 +1057,9 @@ async def replace( |
1053 | 1057 | raise NotImplementedError() |
1054 | 1058 |
|
1055 | 1059 | 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