Skip to content

Commit b3acd9e

Browse files
committed
refactor: rename resource_types in resource_models.
1 parent 2109c5e commit b3acd9e

File tree

11 files changed

+131
-128
lines changed

11 files changed

+131
-128
lines changed

doc/changelog.rst

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ Changelog
99
This version comes with breaking changes:
1010

1111
- `httpx` is no longer a direct dependency, it is shipped in the `httpx` packaging extra.
12-
- Use ``scim2_client.engines.httpx.SyncSCIMClient`` instead of ``scim2_client.SCIMClient``.
12+
- ``scim2_client.SCIMClient`` has moved to ``scim2_client.engines.httpx.SyncSCIMClient``.
13+
- The ``resource_types`` parameters has been renamed ``resource_models``.
1314

1415
Added
1516
^^^^^

scim2_client/client.py

Lines changed: 49 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ class BaseSCIMClient:
3636
3737
This class can be inherited and used as a basis for request engine integration.
3838
39-
:param resource_types: A tuple of :class:`~scim2_models.Resource` types expected to be handled by the SCIM client.
39+
:param resource_models: A tuple of :class:`~scim2_models.Resource` types expected to be handled by the SCIM client.
4040
If a request payload describe a resource that is not in this list, an exception will be raised.
4141
4242
.. note::
@@ -124,30 +124,32 @@ class BaseSCIMClient:
124124
:rfc:`RFC7644 §3.12 <7644#section-3.12>`.
125125
"""
126126

127-
def __init__(self, resource_types: Optional[tuple[type[Resource]]] = None):
128-
self.resource_types = tuple(
129-
set(resource_types or []) | {ResourceType, Schema, ServiceProviderConfig}
127+
def __init__(self, resource_models: Optional[tuple[type[Resource]]] = None):
128+
self.resource_models = tuple(
129+
set(resource_models or []) | {ResourceType, Schema, ServiceProviderConfig}
130130
)
131131

132-
def check_resource_type(self, resource_type: type[Resource], payload=None) -> None:
133-
if resource_type not in self.resource_types:
132+
def check_resource_model(
133+
self, resource_model: type[Resource], payload=None
134+
) -> None:
135+
if resource_model not in self.resource_models:
134136
raise SCIMRequestError(
135-
f"Unknown resource type: '{resource_type}'", source=payload
137+
f"Unknown resource type: '{resource_model}'", source=payload
136138
)
137139

138-
def resource_endpoint(self, resource_type: Optional[type[Resource]]) -> str:
139-
if resource_type is None:
140+
def resource_endpoint(self, resource_model: Optional[type[Resource]]) -> str:
141+
if resource_model is None:
140142
return "/"
141143

142144
# This one takes no final 's'
143-
if resource_type is ServiceProviderConfig:
145+
if resource_model is ServiceProviderConfig:
144146
return "/ServiceProviderConfig"
145147

146148
try:
147-
first_bracket_index = resource_type.__name__.index("[")
148-
root_name = resource_type.__name__[:first_bracket_index]
149+
first_bracket_index = resource_model.__name__.index("[")
150+
root_name = resource_model.__name__[:first_bracket_index]
149151
except ValueError:
150-
root_name = resource_type.__name__
152+
root_name = resource_model.__name__
151153
return f"/{root_name}s"
152154

153155
def check_response(
@@ -288,25 +290,25 @@ def prepare_create_request(
288290

289291
else:
290292
if isinstance(resource, Resource):
291-
resource_type = resource.__class__
293+
resource_model = resource.__class__
292294

293295
else:
294-
resource_type = Resource.get_by_payload(self.resource_types, resource)
295-
if not resource_type:
296+
resource_model = Resource.get_by_payload(self.resource_models, resource)
297+
if not resource_model:
296298
raise SCIMRequestError(
297299
"Cannot guess resource type from the payload"
298300
)
299301

300302
try:
301-
resource = resource_type.model_validate(resource)
303+
resource = resource_model.model_validate(resource)
302304
except ValidationError as exc:
303305
scim_validation_exc = RequestPayloadValidationError(source=resource)
304306
if sys.version_info >= (3, 11): # pragma: no cover
305307
scim_validation_exc.add_note(str(exc))
306308
raise scim_validation_exc from exc
307309

308-
self.check_resource_type(resource_type, resource)
309-
url = kwargs.pop("url", self.resource_endpoint(resource_type))
310+
self.check_resource_model(resource_model, resource)
311+
url = kwargs.pop("url", self.resource_endpoint(resource_model))
310312
payload = resource.model_dump(scim_ctx=Context.RESOURCE_CREATION_REQUEST)
311313

312314
expected_types = [resource.__class__] if check_request_payload else None
@@ -315,7 +317,7 @@ def prepare_create_request(
315317

316318
def query(
317319
self,
318-
resource_type: Optional[type[Resource]] = None,
320+
resource_model: Optional[type[Resource]] = None,
319321
id: Optional[str] = None,
320322
search_request: Optional[Union[SearchRequest, dict]] = None,
321323
check_request_payload: bool = True,
@@ -329,7 +331,7 @@ def query(
329331
- If `id` is not :data:`None`, the resource with the exact id will be reached.
330332
- If `id` is :data:`None`, all the resources with the given type will be reached.
331333
332-
:param resource_type: A :class:`~scim2_models.Resource` subtype or :data:`None`
334+
:param resource_model: A :class:`~scim2_models.Resource` subtype or :data:`None`
333335
:param id: The SCIM id of an object to get, or :data:`None`
334336
:param search_request: An object detailing the search query parameters.
335337
:param check_request_payload: If :data:`False`,
@@ -345,8 +347,8 @@ def query(
345347
346348
:return:
347349
- A :class:`~scim2_models.Error` object in case of error.
348-
- A `resource_type` object in case of success if `id` is not :data:`None`
349-
- A :class:`~scim2_models.ListResponse[resource_type]` object in case of success if `id` is :data:`None`
350+
- A `resource_model` object in case of success if `id` is not :data:`None`
351+
- A :class:`~scim2_models.ListResponse[resource_model]` object in case of success if `id` is :data:`None`
350352
351353
.. note::
352354
@@ -391,7 +393,7 @@ def query(
391393

392394
def prepare_query_request(
393395
self,
394-
resource_type: Optional[type[Resource]] = None,
396+
resource_model: Optional[type[Resource]] = None,
395397
id: Optional[str] = None,
396398
search_request: Optional[Union[SearchRequest, dict]] = None,
397399
check_request_payload: bool = True,
@@ -400,8 +402,8 @@ def prepare_query_request(
400402
raise_scim_errors: bool = True,
401403
**kwargs,
402404
) -> tuple[str, Union[AnyResource, dict], Optional[list[type[Resource]]], dict]:
403-
if resource_type and check_request_payload:
404-
self.check_resource_type(resource_type)
405+
if resource_model and check_request_payload:
406+
self.check_resource_model(resource_model)
405407

406408
payload: Optional[SearchRequest]
407409
if not check_request_payload:
@@ -416,25 +418,25 @@ def prepare_query_request(
416418
else:
417419
payload = None
418420

419-
url = kwargs.pop("url", self.resource_endpoint(resource_type))
421+
url = kwargs.pop("url", self.resource_endpoint(resource_model))
420422

421-
if resource_type is None:
423+
if resource_model is None:
422424
expected_types = [
423-
*self.resource_types,
424-
ListResponse[Union[self.resource_types]],
425+
*self.resource_models,
426+
ListResponse[Union[self.resource_models]],
425427
]
426428

427-
elif resource_type == ServiceProviderConfig:
428-
expected_types = [resource_type]
429+
elif resource_model == ServiceProviderConfig:
430+
expected_types = [resource_model]
429431
if id:
430432
raise SCIMClientError("ServiceProviderConfig cannot have an id")
431433

432434
elif id:
433-
expected_types = [resource_type]
435+
expected_types = [resource_model]
434436
url = f"{url}/{id}"
435437

436438
else:
437-
expected_types = [ListResponse[resource_type]]
439+
expected_types = [ListResponse[resource_model]]
438440

439441
return url, payload, expected_types, kwargs
440442

@@ -449,7 +451,7 @@ def search(
449451
) -> Union[AnyResource, ListResponse[AnyResource], Error, dict]:
450452
"""Perform a POST search request to read all available resources, as defined in :rfc:`RFC7644 §3.4.3 <7644#section-3.4.3>`.
451453
452-
:param resource_types: Resource type or union of types expected
454+
:param resource_models: Resource type or union of types expected
453455
to be read from the response.
454456
:param search_request: An object detailing the search query parameters.
455457
:param check_request_payload: If :data:`False`,
@@ -466,7 +468,7 @@ def search(
466468
467469
:return:
468470
- A :class:`~scim2_models.Error` object in case of error.
469-
- A :class:`~scim2_models.ListResponse[resource_type]` object in case of success.
471+
- A :class:`~scim2_models.ListResponse[resource_model]` object in case of success.
470472
471473
:usage:
472474
@@ -510,12 +512,12 @@ def prepare_search_request(
510512
)
511513

512514
url = kwargs.pop("url", "/.search")
513-
expected_types = [ListResponse[Union[self.resource_types]]]
515+
expected_types = [ListResponse[Union[self.resource_models]]]
514516
return url, payload, expected_types, kwargs
515517

516518
def delete(
517519
self,
518-
resource_type: type,
520+
resource_model: type,
519521
id: str,
520522
check_response_payload: bool = True,
521523
expected_status_codes: Optional[list[int]] = DELETION_RESPONSE_STATUS_CODES,
@@ -524,7 +526,7 @@ def delete(
524526
) -> Optional[Union[Error, dict]]:
525527
"""Perform a DELETE request to create, as defined in :rfc:`RFC7644 §3.6 <7644#section-3.6>`.
526528
527-
:param resource_type: The type of the resource to delete.
529+
:param resource_model: The type of the resource to delete.
528530
:param id: The type id the resource to delete.
529531
:param check_response_payload: Whether to validate that the response payload is valid.
530532
If set, the raw payload will be returned.
@@ -554,15 +556,15 @@ def delete(
554556

555557
def prepare_delete_request(
556558
self,
557-
resource_type: type,
559+
resource_model: type,
558560
id: str,
559561
check_response_payload: bool = True,
560562
expected_status_codes: Optional[list[int]] = DELETION_RESPONSE_STATUS_CODES,
561563
raise_scim_errors: bool = True,
562564
**kwargs,
563565
) -> tuple[str, dict]:
564-
self.check_resource_type(resource_type)
565-
delete_url = self.resource_endpoint(resource_type) + f"/{id}"
566+
self.check_resource_model(resource_model)
567+
delete_url = self.resource_endpoint(resource_model) + f"/{id}"
566568
url = kwargs.pop("url", delete_url)
567569
return url, kwargs
568570

@@ -630,25 +632,25 @@ def prepare_replace_request(
630632

631633
else:
632634
if isinstance(resource, Resource):
633-
resource_type = resource.__class__
635+
resource_model = resource.__class__
634636

635637
else:
636-
resource_type = Resource.get_by_payload(self.resource_types, resource)
637-
if not resource_type:
638+
resource_model = Resource.get_by_payload(self.resource_models, resource)
639+
if not resource_model:
638640
raise SCIMRequestError(
639641
"Cannot guess resource type from the payload",
640642
source=resource,
641643
)
642644

643645
try:
644-
resource = resource_type.model_validate(resource)
646+
resource = resource_model.model_validate(resource)
645647
except ValidationError as exc:
646648
scim_validation_exc = RequestPayloadValidationError(source=resource)
647649
if sys.version_info >= (3, 11): # pragma: no cover
648650
scim_validation_exc.add_note(str(exc))
649651
raise scim_validation_exc from exc
650652

651-
self.check_resource_type(resource_type, resource)
653+
self.check_resource_model(resource_model, resource)
652654

653655
if not resource.id:
654656
raise SCIMRequestError("Resource must have an id", source=resource)

scim2_client/engines/httpx.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,9 @@ class SyncSCIMClient(BaseSCIMClient):
5252
"""
5353

5454
def __init__(
55-
self, client: Client, resource_types: Optional[tuple[type[Resource]]] = None
55+
self, client: Client, resource_models: Optional[tuple[type[Resource]]] = None
5656
):
57-
super().__init__(resource_types=resource_types)
57+
super().__init__(resource_models=resource_models)
5858
self.client = client
5959

6060
def create(
@@ -94,7 +94,7 @@ def create(
9494

9595
def query(
9696
self,
97-
resource_type: Optional[type[Resource]] = None,
97+
resource_model: Optional[type[Resource]] = None,
9898
id: Optional[str] = None,
9999
search_request: Optional[Union[SearchRequest, dict]] = None,
100100
check_request_payload: bool = True,
@@ -106,7 +106,7 @@ def query(
106106
**kwargs,
107107
):
108108
url, payload, expected_types, request_kwargs = self.prepare_query_request(
109-
resource_type=resource_type,
109+
resource_model=resource_model,
110110
id=id,
111111
search_request=search_request,
112112
check_request_payload=check_request_payload,
@@ -168,7 +168,7 @@ def search(
168168

169169
def delete(
170170
self,
171-
resource_type: type,
171+
resource_model: type,
172172
id: str,
173173
check_response_payload: bool = True,
174174
expected_status_codes: Optional[
@@ -178,7 +178,7 @@ def delete(
178178
**kwargs,
179179
) -> Optional[Union[Error, dict]]:
180180
url, request_kwargs = self.prepare_delete_request(
181-
resource_type=resource_type,
181+
resource_model=resource_model,
182182
id=id,
183183
check_response_payload=check_response_payload,
184184
expected_status_codes=expected_status_codes,

scim2_client/engines/werkzeug.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -34,14 +34,14 @@ class TestSCIMClient(BaseSCIMClient):
3434
3535
:param client: A WSGI application instance that will be used to send requests.
3636
:param scim_prefix: The scim root endpoint in the application.
37-
:param resource_types: The client resource types.
37+
:param resource_models: The client resource types.
3838
3939
.. code-block:: python
4040
4141
from scim2_client.engines.werkzeug import TestSCIMClient
4242
from scim2_models import User, Group
4343
44-
testclient = TestSCIMClient(app=scim_provider, resource_types=(User, Group))
44+
testclient = TestSCIMClient(app=scim_provider, resource_models=(User, Group))
4545
4646
request_user = User(user_name="foo", display_name="bar")
4747
response_user = scim_client.create(request_user)
@@ -52,9 +52,9 @@ def __init__(
5252
self,
5353
app,
5454
scim_prefix: str = "",
55-
resource_types: Optional[tuple[type[Resource]]] = None,
55+
resource_models: Optional[tuple[type[Resource]]] = None,
5656
):
57-
super().__init__(resource_types=resource_types)
57+
super().__init__(resource_models=resource_models)
5858
self.client = Client(app)
5959
self.scim_prefix = scim_prefix
6060

@@ -102,7 +102,7 @@ def create(
102102

103103
def query(
104104
self,
105-
resource_type: Optional[type[Resource]] = None,
105+
resource_model: Optional[type[Resource]] = None,
106106
id: Optional[str] = None,
107107
search_request: Optional[Union[SearchRequest, dict]] = None,
108108
check_request_payload: bool = True,
@@ -114,7 +114,7 @@ def query(
114114
**kwargs,
115115
):
116116
url, payload, expected_types, request_kwargs = self.prepare_query_request(
117-
resource_type=resource_type,
117+
resource_model=resource_model,
118118
id=id,
119119
search_request=search_request,
120120
check_request_payload=check_request_payload,
@@ -177,7 +177,7 @@ def search(
177177

178178
def delete(
179179
self,
180-
resource_type: type,
180+
resource_model: type,
181181
id: str,
182182
check_response_payload: bool = True,
183183
expected_status_codes: Optional[
@@ -187,7 +187,7 @@ def delete(
187187
**kwargs,
188188
) -> Optional[Union[Error, dict]]:
189189
url, request_kwargs = self.prepare_delete_request(
190-
resource_type=resource_type,
190+
resource_model=resource_model,
191191
id=id,
192192
check_response_payload=check_response_payload,
193193
expected_status_codes=expected_status_codes,

tests/engines/test_werkzeug.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ def scim_provider():
3131

3232
@pytest.fixture
3333
def scim_client(scim_provider):
34-
return TestSCIMClient(app=scim_provider, resource_types=(User,))
34+
return TestSCIMClient(app=scim_provider, resource_models=(User,))
3535

3636

3737
def test_werkzeug_engine(scim_client):

0 commit comments

Comments
 (0)