scim2-client 0.3.1__tar.gz → 0.3.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {scim2_client-0.3.1 → scim2_client-0.3.3}/.readthedocs.yml +1 -1
- {scim2_client-0.3.1 → scim2_client-0.3.3}/PKG-INFO +1 -1
- {scim2_client-0.3.1 → scim2_client-0.3.3}/doc/changelog.rst +21 -3
- {scim2_client-0.3.1 → scim2_client-0.3.3}/doc/conf.py +1 -0
- {scim2_client-0.3.1 → scim2_client-0.3.3}/doc/tutorial.rst +11 -11
- {scim2_client-0.3.1 → scim2_client-0.3.3}/pyproject.toml +2 -1
- {scim2_client-0.3.1 → scim2_client-0.3.3}/scim2_client/client.py +102 -106
- {scim2_client-0.3.1 → scim2_client-0.3.3}/scim2_client/engines/httpx.py +49 -36
- {scim2_client-0.3.1 → scim2_client-0.3.3}/scim2_client/engines/werkzeug.py +29 -21
- {scim2_client-0.3.1 → scim2_client-0.3.3}/tests/engines/test_werkzeug.py +15 -0
- {scim2_client-0.3.1 → scim2_client-0.3.3}/uv.lock +13 -1
- {scim2_client-0.3.1 → scim2_client-0.3.3}/.github/FUNDING.yml +0 -0
- {scim2_client-0.3.1 → scim2_client-0.3.3}/.github/workflows/release.yml +0 -0
- {scim2_client-0.3.1 → scim2_client-0.3.3}/.github/workflows/tests.yaml +0 -0
- {scim2_client-0.3.1 → scim2_client-0.3.3}/.gitignore +0 -0
- {scim2_client-0.3.1 → scim2_client-0.3.3}/.pre-commit-config.yaml +0 -0
- {scim2_client-0.3.1 → scim2_client-0.3.3}/LICENSE.md +0 -0
- {scim2_client-0.3.1 → scim2_client-0.3.3}/README.md +0 -0
- {scim2_client-0.3.1 → scim2_client-0.3.3}/doc/__init__.py +0 -0
- {scim2_client-0.3.1 → scim2_client-0.3.3}/doc/contributing.rst +0 -0
- {scim2_client-0.3.1 → scim2_client-0.3.3}/doc/index.rst +0 -0
- {scim2_client-0.3.1 → scim2_client-0.3.3}/doc/reference.rst +0 -0
- {scim2_client-0.3.1 → scim2_client-0.3.3}/scim2_client/__init__.py +0 -0
- {scim2_client-0.3.1 → scim2_client-0.3.3}/scim2_client/engines/__init__.py +0 -0
- {scim2_client-0.3.1 → scim2_client-0.3.3}/scim2_client/errors.py +0 -0
- {scim2_client-0.3.1 → scim2_client-0.3.3}/scim2_client/py.typed +0 -0
- {scim2_client-0.3.1 → scim2_client-0.3.3}/tests/__init__.py +0 -0
- {scim2_client-0.3.1 → scim2_client-0.3.3}/tests/engines/__init__.py +0 -0
- {scim2_client-0.3.1 → scim2_client-0.3.3}/tests/engines/test_httpx.py +0 -0
- {scim2_client-0.3.1 → scim2_client-0.3.3}/tests/test_create.py +0 -0
- {scim2_client-0.3.1 → scim2_client-0.3.3}/tests/test_delete.py +0 -0
- {scim2_client-0.3.1 → scim2_client-0.3.3}/tests/test_query.py +0 -0
- {scim2_client-0.3.1 → scim2_client-0.3.3}/tests/test_replace.py +0 -0
- {scim2_client-0.3.1 → scim2_client-0.3.3}/tests/test_search.py +0 -0
- {scim2_client-0.3.1 → scim2_client-0.3.3}/tests/test_utils.py +0 -0
|
@@ -9,7 +9,7 @@ build:
|
|
|
9
9
|
jobs:
|
|
10
10
|
post_create_environment:
|
|
11
11
|
- pip install uv
|
|
12
|
-
- uv export --group doc --no-hashes --output-file requirements.txt
|
|
12
|
+
- uv export --all-extras --group doc --no-hashes --output-file requirements.txt
|
|
13
13
|
post_install:
|
|
14
14
|
- pip install .
|
|
15
15
|
- pip install --requirement requirements.txt
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: scim2-client
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.3
|
|
4
4
|
Summary: Pythonically build SCIM requests and parse SCIM responses
|
|
5
5
|
Project-URL: documentation, https://scim2-client.readthedocs.io
|
|
6
6
|
Project-URL: repository, https://github.com/python-scim/scim2-client
|
|
@@ -1,6 +1,24 @@
|
|
|
1
1
|
Changelog
|
|
2
2
|
=========
|
|
3
3
|
|
|
4
|
+
[0.3.3] - 2024-11-29
|
|
5
|
+
--------------------
|
|
6
|
+
|
|
7
|
+
Added
|
|
8
|
+
^^^^^
|
|
9
|
+
- :class:`~scim2_client.engines.werkzeug.TestSCIMClient` raise a
|
|
10
|
+
:class:`~scim2_client.UnexpectedContentFormat` exception when response is not JSON.
|
|
11
|
+
|
|
12
|
+
[0.3.2] - 2024-11-29
|
|
13
|
+
--------------------
|
|
14
|
+
|
|
15
|
+
Added
|
|
16
|
+
^^^^^
|
|
17
|
+
- Implement :class:`~scim2_client.BaseSCIMClient` :paramref:`~scim2_client.BaseSCIMClient.check_request_payload`,
|
|
18
|
+
:paramref:`~scim2_client.BaseSCIMClient.check_response_payload` and
|
|
19
|
+
:paramref:`~scim2_client.BaseSCIMClient.raise_scim_errors` paramibutes,
|
|
20
|
+
to keep the same values for all the requests.
|
|
21
|
+
|
|
4
22
|
[0.3.1] - 2024-11-29
|
|
5
23
|
--------------------
|
|
6
24
|
|
|
@@ -22,12 +40,12 @@ Fixed
|
|
|
22
40
|
Added
|
|
23
41
|
^^^^^
|
|
24
42
|
- The `Unknown resource type` request error keeps a reference to the faulty payload.
|
|
25
|
-
- New
|
|
26
|
-
- New
|
|
43
|
+
- New :class:`~scim2_client.engines.werkzeug.TestSCIMClient` request engine for application development purpose.
|
|
44
|
+
- New :class:`~scim2_client.engines.httpx.AsyncSCIMClient` request engine. :issue:`1`
|
|
27
45
|
|
|
28
46
|
Changed
|
|
29
47
|
^^^^^^^
|
|
30
|
-
- Separate httpx network code and SCIM code in separate file as a basis for async support (and
|
|
48
|
+
- Separate httpx network code and SCIM code in separate file as a basis for async support (and other request engines).
|
|
31
49
|
|
|
32
50
|
[0.2.2] - 2024-11-12
|
|
33
51
|
--------------------
|
|
@@ -17,15 +17,15 @@ In addition to your SCIM server root endpoint, you will probably want to provide
|
|
|
17
17
|
from scim2_client.engines.httpx import SyncSCIMClient
|
|
18
18
|
|
|
19
19
|
client = Client(base_url="https://auth.example/scim/v2", headers={"Authorization": "Bearer foobar"})
|
|
20
|
-
scim = SyncSCIMClient(client,
|
|
20
|
+
scim = SyncSCIMClient(client, resource_models=(User[EnterpriseUser], Group))
|
|
21
21
|
|
|
22
|
-
You need to give to indicate to :class:`~scim2_client.
|
|
22
|
+
You need to give to indicate to :class:`~scim2_client.BaseSCIMClient` all the different :class:`~scim2_models.Resource` types that you will need to manipulate with the :code:`resource_models` parameter.
|
|
23
23
|
This is needed so scim2-client will be able to guess which resource type to instante when an arbitrary payload is met.
|
|
24
24
|
|
|
25
25
|
.. todo::
|
|
26
26
|
|
|
27
27
|
We plan to implement the automatic discovery of SCIM server resources,
|
|
28
|
-
so they can dynamically be used without explicitly passing them with the :code:`
|
|
28
|
+
so they can dynamically be used without explicitly passing them with the :code:`resource_models` parameter.
|
|
29
29
|
|
|
30
30
|
Performing actions
|
|
31
31
|
==================
|
|
@@ -33,11 +33,11 @@ Performing actions
|
|
|
33
33
|
scim2-client allows your application to interact with a SCIM server as described in :rfc:`RFC7644 §3 <7644#section-3>`, so you can read and manage the resources.
|
|
34
34
|
The following actions are available:
|
|
35
35
|
|
|
36
|
-
- :meth:`~scim2_client.
|
|
37
|
-
- :meth:`~scim2_client.
|
|
38
|
-
- :meth:`~scim2_client.
|
|
39
|
-
- :meth:`~scim2_client.
|
|
40
|
-
- :meth:`~scim2_client.
|
|
36
|
+
- :meth:`~scim2_client.BaseSyncSCIMClient.create`
|
|
37
|
+
- :meth:`~scim2_client.BaseSyncSCIMClient.query`
|
|
38
|
+
- :meth:`~scim2_client.BaseSyncSCIMClient.replace`
|
|
39
|
+
- :meth:`~scim2_client.BaseSyncSCIMClient.delete`
|
|
40
|
+
- :meth:`~scim2_client.BaseSyncSCIMClient.search`
|
|
41
41
|
|
|
42
42
|
Have a look at the :doc:`reference` to see usage examples and the exhaustive set of parameters, but generally it looks like this:
|
|
43
43
|
|
|
@@ -64,16 +64,16 @@ By default, the data passed to the :class:`SCIM client <scim2_client.BaseSCIMCli
|
|
|
64
64
|
However sometimes you want to accept invalid inputs and outputs.
|
|
65
65
|
To achieve this, all the methods provide the following parameters, all are :data:`True` by default:
|
|
66
66
|
|
|
67
|
-
- :
|
|
67
|
+
- :paramref:`~scim2_client.BaseSCIMClient.check_request_payload`:
|
|
68
68
|
If :data:`True` (the default) a :class:`~pydantic.ValidationError` will be raised if the input does not respect the SCIM standard.
|
|
69
69
|
If :data:`False`, input is expected to be a :data:`dict` that will be passed as-is in the request.
|
|
70
|
-
- :
|
|
70
|
+
- :paramref:`~scim2_client.BaseSCIMClient.check_response_payload`:
|
|
71
71
|
If :data:`True` (the default) a :class:`~pydantic.ValidationError` will be raised if the server response does not respect the SCIM standard.
|
|
72
72
|
If :data:`False` the server response is returned as-is.
|
|
73
73
|
- :code:`expected_status_codes`: The list of expected status codes in the response.
|
|
74
74
|
If :data:`None` any status code is accepted.
|
|
75
75
|
If an unexpected status code is returned, a :class:`~scim2_client.errors.UnexpectedStatusCode` exception is raised.
|
|
76
|
-
- :
|
|
76
|
+
- :paramref:`~scim2_client.BaseSCIMClient.raise_scim_errors`: If :data:`True` (the default) and the server returned an :class:`~scim2_models.Error` object, a :class:`~scim2_client.SCIMResponseErrorObject` exception will be raised.
|
|
77
77
|
If :data:`False` the error object is returned.
|
|
78
78
|
|
|
79
79
|
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "scim2-client"
|
|
7
|
-
version = "0.3.
|
|
7
|
+
version = "0.3.3"
|
|
8
8
|
description = "Pythonically build SCIM requests and parse SCIM responses"
|
|
9
9
|
authors = [{name="Yaal Coop", email="contact@yaal.coop"}]
|
|
10
10
|
license = {file = "LICENSE.md"}
|
|
@@ -64,6 +64,7 @@ doc = [
|
|
|
64
64
|
"shibuya>=2024.5.15",
|
|
65
65
|
"sphinx-issues >= 5.0.0",
|
|
66
66
|
"sphinx>=7.3.7",
|
|
67
|
+
"sphinx-paramlinks>=0.6.0",
|
|
67
68
|
]
|
|
68
69
|
|
|
69
70
|
[tool.coverage.run]
|
|
@@ -48,6 +48,14 @@ class BaseSCIMClient:
|
|
|
48
48
|
|
|
49
49
|
:param resource_models: A tuple of :class:`~scim2_models.Resource` types expected to be handled by the SCIM client.
|
|
50
50
|
If a request payload describe a resource that is not in this list, an exception will be raised.
|
|
51
|
+
:param check_request_payload: If :data:`False`,
|
|
52
|
+
:code:`resource` is expected to be a dict that will be passed as-is in the request.
|
|
53
|
+
This value can be overwritten in methods.
|
|
54
|
+
:param check_response_payload: Whether to validate that the response payloads are valid.
|
|
55
|
+
If set, the raw payload will be returned. This value can be overwritten in methods.
|
|
56
|
+
:param raise_scim_errors: If :data:`True` and the server returned an
|
|
57
|
+
:class:`~scim2_models.Error` object during a request, a :class:`~scim2_client.SCIMResponseErrorObject`
|
|
58
|
+
exception will be raised. If :data:`False` the error object is returned. This value can be overwritten in methods.
|
|
51
59
|
|
|
52
60
|
.. note::
|
|
53
61
|
|
|
@@ -134,10 +142,19 @@ class BaseSCIMClient:
|
|
|
134
142
|
:rfc:`RFC7644 §3.12 <7644#section-3.12>`.
|
|
135
143
|
"""
|
|
136
144
|
|
|
137
|
-
def __init__(
|
|
145
|
+
def __init__(
|
|
146
|
+
self,
|
|
147
|
+
resource_models: Optional[tuple[type[Resource]]] = None,
|
|
148
|
+
check_request_payload: bool = True,
|
|
149
|
+
check_response_payload: bool = True,
|
|
150
|
+
raise_scim_errors: bool = True,
|
|
151
|
+
):
|
|
138
152
|
self.resource_models = tuple(
|
|
139
153
|
set(resource_models or []) | {ResourceType, Schema, ServiceProviderConfig}
|
|
140
154
|
)
|
|
155
|
+
self.check_request_payload = True
|
|
156
|
+
self.check_response_payload = True
|
|
157
|
+
self.raise_scim_errors = True
|
|
141
158
|
|
|
142
159
|
def check_resource_model(
|
|
143
160
|
self, resource_model: type[Resource], payload=None
|
|
@@ -169,10 +186,13 @@ class BaseSCIMClient:
|
|
|
169
186
|
headers: dict,
|
|
170
187
|
expected_status_codes: Optional[list[int]] = None,
|
|
171
188
|
expected_types: Optional[list[type[Resource]]] = None,
|
|
172
|
-
check_response_payload: bool =
|
|
173
|
-
raise_scim_errors: bool =
|
|
189
|
+
check_response_payload: Optional[bool] = None,
|
|
190
|
+
raise_scim_errors: Optional[bool] = None,
|
|
174
191
|
scim_ctx: Optional[Context] = None,
|
|
175
192
|
) -> Union[Error, None, dict, type[Resource]]:
|
|
193
|
+
if raise_scim_errors is None:
|
|
194
|
+
raise_scim_errors = self.raise_scim_errors
|
|
195
|
+
|
|
176
196
|
if expected_status_codes and status_code not in expected_status_codes:
|
|
177
197
|
raise UnexpectedStatusCode(status_code)
|
|
178
198
|
|
|
@@ -198,6 +218,9 @@ class BaseSCIMClient:
|
|
|
198
218
|
else:
|
|
199
219
|
response_payload = payload
|
|
200
220
|
|
|
221
|
+
if check_response_payload is None:
|
|
222
|
+
check_response_payload = self.check_response_payload
|
|
223
|
+
|
|
201
224
|
if not check_response_payload:
|
|
202
225
|
return response_payload
|
|
203
226
|
|
|
@@ -240,15 +263,17 @@ class BaseSCIMClient:
|
|
|
240
263
|
def prepare_create_request(
|
|
241
264
|
self,
|
|
242
265
|
resource: Union[AnyResource, dict],
|
|
243
|
-
check_request_payload: bool =
|
|
266
|
+
check_request_payload: Optional[bool] = None,
|
|
244
267
|
expected_status_codes: Optional[list[int]] = None,
|
|
245
|
-
raise_scim_errors: bool =
|
|
268
|
+
raise_scim_errors: Optional[bool] = None,
|
|
246
269
|
**kwargs,
|
|
247
270
|
) -> RequestPayload:
|
|
248
271
|
req = RequestPayload(
|
|
249
272
|
expected_status_codes=expected_status_codes,
|
|
250
273
|
request_kwargs=kwargs,
|
|
251
274
|
)
|
|
275
|
+
if check_request_payload is None:
|
|
276
|
+
check_request_payload = self.check_request_payload
|
|
252
277
|
|
|
253
278
|
if not check_request_payload:
|
|
254
279
|
req.payload = resource
|
|
@@ -289,9 +314,9 @@ class BaseSCIMClient:
|
|
|
289
314
|
resource_model: Optional[type[Resource]] = None,
|
|
290
315
|
id: Optional[str] = None,
|
|
291
316
|
search_request: Optional[Union[SearchRequest, dict]] = None,
|
|
292
|
-
check_request_payload: bool =
|
|
317
|
+
check_request_payload: Optional[bool] = None,
|
|
293
318
|
expected_status_codes: Optional[list[int]] = None,
|
|
294
|
-
raise_scim_errors: bool =
|
|
319
|
+
raise_scim_errors: Optional[bool] = None,
|
|
295
320
|
**kwargs,
|
|
296
321
|
) -> RequestPayload:
|
|
297
322
|
req = RequestPayload(
|
|
@@ -299,6 +324,9 @@ class BaseSCIMClient:
|
|
|
299
324
|
request_kwargs=kwargs,
|
|
300
325
|
)
|
|
301
326
|
|
|
327
|
+
if check_request_payload is None:
|
|
328
|
+
check_request_payload = self.check_request_payload
|
|
329
|
+
|
|
302
330
|
if resource_model and check_request_payload:
|
|
303
331
|
self.check_resource_model(resource_model)
|
|
304
332
|
|
|
@@ -341,9 +369,9 @@ class BaseSCIMClient:
|
|
|
341
369
|
def prepare_search_request(
|
|
342
370
|
self,
|
|
343
371
|
search_request: Optional[SearchRequest] = None,
|
|
344
|
-
check_request_payload: bool =
|
|
372
|
+
check_request_payload: Optional[bool] = None,
|
|
345
373
|
expected_status_codes: Optional[list[int]] = None,
|
|
346
|
-
raise_scim_errors: bool =
|
|
374
|
+
raise_scim_errors: Optional[bool] = None,
|
|
347
375
|
**kwargs,
|
|
348
376
|
) -> RequestPayload:
|
|
349
377
|
req = RequestPayload(
|
|
@@ -351,6 +379,9 @@ class BaseSCIMClient:
|
|
|
351
379
|
request_kwargs=kwargs,
|
|
352
380
|
)
|
|
353
381
|
|
|
382
|
+
if check_request_payload is None:
|
|
383
|
+
check_request_payload = self.check_request_payload
|
|
384
|
+
|
|
354
385
|
if not check_request_payload:
|
|
355
386
|
req.payload = search_request
|
|
356
387
|
|
|
@@ -372,7 +403,7 @@ class BaseSCIMClient:
|
|
|
372
403
|
resource_model: type,
|
|
373
404
|
id: str,
|
|
374
405
|
expected_status_codes: Optional[list[int]] = None,
|
|
375
|
-
raise_scim_errors: bool =
|
|
406
|
+
raise_scim_errors: Optional[bool] = None,
|
|
376
407
|
**kwargs,
|
|
377
408
|
) -> RequestPayload:
|
|
378
409
|
req = RequestPayload(
|
|
@@ -388,9 +419,9 @@ class BaseSCIMClient:
|
|
|
388
419
|
def prepare_replace_request(
|
|
389
420
|
self,
|
|
390
421
|
resource: Union[AnyResource, dict],
|
|
391
|
-
check_request_payload: bool =
|
|
422
|
+
check_request_payload: Optional[bool] = None,
|
|
392
423
|
expected_status_codes: Optional[list[int]] = None,
|
|
393
|
-
raise_scim_errors: bool =
|
|
424
|
+
raise_scim_errors: Optional[bool] = None,
|
|
394
425
|
**kwargs,
|
|
395
426
|
) -> RequestPayload:
|
|
396
427
|
req = RequestPayload(
|
|
@@ -398,6 +429,9 @@ class BaseSCIMClient:
|
|
|
398
429
|
request_kwargs=kwargs,
|
|
399
430
|
)
|
|
400
431
|
|
|
432
|
+
if check_request_payload is None:
|
|
433
|
+
check_request_payload = self.check_request_payload
|
|
434
|
+
|
|
401
435
|
if not check_request_payload:
|
|
402
436
|
req.payload = resource
|
|
403
437
|
req.url = kwargs.pop("url", None)
|
|
@@ -449,27 +483,23 @@ class BaseSyncSCIMClient(BaseSCIMClient):
|
|
|
449
483
|
def create(
|
|
450
484
|
self,
|
|
451
485
|
resource: Union[AnyResource, dict],
|
|
452
|
-
check_request_payload: bool =
|
|
453
|
-
check_response_payload: bool =
|
|
486
|
+
check_request_payload: Optional[bool] = None,
|
|
487
|
+
check_response_payload: Optional[bool] = None,
|
|
454
488
|
expected_status_codes: Optional[
|
|
455
489
|
list[int]
|
|
456
490
|
] = BaseSCIMClient.CREATION_RESPONSE_STATUS_CODES,
|
|
457
|
-
raise_scim_errors: bool =
|
|
491
|
+
raise_scim_errors: Optional[bool] = None,
|
|
458
492
|
**kwargs,
|
|
459
493
|
) -> Union[AnyResource, Error, dict]:
|
|
460
494
|
"""Perform a POST request to create, as defined in :rfc:`RFC7644 §3.3 <7644#section-3.3>`.
|
|
461
495
|
|
|
462
496
|
:param resource: The resource to create
|
|
463
497
|
If is a :data:`dict`, the resource type will be guessed from the schema.
|
|
464
|
-
:param check_request_payload: If :
|
|
465
|
-
|
|
466
|
-
:param check_response_payload: Whether to validate that the response payload is valid.
|
|
467
|
-
If set, the raw payload will be returned.
|
|
498
|
+
:param check_request_payload: If set, overwrites :paramref:`BaseSCIMClient.check_request_payload`.
|
|
499
|
+
:param check_response_payload: If set, overwrites :paramref:`BaseSCIMClient.check_response_payload`.
|
|
468
500
|
:param expected_status_codes: The list of expected status codes form the response.
|
|
469
501
|
If :data:`None` any status code is accepted.
|
|
470
|
-
:param raise_scim_errors: If :
|
|
471
|
-
:class:`~scim2_models.Error` object, a :class:`~scim2_client.SCIMResponseErrorObject`
|
|
472
|
-
exception will be raised. If :data:`False` the error object is returned.
|
|
502
|
+
:param raise_scim_errors: If set, overwrites :paramref:`BaseSCIMClient.raise_scim_errors`.
|
|
473
503
|
:param kwargs: Additional parameters passed to the underlying HTTP request
|
|
474
504
|
library.
|
|
475
505
|
|
|
@@ -501,12 +531,12 @@ class BaseSyncSCIMClient(BaseSCIMClient):
|
|
|
501
531
|
resource_model: Optional[type[Resource]] = None,
|
|
502
532
|
id: Optional[str] = None,
|
|
503
533
|
search_request: Optional[Union[SearchRequest, dict]] = None,
|
|
504
|
-
check_request_payload: bool =
|
|
505
|
-
check_response_payload: bool =
|
|
534
|
+
check_request_payload: Optional[bool] = None,
|
|
535
|
+
check_response_payload: Optional[bool] = None,
|
|
506
536
|
expected_status_codes: Optional[
|
|
507
537
|
list[int]
|
|
508
538
|
] = BaseSCIMClient.QUERY_RESPONSE_STATUS_CODES,
|
|
509
|
-
raise_scim_errors: bool =
|
|
539
|
+
raise_scim_errors: Optional[bool] = None,
|
|
510
540
|
**kwargs,
|
|
511
541
|
) -> Union[AnyResource, ListResponse[AnyResource], Error, dict]:
|
|
512
542
|
"""Perform a GET request to read resources, as defined in :rfc:`RFC7644 §3.4.2 <7644#section-3.4.2>`.
|
|
@@ -517,15 +547,11 @@ class BaseSyncSCIMClient(BaseSCIMClient):
|
|
|
517
547
|
:param resource_model: A :class:`~scim2_models.Resource` subtype or :data:`None`
|
|
518
548
|
:param id: The SCIM id of an object to get, or :data:`None`
|
|
519
549
|
:param search_request: An object detailing the search query parameters.
|
|
520
|
-
:param check_request_payload: If :
|
|
521
|
-
|
|
522
|
-
:param check_response_payload: Whether to validate that the response payload is valid.
|
|
523
|
-
If set, the raw payload will be returned.
|
|
550
|
+
:param check_request_payload: If set, overwrites :paramref:`BaseSCIMClient.check_request_payload`.
|
|
551
|
+
:param check_response_payload: If set, overwrites :paramref:`BaseSCIMClient.check_response_payload`.
|
|
524
552
|
:param expected_status_codes: The list of expected status codes form the response.
|
|
525
553
|
If :data:`None` any status code is accepted.
|
|
526
|
-
:param raise_scim_errors: If :
|
|
527
|
-
:class:`~scim2_models.Error` object, a :class:`~scim2_client.SCIMResponseErrorObject`
|
|
528
|
-
exception will be raised. If :data:`False` the error object is returned.
|
|
554
|
+
:param raise_scim_errors: If set, overwrites :paramref:`BaseSCIMClient.raise_scim_errors`.
|
|
529
555
|
:param kwargs: Additional parameters passed to the underlying HTTP request library.
|
|
530
556
|
|
|
531
557
|
:return:
|
|
@@ -577,12 +603,12 @@ class BaseSyncSCIMClient(BaseSCIMClient):
|
|
|
577
603
|
def search(
|
|
578
604
|
self,
|
|
579
605
|
search_request: Optional[SearchRequest] = None,
|
|
580
|
-
check_request_payload: bool =
|
|
581
|
-
check_response_payload: bool =
|
|
606
|
+
check_request_payload: Optional[bool] = None,
|
|
607
|
+
check_response_payload: Optional[bool] = None,
|
|
582
608
|
expected_status_codes: Optional[
|
|
583
609
|
list[int]
|
|
584
610
|
] = BaseSCIMClient.SEARCH_RESPONSE_STATUS_CODES,
|
|
585
|
-
raise_scim_errors: bool =
|
|
611
|
+
raise_scim_errors: Optional[bool] = None,
|
|
586
612
|
**kwargs,
|
|
587
613
|
) -> Union[AnyResource, ListResponse[AnyResource], Error, dict]:
|
|
588
614
|
"""Perform a POST search request to read all available resources, as defined in :rfc:`RFC7644 §3.4.3 <7644#section-3.4.3>`.
|
|
@@ -590,15 +616,11 @@ class BaseSyncSCIMClient(BaseSCIMClient):
|
|
|
590
616
|
:param resource_models: Resource type or union of types expected
|
|
591
617
|
to be read from the response.
|
|
592
618
|
:param search_request: An object detailing the search query parameters.
|
|
593
|
-
:param check_request_payload: If :
|
|
594
|
-
|
|
595
|
-
:param check_response_payload: Whether to validate that the response payload is valid.
|
|
596
|
-
If set, the raw payload will be returned.
|
|
619
|
+
:param check_request_payload: If set, overwrites :paramref:`BaseSCIMClient.check_request_payload`.
|
|
620
|
+
:param check_response_payload: If set, overwrites :paramref:`BaseSCIMClient.check_response_payload`.
|
|
597
621
|
:param expected_status_codes: The list of expected status codes form the response.
|
|
598
622
|
If :data:`None` any status code is accepted.
|
|
599
|
-
:param raise_scim_errors: If :
|
|
600
|
-
:class:`~scim2_models.Error` object, a :class:`~scim2_client.SCIMResponseErrorObject`
|
|
601
|
-
exception will be raised. If :data:`False` the error object is returned.
|
|
623
|
+
:param raise_scim_errors: If set, overwrites :paramref:`BaseSCIMClient.raise_scim_errors`.
|
|
602
624
|
:param kwargs: Additional parameters passed to the underlying
|
|
603
625
|
HTTP request library.
|
|
604
626
|
|
|
@@ -630,24 +652,21 @@ class BaseSyncSCIMClient(BaseSCIMClient):
|
|
|
630
652
|
self,
|
|
631
653
|
resource_model: type,
|
|
632
654
|
id: str,
|
|
633
|
-
check_response_payload: bool =
|
|
655
|
+
check_response_payload: Optional[bool] = None,
|
|
634
656
|
expected_status_codes: Optional[
|
|
635
657
|
list[int]
|
|
636
658
|
] = BaseSCIMClient.DELETION_RESPONSE_STATUS_CODES,
|
|
637
|
-
raise_scim_errors: bool =
|
|
659
|
+
raise_scim_errors: Optional[bool] = None,
|
|
638
660
|
**kwargs,
|
|
639
661
|
) -> Optional[Union[Error, dict]]:
|
|
640
662
|
"""Perform a DELETE request to create, as defined in :rfc:`RFC7644 §3.6 <7644#section-3.6>`.
|
|
641
663
|
|
|
642
664
|
:param resource_model: The type of the resource to delete.
|
|
643
665
|
:param id: The type id the resource to delete.
|
|
644
|
-
:param check_response_payload:
|
|
645
|
-
If set, the raw payload will be returned.
|
|
666
|
+
:param check_response_payload: If set, overwrites :paramref:`BaseSCIMClient.check_response_payload`.
|
|
646
667
|
:param expected_status_codes: The list of expected status codes form the response.
|
|
647
668
|
If :data:`None` any status code is accepted.
|
|
648
|
-
:param raise_scim_errors: If :
|
|
649
|
-
:class:`~scim2_models.Error` object, a :class:`~scim2_client.SCIMResponseErrorObject`
|
|
650
|
-
exception will be raised. If :data:`False` the error object is returned.
|
|
669
|
+
:param raise_scim_errors: If set, overwrites :paramref:`BaseSCIMClient.raise_scim_errors`.
|
|
651
670
|
:param kwargs: Additional parameters passed to the underlying
|
|
652
671
|
HTTP request library.
|
|
653
672
|
|
|
@@ -670,27 +689,23 @@ class BaseSyncSCIMClient(BaseSCIMClient):
|
|
|
670
689
|
def replace(
|
|
671
690
|
self,
|
|
672
691
|
resource: Union[AnyResource, dict],
|
|
673
|
-
check_request_payload: bool =
|
|
674
|
-
check_response_payload: bool =
|
|
692
|
+
check_request_payload: Optional[bool] = None,
|
|
693
|
+
check_response_payload: Optional[bool] = None,
|
|
675
694
|
expected_status_codes: Optional[
|
|
676
695
|
list[int]
|
|
677
696
|
] = BaseSCIMClient.REPLACEMENT_RESPONSE_STATUS_CODES,
|
|
678
|
-
raise_scim_errors: bool =
|
|
697
|
+
raise_scim_errors: Optional[bool] = None,
|
|
679
698
|
**kwargs,
|
|
680
699
|
) -> Union[AnyResource, Error, dict]:
|
|
681
700
|
"""Perform a PUT request to replace a resource, as defined in :rfc:`RFC7644 §3.5.1 <7644#section-3.5.1>`.
|
|
682
701
|
|
|
683
702
|
:param resource: The new resource to replace.
|
|
684
703
|
If is a :data:`dict`, the resource type will be guessed from the schema.
|
|
685
|
-
:param check_request_payload: If :
|
|
686
|
-
|
|
687
|
-
:param check_response_payload: Whether to validate that the response payload is valid.
|
|
688
|
-
If set, the raw payload will be returned.
|
|
704
|
+
:param check_request_payload: If set, overwrites :paramref:`BaseSCIMClient.check_request_payload`.
|
|
705
|
+
:param check_response_payload: If set, overwrites :paramref:`BaseSCIMClient.check_response_payload`.
|
|
689
706
|
:param expected_status_codes: The list of expected status codes form the response.
|
|
690
707
|
If :data:`None` any status code is accepted.
|
|
691
|
-
:param raise_scim_errors: If :
|
|
692
|
-
:class:`~scim2_models.Error` object, a :class:`~scim2_client.SCIMResponseErrorObject`
|
|
693
|
-
exception will be raised. If :data:`False` the error object is returned.
|
|
708
|
+
:param raise_scim_errors: If set, overwrites :paramref:`BaseSCIMClient.raise_scim_errors`.
|
|
694
709
|
:param kwargs: Additional parameters passed to the underlying
|
|
695
710
|
HTTP request library.
|
|
696
711
|
|
|
@@ -725,27 +740,23 @@ class BaseAsyncSCIMClient(BaseSCIMClient):
|
|
|
725
740
|
async def create(
|
|
726
741
|
self,
|
|
727
742
|
resource: Union[AnyResource, dict],
|
|
728
|
-
check_request_payload: bool =
|
|
729
|
-
check_response_payload: bool =
|
|
743
|
+
check_request_payload: Optional[bool] = None,
|
|
744
|
+
check_response_payload: Optional[bool] = None,
|
|
730
745
|
expected_status_codes: Optional[
|
|
731
746
|
list[int]
|
|
732
747
|
] = BaseSCIMClient.CREATION_RESPONSE_STATUS_CODES,
|
|
733
|
-
raise_scim_errors: bool =
|
|
748
|
+
raise_scim_errors: Optional[bool] = None,
|
|
734
749
|
**kwargs,
|
|
735
750
|
) -> Union[AnyResource, Error, dict]:
|
|
736
751
|
"""Perform a POST request to create, as defined in :rfc:`RFC7644 §3.3 <7644#section-3.3>`.
|
|
737
752
|
|
|
738
753
|
:param resource: The resource to create
|
|
739
754
|
If is a :data:`dict`, the resource type will be guessed from the schema.
|
|
740
|
-
:param check_request_payload: If :
|
|
741
|
-
|
|
742
|
-
:param check_response_payload: Whether to validate that the response payload is valid.
|
|
743
|
-
If set, the raw payload will be returned.
|
|
755
|
+
:param check_request_payload: If set, overwrites :paramref:`BaseSCIMClient.check_request_payload`.
|
|
756
|
+
:param check_response_payload: If set, overwrites :paramref:`BaseSCIMClient.check_response_payload`.
|
|
744
757
|
:param expected_status_codes: The list of expected status codes form the response.
|
|
745
758
|
If :data:`None` any status code is accepted.
|
|
746
|
-
:param raise_scim_errors: If :
|
|
747
|
-
:class:`~scim2_models.Error` object, a :class:`~scim2_client.SCIMResponseErrorObject`
|
|
748
|
-
exception will be raised. If :data:`False` the error object is returned.
|
|
759
|
+
:param raise_scim_errors: If set, overwrites :paramref:`BaseSCIMClient.raise_scim_errors`.
|
|
749
760
|
:param kwargs: Additional parameters passed to the underlying HTTP request
|
|
750
761
|
library.
|
|
751
762
|
|
|
@@ -777,12 +788,12 @@ class BaseAsyncSCIMClient(BaseSCIMClient):
|
|
|
777
788
|
resource_model: Optional[type[Resource]] = None,
|
|
778
789
|
id: Optional[str] = None,
|
|
779
790
|
search_request: Optional[Union[SearchRequest, dict]] = None,
|
|
780
|
-
check_request_payload: bool =
|
|
781
|
-
check_response_payload: bool =
|
|
791
|
+
check_request_payload: Optional[bool] = None,
|
|
792
|
+
check_response_payload: Optional[bool] = None,
|
|
782
793
|
expected_status_codes: Optional[
|
|
783
794
|
list[int]
|
|
784
795
|
] = BaseSCIMClient.QUERY_RESPONSE_STATUS_CODES,
|
|
785
|
-
raise_scim_errors: bool =
|
|
796
|
+
raise_scim_errors: Optional[bool] = None,
|
|
786
797
|
**kwargs,
|
|
787
798
|
) -> Union[AnyResource, ListResponse[AnyResource], Error, dict]:
|
|
788
799
|
"""Perform a GET request to read resources, as defined in :rfc:`RFC7644 §3.4.2 <7644#section-3.4.2>`.
|
|
@@ -793,15 +804,11 @@ class BaseAsyncSCIMClient(BaseSCIMClient):
|
|
|
793
804
|
:param resource_model: A :class:`~scim2_models.Resource` subtype or :data:`None`
|
|
794
805
|
:param id: The SCIM id of an object to get, or :data:`None`
|
|
795
806
|
:param search_request: An object detailing the search query parameters.
|
|
796
|
-
:param check_request_payload: If :
|
|
797
|
-
|
|
798
|
-
:param check_response_payload: Whether to validate that the response payload is valid.
|
|
799
|
-
If set, the raw payload will be returned.
|
|
807
|
+
:param check_request_payload: If set, overwrites :paramref:`BaseSCIMClient.check_request_payload`.
|
|
808
|
+
:param check_response_payload: If set, overwrites :paramref:`BaseSCIMClient.check_response_payload`.
|
|
800
809
|
:param expected_status_codes: The list of expected status codes form the response.
|
|
801
810
|
If :data:`None` any status code is accepted.
|
|
802
|
-
:param raise_scim_errors: If :
|
|
803
|
-
:class:`~scim2_models.Error` object, a :class:`~scim2_client.SCIMResponseErrorObject`
|
|
804
|
-
exception will be raised. If :data:`False` the error object is returned.
|
|
811
|
+
:param raise_scim_errors: If set, overwrites :paramref:`BaseSCIMClient.raise_scim_errors`.
|
|
805
812
|
:param kwargs: Additional parameters passed to the underlying HTTP request library.
|
|
806
813
|
|
|
807
814
|
:return:
|
|
@@ -853,12 +860,12 @@ class BaseAsyncSCIMClient(BaseSCIMClient):
|
|
|
853
860
|
async def search(
|
|
854
861
|
self,
|
|
855
862
|
search_request: Optional[SearchRequest] = None,
|
|
856
|
-
check_request_payload: bool =
|
|
857
|
-
check_response_payload: bool =
|
|
863
|
+
check_request_payload: Optional[bool] = None,
|
|
864
|
+
check_response_payload: Optional[bool] = None,
|
|
858
865
|
expected_status_codes: Optional[
|
|
859
866
|
list[int]
|
|
860
867
|
] = BaseSCIMClient.SEARCH_RESPONSE_STATUS_CODES,
|
|
861
|
-
raise_scim_errors: bool =
|
|
868
|
+
raise_scim_errors: Optional[bool] = None,
|
|
862
869
|
**kwargs,
|
|
863
870
|
) -> Union[AnyResource, ListResponse[AnyResource], Error, dict]:
|
|
864
871
|
"""Perform a POST search request to read all available resources, as defined in :rfc:`RFC7644 §3.4.3 <7644#section-3.4.3>`.
|
|
@@ -866,15 +873,11 @@ class BaseAsyncSCIMClient(BaseSCIMClient):
|
|
|
866
873
|
:param resource_models: Resource type or union of types expected
|
|
867
874
|
to be read from the response.
|
|
868
875
|
:param search_request: An object detailing the search query parameters.
|
|
869
|
-
:param check_request_payload: If :
|
|
870
|
-
|
|
871
|
-
:param check_response_payload: Whether to validate that the response payload is valid.
|
|
872
|
-
If set, the raw payload will be returned.
|
|
876
|
+
:param check_request_payload: If set, overwrites :paramref:`BaseSCIMClient.check_request_payload`.
|
|
877
|
+
:param check_response_payload: If set, overwrites :paramref:`BaseSCIMClient.check_response_payload`.
|
|
873
878
|
:param expected_status_codes: The list of expected status codes form the response.
|
|
874
879
|
If :data:`None` any status code is accepted.
|
|
875
|
-
:param raise_scim_errors: If :
|
|
876
|
-
:class:`~scim2_models.Error` object, a :class:`~scim2_client.SCIMResponseErrorObject`
|
|
877
|
-
exception will be raised. If :data:`False` the error object is returned.
|
|
880
|
+
:param raise_scim_errors: If set, overwrites :paramref:`BaseSCIMClient.raise_scim_errors`.
|
|
878
881
|
:param kwargs: Additional parameters passed to the underlying
|
|
879
882
|
HTTP request library.
|
|
880
883
|
|
|
@@ -906,24 +909,21 @@ class BaseAsyncSCIMClient(BaseSCIMClient):
|
|
|
906
909
|
self,
|
|
907
910
|
resource_model: type,
|
|
908
911
|
id: str,
|
|
909
|
-
check_response_payload: bool =
|
|
912
|
+
check_response_payload: Optional[bool] = None,
|
|
910
913
|
expected_status_codes: Optional[
|
|
911
914
|
list[int]
|
|
912
915
|
] = BaseSCIMClient.DELETION_RESPONSE_STATUS_CODES,
|
|
913
|
-
raise_scim_errors: bool =
|
|
916
|
+
raise_scim_errors: Optional[bool] = None,
|
|
914
917
|
**kwargs,
|
|
915
918
|
) -> Optional[Union[Error, dict]]:
|
|
916
919
|
"""Perform a DELETE request to create, as defined in :rfc:`RFC7644 §3.6 <7644#section-3.6>`.
|
|
917
920
|
|
|
918
921
|
:param resource_model: The type of the resource to delete.
|
|
919
922
|
:param id: The type id the resource to delete.
|
|
920
|
-
:param check_response_payload:
|
|
921
|
-
If set, the raw payload will be returned.
|
|
923
|
+
:param check_response_payload: If set, overwrites :paramref:`BaseSCIMClient.check_response_payload`.
|
|
922
924
|
:param expected_status_codes: The list of expected status codes form the response.
|
|
923
925
|
If :data:`None` any status code is accepted.
|
|
924
|
-
:param raise_scim_errors: If :
|
|
925
|
-
:class:`~scim2_models.Error` object, a :class:`~scim2_client.SCIMResponseErrorObject`
|
|
926
|
-
exception will be raised. If :data:`False` the error object is returned.
|
|
926
|
+
:param raise_scim_errors: If set, overwrites :paramref:`BaseSCIMClient.raise_scim_errors`.
|
|
927
927
|
:param kwargs: Additional parameters passed to the underlying
|
|
928
928
|
HTTP request library.
|
|
929
929
|
|
|
@@ -946,27 +946,23 @@ class BaseAsyncSCIMClient(BaseSCIMClient):
|
|
|
946
946
|
async def replace(
|
|
947
947
|
self,
|
|
948
948
|
resource: Union[AnyResource, dict],
|
|
949
|
-
check_request_payload: bool =
|
|
950
|
-
check_response_payload: bool =
|
|
949
|
+
check_request_payload: Optional[bool] = None,
|
|
950
|
+
check_response_payload: Optional[bool] = None,
|
|
951
951
|
expected_status_codes: Optional[
|
|
952
952
|
list[int]
|
|
953
953
|
] = BaseSCIMClient.REPLACEMENT_RESPONSE_STATUS_CODES,
|
|
954
|
-
raise_scim_errors: bool =
|
|
954
|
+
raise_scim_errors: Optional[bool] = None,
|
|
955
955
|
**kwargs,
|
|
956
956
|
) -> Union[AnyResource, Error, dict]:
|
|
957
957
|
"""Perform a PUT request to replace a resource, as defined in :rfc:`RFC7644 §3.5.1 <7644#section-3.5.1>`.
|
|
958
958
|
|
|
959
959
|
:param resource: The new resource to replace.
|
|
960
960
|
If is a :data:`dict`, the resource type will be guessed from the schema.
|
|
961
|
-
:param check_request_payload: If :
|
|
962
|
-
|
|
963
|
-
:param check_response_payload: Whether to validate that the response payload is valid.
|
|
964
|
-
If set, the raw payload will be returned.
|
|
961
|
+
:param check_request_payload: If set, overwrites :paramref:`BaseSCIMClient.check_request_payload`.
|
|
962
|
+
:param check_response_payload: If set, overwrites :paramref:`BaseSCIMClient.check_response_payload`.
|
|
965
963
|
:param expected_status_codes: The list of expected status codes form the response.
|
|
966
964
|
If :data:`None` any status code is accepted.
|
|
967
|
-
:param raise_scim_errors: If :
|
|
968
|
-
:class:`~scim2_models.Error` object, a :class:`~scim2_client.SCIMResponseErrorObject`
|
|
969
|
-
exception will be raised. If :data:`False` the error object is returned.
|
|
965
|
+
:param raise_scim_errors: If set, overwrites :paramref:`BaseSCIMClient.raise_scim_errors`.
|
|
970
966
|
:param kwargs: Additional parameters passed to the underlying
|
|
971
967
|
HTTP request library.
|
|
972
968
|
|
|
@@ -52,23 +52,29 @@ class SyncSCIMClient(BaseSyncSCIMClient):
|
|
|
52
52
|
:param client: A :class:`httpx.Client` instance that will be used to send requests.
|
|
53
53
|
:param resource_models: A tuple of :class:`~scim2_models.Resource` types expected to be handled by the SCIM client.
|
|
54
54
|
If a request payload describe a resource that is not in this list, an exception will be raised.
|
|
55
|
+
:param check_request_payload: If :data:`False`,
|
|
56
|
+
:code:`resource` is expected to be a dict that will be passed as-is in the request.
|
|
57
|
+
This value can be overwritten in methods.
|
|
58
|
+
:param check_response_payload: Whether to validate that the response payloads are valid.
|
|
59
|
+
If set, the raw payload will be returned. This value can be overwritten in methods.
|
|
60
|
+
:param raise_scim_errors: If :data:`True` and the server returned an
|
|
61
|
+
:class:`~scim2_models.Error` object during a request, a :class:`~scim2_client.SCIMResponseErrorObject`
|
|
62
|
+
exception will be raised. If :data:`False` the error object is returned. This value can be overwritten in methods.
|
|
55
63
|
"""
|
|
56
64
|
|
|
57
|
-
def __init__(
|
|
58
|
-
|
|
59
|
-
):
|
|
60
|
-
super().__init__(resource_models=resource_models)
|
|
65
|
+
def __init__(self, client: Client, *args, **kwargs):
|
|
66
|
+
super().__init__(*args, **kwargs)
|
|
61
67
|
self.client = client
|
|
62
68
|
|
|
63
69
|
def create(
|
|
64
70
|
self,
|
|
65
71
|
resource: Union[AnyResource, dict],
|
|
66
|
-
check_request_payload: bool =
|
|
67
|
-
check_response_payload: bool =
|
|
72
|
+
check_request_payload: Optional[bool] = None,
|
|
73
|
+
check_response_payload: Optional[bool] = None,
|
|
68
74
|
expected_status_codes: Optional[
|
|
69
75
|
list[int]
|
|
70
76
|
] = BaseSyncSCIMClient.CREATION_RESPONSE_STATUS_CODES,
|
|
71
|
-
raise_scim_errors: bool =
|
|
77
|
+
raise_scim_errors: Optional[bool] = None,
|
|
72
78
|
**kwargs,
|
|
73
79
|
) -> Union[AnyResource, Error, dict]:
|
|
74
80
|
req = self.prepare_create_request(
|
|
@@ -99,12 +105,12 @@ class SyncSCIMClient(BaseSyncSCIMClient):
|
|
|
99
105
|
resource_model: Optional[type[Resource]] = None,
|
|
100
106
|
id: Optional[str] = None,
|
|
101
107
|
search_request: Optional[Union[SearchRequest, dict]] = None,
|
|
102
|
-
check_request_payload: bool =
|
|
103
|
-
check_response_payload: bool =
|
|
108
|
+
check_request_payload: Optional[bool] = None,
|
|
109
|
+
check_response_payload: Optional[bool] = None,
|
|
104
110
|
expected_status_codes: Optional[
|
|
105
111
|
list[int]
|
|
106
112
|
] = BaseSyncSCIMClient.QUERY_RESPONSE_STATUS_CODES,
|
|
107
|
-
raise_scim_errors: bool =
|
|
113
|
+
raise_scim_errors: Optional[bool] = None,
|
|
108
114
|
**kwargs,
|
|
109
115
|
):
|
|
110
116
|
req = self.prepare_query_request(
|
|
@@ -137,12 +143,12 @@ class SyncSCIMClient(BaseSyncSCIMClient):
|
|
|
137
143
|
def search(
|
|
138
144
|
self,
|
|
139
145
|
search_request: Optional[SearchRequest] = None,
|
|
140
|
-
check_request_payload: bool =
|
|
141
|
-
check_response_payload: bool =
|
|
146
|
+
check_request_payload: Optional[bool] = None,
|
|
147
|
+
check_response_payload: Optional[bool] = None,
|
|
142
148
|
expected_status_codes: Optional[
|
|
143
149
|
list[int]
|
|
144
150
|
] = BaseSyncSCIMClient.SEARCH_RESPONSE_STATUS_CODES,
|
|
145
|
-
raise_scim_errors: bool =
|
|
151
|
+
raise_scim_errors: Optional[bool] = None,
|
|
146
152
|
**kwargs,
|
|
147
153
|
) -> Union[AnyResource, ListResponse[AnyResource], Error, dict]:
|
|
148
154
|
req = self.prepare_search_request(
|
|
@@ -172,11 +178,11 @@ class SyncSCIMClient(BaseSyncSCIMClient):
|
|
|
172
178
|
self,
|
|
173
179
|
resource_model: type,
|
|
174
180
|
id: str,
|
|
175
|
-
check_response_payload: bool =
|
|
181
|
+
check_response_payload: Optional[bool] = None,
|
|
176
182
|
expected_status_codes: Optional[
|
|
177
183
|
list[int]
|
|
178
184
|
] = BaseSyncSCIMClient.DELETION_RESPONSE_STATUS_CODES,
|
|
179
|
-
raise_scim_errors: bool =
|
|
185
|
+
raise_scim_errors: Optional[bool] = None,
|
|
180
186
|
**kwargs,
|
|
181
187
|
) -> Optional[Union[Error, dict]]:
|
|
182
188
|
req = self.prepare_delete_request(
|
|
@@ -203,12 +209,12 @@ class SyncSCIMClient(BaseSyncSCIMClient):
|
|
|
203
209
|
def replace(
|
|
204
210
|
self,
|
|
205
211
|
resource: Union[AnyResource, dict],
|
|
206
|
-
check_request_payload: bool =
|
|
207
|
-
check_response_payload: bool =
|
|
212
|
+
check_request_payload: Optional[bool] = None,
|
|
213
|
+
check_response_payload: Optional[bool] = None,
|
|
208
214
|
expected_status_codes: Optional[
|
|
209
215
|
list[int]
|
|
210
216
|
] = BaseSyncSCIMClient.REPLACEMENT_RESPONSE_STATUS_CODES,
|
|
211
|
-
raise_scim_errors: bool =
|
|
217
|
+
raise_scim_errors: Optional[bool] = None,
|
|
212
218
|
**kwargs,
|
|
213
219
|
) -> Union[AnyResource, Error, dict]:
|
|
214
220
|
req = self.prepare_replace_request(
|
|
@@ -241,23 +247,30 @@ class AsyncSCIMClient(BaseAsyncSCIMClient):
|
|
|
241
247
|
:param client: A :class:`httpx.AsyncClient` instance that will be used to send requests.
|
|
242
248
|
:param resource_models: A tuple of :class:`~scim2_models.Resource` types expected to be handled by the SCIM client.
|
|
243
249
|
If a request payload describe a resource that is not in this list, an exception will be raised.
|
|
250
|
+
:param check_request_payload: If :data:`False`,
|
|
251
|
+
:code:`resource` is expected to be a dict that will be passed as-is in the request.
|
|
252
|
+
This value can be overwritten in methods.
|
|
253
|
+
:param check_response_payload: Whether to validate that the response payloads are valid.
|
|
254
|
+
If set, the raw payload will be returned. This value can be overwritten in methods.
|
|
255
|
+
:param raise_scim_errors: If :data:`True` and the server returned an
|
|
256
|
+
:class:`~scim2_models.Error` object during a request, a :class:`~scim2_client.SCIMResponseErrorObject`
|
|
257
|
+
exception will be raised. If :data:`False` the error object is returned. This value can be overwritten in methods.
|
|
258
|
+
|
|
244
259
|
"""
|
|
245
260
|
|
|
246
|
-
def __init__(
|
|
247
|
-
|
|
248
|
-
):
|
|
249
|
-
super().__init__(resource_models=resource_models)
|
|
261
|
+
def __init__(self, client: Client, *args, **kwargs):
|
|
262
|
+
super().__init__(*args, **kwargs)
|
|
250
263
|
self.client = client
|
|
251
264
|
|
|
252
265
|
async def create(
|
|
253
266
|
self,
|
|
254
267
|
resource: Union[AnyResource, dict],
|
|
255
|
-
check_request_payload: bool =
|
|
256
|
-
check_response_payload: bool =
|
|
268
|
+
check_request_payload: Optional[bool] = None,
|
|
269
|
+
check_response_payload: Optional[bool] = None,
|
|
257
270
|
expected_status_codes: Optional[
|
|
258
271
|
list[int]
|
|
259
272
|
] = BaseAsyncSCIMClient.CREATION_RESPONSE_STATUS_CODES,
|
|
260
|
-
raise_scim_errors: bool =
|
|
273
|
+
raise_scim_errors: Optional[bool] = None,
|
|
261
274
|
**kwargs,
|
|
262
275
|
) -> Union[AnyResource, Error, dict]:
|
|
263
276
|
req = self.prepare_create_request(
|
|
@@ -290,12 +303,12 @@ class AsyncSCIMClient(BaseAsyncSCIMClient):
|
|
|
290
303
|
resource_model: Optional[type[Resource]] = None,
|
|
291
304
|
id: Optional[str] = None,
|
|
292
305
|
search_request: Optional[Union[SearchRequest, dict]] = None,
|
|
293
|
-
check_request_payload: bool =
|
|
294
|
-
check_response_payload: bool =
|
|
306
|
+
check_request_payload: Optional[bool] = None,
|
|
307
|
+
check_response_payload: Optional[bool] = None,
|
|
295
308
|
expected_status_codes: Optional[
|
|
296
309
|
list[int]
|
|
297
310
|
] = BaseAsyncSCIMClient.QUERY_RESPONSE_STATUS_CODES,
|
|
298
|
-
raise_scim_errors: bool =
|
|
311
|
+
raise_scim_errors: Optional[bool] = None,
|
|
299
312
|
**kwargs,
|
|
300
313
|
):
|
|
301
314
|
req = self.prepare_query_request(
|
|
@@ -328,12 +341,12 @@ class AsyncSCIMClient(BaseAsyncSCIMClient):
|
|
|
328
341
|
async def search(
|
|
329
342
|
self,
|
|
330
343
|
search_request: Optional[SearchRequest] = None,
|
|
331
|
-
check_request_payload: bool =
|
|
332
|
-
check_response_payload: bool =
|
|
344
|
+
check_request_payload: Optional[bool] = None,
|
|
345
|
+
check_response_payload: Optional[bool] = None,
|
|
333
346
|
expected_status_codes: Optional[
|
|
334
347
|
list[int]
|
|
335
348
|
] = BaseAsyncSCIMClient.SEARCH_RESPONSE_STATUS_CODES,
|
|
336
|
-
raise_scim_errors: bool =
|
|
349
|
+
raise_scim_errors: Optional[bool] = None,
|
|
337
350
|
**kwargs,
|
|
338
351
|
) -> Union[AnyResource, ListResponse[AnyResource], Error, dict]:
|
|
339
352
|
req = self.prepare_search_request(
|
|
@@ -365,11 +378,11 @@ class AsyncSCIMClient(BaseAsyncSCIMClient):
|
|
|
365
378
|
self,
|
|
366
379
|
resource_model: type,
|
|
367
380
|
id: str,
|
|
368
|
-
check_response_payload: bool =
|
|
381
|
+
check_response_payload: Optional[bool] = None,
|
|
369
382
|
expected_status_codes: Optional[
|
|
370
383
|
list[int]
|
|
371
384
|
] = BaseAsyncSCIMClient.DELETION_RESPONSE_STATUS_CODES,
|
|
372
|
-
raise_scim_errors: bool =
|
|
385
|
+
raise_scim_errors: Optional[bool] = None,
|
|
373
386
|
**kwargs,
|
|
374
387
|
) -> Optional[Union[Error, dict]]:
|
|
375
388
|
req = self.prepare_delete_request(
|
|
@@ -396,12 +409,12 @@ class AsyncSCIMClient(BaseAsyncSCIMClient):
|
|
|
396
409
|
async def replace(
|
|
397
410
|
self,
|
|
398
411
|
resource: Union[AnyResource, dict],
|
|
399
|
-
check_request_payload: bool =
|
|
400
|
-
check_response_payload: bool =
|
|
412
|
+
check_request_payload: Optional[bool] = None,
|
|
413
|
+
check_response_payload: Optional[bool] = None,
|
|
401
414
|
expected_status_codes: Optional[
|
|
402
415
|
list[int]
|
|
403
416
|
] = BaseAsyncSCIMClient.REPLACEMENT_RESPONSE_STATUS_CODES,
|
|
404
|
-
raise_scim_errors: bool =
|
|
417
|
+
raise_scim_errors: Optional[bool] = None,
|
|
405
418
|
**kwargs,
|
|
406
419
|
) -> Union[AnyResource, Error, dict]:
|
|
407
420
|
req = self.prepare_replace_request(
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import json
|
|
1
2
|
from contextlib import contextmanager
|
|
2
3
|
from typing import Optional
|
|
3
4
|
from typing import Union
|
|
@@ -13,6 +14,7 @@ from werkzeug.test import Client
|
|
|
13
14
|
|
|
14
15
|
from scim2_client.client import BaseSyncSCIMClient
|
|
15
16
|
from scim2_client.errors import SCIMClientError
|
|
17
|
+
from scim2_client.errors import UnexpectedContentFormat
|
|
16
18
|
|
|
17
19
|
|
|
18
20
|
@contextmanager
|
|
@@ -20,6 +22,9 @@ def handle_response_error(response):
|
|
|
20
22
|
try:
|
|
21
23
|
yield
|
|
22
24
|
|
|
25
|
+
except json.decoder.JSONDecodeError as exc:
|
|
26
|
+
raise UnexpectedContentFormat(source=response) from exc
|
|
27
|
+
|
|
23
28
|
except SCIMClientError as exc:
|
|
24
29
|
exc.source = response
|
|
25
30
|
raise exc
|
|
@@ -36,6 +41,14 @@ class TestSCIMClient(BaseSyncSCIMClient):
|
|
|
36
41
|
:param scim_prefix: The scim root endpoint in the application.
|
|
37
42
|
:param resource_models: A tuple of :class:`~scim2_models.Resource` types expected to be handled by the SCIM client.
|
|
38
43
|
If a request payload describe a resource that is not in this list, an exception will be raised.
|
|
44
|
+
:param check_request_payload: If :data:`False`,
|
|
45
|
+
:code:`resource` is expected to be a dict that will be passed as-is in the request.
|
|
46
|
+
This value can be overwritten in methods.
|
|
47
|
+
:param check_response_payload: Whether to validate that the response payloads are valid.
|
|
48
|
+
If set, the raw payload will be returned. This value can be overwritten in methods.
|
|
49
|
+
:param raise_scim_errors: If :data:`True` and the server returned an
|
|
50
|
+
:class:`~scim2_models.Error` object during a request, a :class:`~scim2_client.SCIMResponseErrorObject`
|
|
51
|
+
exception will be raised. If :data:`False` the error object is returned. This value can be overwritten in methods.
|
|
39
52
|
|
|
40
53
|
.. code-block:: python
|
|
41
54
|
|
|
@@ -50,13 +63,8 @@ class TestSCIMClient(BaseSyncSCIMClient):
|
|
|
50
63
|
assert response_user.user_name == "foo"
|
|
51
64
|
"""
|
|
52
65
|
|
|
53
|
-
def __init__(
|
|
54
|
-
|
|
55
|
-
app,
|
|
56
|
-
scim_prefix: str = "",
|
|
57
|
-
resource_models: Optional[tuple[type[Resource]]] = None,
|
|
58
|
-
):
|
|
59
|
-
super().__init__(resource_models=resource_models)
|
|
66
|
+
def __init__(self, app, *args, scim_prefix: str = "", **kwargs):
|
|
67
|
+
super().__init__(*args, **kwargs)
|
|
60
68
|
self.client = Client(app)
|
|
61
69
|
self.scim_prefix = scim_prefix
|
|
62
70
|
|
|
@@ -71,12 +79,12 @@ class TestSCIMClient(BaseSyncSCIMClient):
|
|
|
71
79
|
def create(
|
|
72
80
|
self,
|
|
73
81
|
resource: Union[AnyResource, dict],
|
|
74
|
-
check_request_payload: bool =
|
|
75
|
-
check_response_payload: bool =
|
|
82
|
+
check_request_payload: Optional[bool] = None,
|
|
83
|
+
check_response_payload: Optional[bool] = None,
|
|
76
84
|
expected_status_codes: Optional[
|
|
77
85
|
list[int]
|
|
78
86
|
] = BaseSyncSCIMClient.CREATION_RESPONSE_STATUS_CODES,
|
|
79
|
-
raise_scim_errors: bool =
|
|
87
|
+
raise_scim_errors: Optional[bool] = None,
|
|
80
88
|
**kwargs,
|
|
81
89
|
) -> Union[AnyResource, Error, dict]:
|
|
82
90
|
req = self.prepare_create_request(
|
|
@@ -108,12 +116,12 @@ class TestSCIMClient(BaseSyncSCIMClient):
|
|
|
108
116
|
resource_model: Optional[type[Resource]] = None,
|
|
109
117
|
id: Optional[str] = None,
|
|
110
118
|
search_request: Optional[Union[SearchRequest, dict]] = None,
|
|
111
|
-
check_request_payload: bool =
|
|
112
|
-
check_response_payload: bool =
|
|
119
|
+
check_request_payload: Optional[bool] = None,
|
|
120
|
+
check_response_payload: Optional[bool] = None,
|
|
113
121
|
expected_status_codes: Optional[
|
|
114
122
|
list[int]
|
|
115
123
|
] = BaseSyncSCIMClient.QUERY_RESPONSE_STATUS_CODES,
|
|
116
|
-
raise_scim_errors: bool =
|
|
124
|
+
raise_scim_errors: Optional[bool] = None,
|
|
117
125
|
**kwargs,
|
|
118
126
|
):
|
|
119
127
|
req = self.prepare_query_request(
|
|
@@ -146,12 +154,12 @@ class TestSCIMClient(BaseSyncSCIMClient):
|
|
|
146
154
|
def search(
|
|
147
155
|
self,
|
|
148
156
|
search_request: Optional[SearchRequest] = None,
|
|
149
|
-
check_request_payload: bool =
|
|
150
|
-
check_response_payload: bool =
|
|
157
|
+
check_request_payload: Optional[bool] = None,
|
|
158
|
+
check_response_payload: Optional[bool] = None,
|
|
151
159
|
expected_status_codes: Optional[
|
|
152
160
|
list[int]
|
|
153
161
|
] = BaseSyncSCIMClient.SEARCH_RESPONSE_STATUS_CODES,
|
|
154
|
-
raise_scim_errors: bool =
|
|
162
|
+
raise_scim_errors: Optional[bool] = None,
|
|
155
163
|
**kwargs,
|
|
156
164
|
) -> Union[AnyResource, ListResponse[AnyResource], Error, dict]:
|
|
157
165
|
req = self.prepare_search_request(
|
|
@@ -182,11 +190,11 @@ class TestSCIMClient(BaseSyncSCIMClient):
|
|
|
182
190
|
self,
|
|
183
191
|
resource_model: type,
|
|
184
192
|
id: str,
|
|
185
|
-
check_response_payload: bool =
|
|
193
|
+
check_response_payload: Optional[bool] = None,
|
|
186
194
|
expected_status_codes: Optional[
|
|
187
195
|
list[int]
|
|
188
196
|
] = BaseSyncSCIMClient.DELETION_RESPONSE_STATUS_CODES,
|
|
189
|
-
raise_scim_errors: bool =
|
|
197
|
+
raise_scim_errors: Optional[bool] = None,
|
|
190
198
|
**kwargs,
|
|
191
199
|
) -> Optional[Union[Error, dict]]:
|
|
192
200
|
req = self.prepare_delete_request(
|
|
@@ -212,12 +220,12 @@ class TestSCIMClient(BaseSyncSCIMClient):
|
|
|
212
220
|
def replace(
|
|
213
221
|
self,
|
|
214
222
|
resource: Union[AnyResource, dict],
|
|
215
|
-
check_request_payload: bool =
|
|
216
|
-
check_response_payload: bool =
|
|
223
|
+
check_request_payload: Optional[bool] = None,
|
|
224
|
+
check_response_payload: Optional[bool] = None,
|
|
217
225
|
expected_status_codes: Optional[
|
|
218
226
|
list[int]
|
|
219
227
|
] = BaseSyncSCIMClient.REPLACEMENT_RESPONSE_STATUS_CODES,
|
|
220
|
-
raise_scim_errors: bool =
|
|
228
|
+
raise_scim_errors: Optional[bool] = None,
|
|
221
229
|
**kwargs,
|
|
222
230
|
) -> Union[AnyResource, Error, dict]:
|
|
223
231
|
req = self.prepare_replace_request(
|
|
@@ -2,9 +2,12 @@ import pytest
|
|
|
2
2
|
from scim2_models import ResourceType
|
|
3
3
|
from scim2_models import SearchRequest
|
|
4
4
|
from scim2_models import User
|
|
5
|
+
from werkzeug.wrappers import Request
|
|
6
|
+
from werkzeug.wrappers import Response
|
|
5
7
|
|
|
6
8
|
from scim2_client.engines.werkzeug import TestSCIMClient
|
|
7
9
|
from scim2_client.errors import SCIMResponseErrorObject
|
|
10
|
+
from scim2_client.errors import UnexpectedContentFormat
|
|
8
11
|
|
|
9
12
|
scim2_server = pytest.importorskip("scim2_server")
|
|
10
13
|
from scim2_server.backend import InMemoryBackend # noqa: E402
|
|
@@ -61,3 +64,15 @@ def test_werkzeug_engine(scim_client):
|
|
|
61
64
|
scim_client.delete(User, response_user.id)
|
|
62
65
|
with pytest.raises(SCIMResponseErrorObject):
|
|
63
66
|
scim_client.query(User, response_user.id)
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def test_no_json():
|
|
70
|
+
"""Test that pages that do not return JSON raise an UnexpectedContentFormat error."""
|
|
71
|
+
|
|
72
|
+
@Request.application
|
|
73
|
+
def application(request):
|
|
74
|
+
return Response("Hello, World!", content_type="application/scim+json")
|
|
75
|
+
|
|
76
|
+
client = TestSCIMClient(app=application, resource_models=(User,))
|
|
77
|
+
with pytest.raises(UnexpectedContentFormat):
|
|
78
|
+
client.query(url="/")
|
|
@@ -984,7 +984,7 @@ wheels = [
|
|
|
984
984
|
|
|
985
985
|
[[package]]
|
|
986
986
|
name = "scim2-client"
|
|
987
|
-
version = "0.3.
|
|
987
|
+
version = "0.3.2"
|
|
988
988
|
source = { editable = "." }
|
|
989
989
|
dependencies = [
|
|
990
990
|
{ name = "scim2-models" },
|
|
@@ -1017,6 +1017,7 @@ doc = [
|
|
|
1017
1017
|
{ name = "shibuya" },
|
|
1018
1018
|
{ name = "sphinx" },
|
|
1019
1019
|
{ name = "sphinx-issues" },
|
|
1020
|
+
{ name = "sphinx-paramlinks" },
|
|
1020
1021
|
]
|
|
1021
1022
|
|
|
1022
1023
|
[package.metadata]
|
|
@@ -1045,6 +1046,7 @@ doc = [
|
|
|
1045
1046
|
{ name = "shibuya", specifier = ">=2024.5.15" },
|
|
1046
1047
|
{ name = "sphinx", specifier = ">=7.3.7" },
|
|
1047
1048
|
{ name = "sphinx-issues", specifier = ">=5.0.0" },
|
|
1049
|
+
{ name = "sphinx-paramlinks", specifier = ">=0.6.0" },
|
|
1048
1050
|
]
|
|
1049
1051
|
|
|
1050
1052
|
[[package]]
|
|
@@ -1165,6 +1167,16 @@ wheels = [
|
|
|
1165
1167
|
{ url = "https://files.pythonhosted.org/packages/1d/14/a1b38212db8d327f53f2f56f0ed81c8b80ee2c2160e8819069c0d329d0a9/sphinx_issues-5.0.0-py3-none-any.whl", hash = "sha256:d80704a01c8af3d76586771a67a9e48f2d1a6091a0377458c49908460a6a31ea", size = 8063 },
|
|
1166
1168
|
]
|
|
1167
1169
|
|
|
1170
|
+
[[package]]
|
|
1171
|
+
name = "sphinx-paramlinks"
|
|
1172
|
+
version = "0.6.0"
|
|
1173
|
+
source = { registry = "https://pypi.org/simple" }
|
|
1174
|
+
dependencies = [
|
|
1175
|
+
{ name = "docutils" },
|
|
1176
|
+
{ name = "sphinx" },
|
|
1177
|
+
]
|
|
1178
|
+
sdist = { url = "https://files.pythonhosted.org/packages/ae/21/62d3a58ff7bd02bbb9245a63d1f0d2e0455522a11a78951d16088569fca8/sphinx-paramlinks-0.6.0.tar.gz", hash = "sha256:746a0816860aa3fff5d8d746efcbec4deead421f152687411db1d613d29f915e", size = 12363 }
|
|
1179
|
+
|
|
1168
1180
|
[[package]]
|
|
1169
1181
|
name = "sphinxcontrib-applehelp"
|
|
1170
1182
|
version = "2.0.0"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|