scim2-client 0.3.2__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.
Files changed (35) hide show
  1. {scim2_client-0.3.2 → scim2_client-0.3.3}/PKG-INFO +1 -1
  2. {scim2_client-0.3.2 → scim2_client-0.3.3}/doc/changelog.rst +11 -3
  3. {scim2_client-0.3.2 → scim2_client-0.3.3}/doc/tutorial.rst +11 -11
  4. {scim2_client-0.3.2 → scim2_client-0.3.3}/pyproject.toml +1 -1
  5. {scim2_client-0.3.2 → scim2_client-0.3.3}/scim2_client/engines/werkzeug.py +5 -0
  6. {scim2_client-0.3.2 → scim2_client-0.3.3}/tests/engines/test_werkzeug.py +15 -0
  7. {scim2_client-0.3.2 → scim2_client-0.3.3}/.github/FUNDING.yml +0 -0
  8. {scim2_client-0.3.2 → scim2_client-0.3.3}/.github/workflows/release.yml +0 -0
  9. {scim2_client-0.3.2 → scim2_client-0.3.3}/.github/workflows/tests.yaml +0 -0
  10. {scim2_client-0.3.2 → scim2_client-0.3.3}/.gitignore +0 -0
  11. {scim2_client-0.3.2 → scim2_client-0.3.3}/.pre-commit-config.yaml +0 -0
  12. {scim2_client-0.3.2 → scim2_client-0.3.3}/.readthedocs.yml +0 -0
  13. {scim2_client-0.3.2 → scim2_client-0.3.3}/LICENSE.md +0 -0
  14. {scim2_client-0.3.2 → scim2_client-0.3.3}/README.md +0 -0
  15. {scim2_client-0.3.2 → scim2_client-0.3.3}/doc/__init__.py +0 -0
  16. {scim2_client-0.3.2 → scim2_client-0.3.3}/doc/conf.py +0 -0
  17. {scim2_client-0.3.2 → scim2_client-0.3.3}/doc/contributing.rst +0 -0
  18. {scim2_client-0.3.2 → scim2_client-0.3.3}/doc/index.rst +0 -0
  19. {scim2_client-0.3.2 → scim2_client-0.3.3}/doc/reference.rst +0 -0
  20. {scim2_client-0.3.2 → scim2_client-0.3.3}/scim2_client/__init__.py +0 -0
  21. {scim2_client-0.3.2 → scim2_client-0.3.3}/scim2_client/client.py +0 -0
  22. {scim2_client-0.3.2 → scim2_client-0.3.3}/scim2_client/engines/__init__.py +0 -0
  23. {scim2_client-0.3.2 → scim2_client-0.3.3}/scim2_client/engines/httpx.py +0 -0
  24. {scim2_client-0.3.2 → scim2_client-0.3.3}/scim2_client/errors.py +0 -0
  25. {scim2_client-0.3.2 → scim2_client-0.3.3}/scim2_client/py.typed +0 -0
  26. {scim2_client-0.3.2 → scim2_client-0.3.3}/tests/__init__.py +0 -0
  27. {scim2_client-0.3.2 → scim2_client-0.3.3}/tests/engines/__init__.py +0 -0
  28. {scim2_client-0.3.2 → scim2_client-0.3.3}/tests/engines/test_httpx.py +0 -0
  29. {scim2_client-0.3.2 → scim2_client-0.3.3}/tests/test_create.py +0 -0
  30. {scim2_client-0.3.2 → scim2_client-0.3.3}/tests/test_delete.py +0 -0
  31. {scim2_client-0.3.2 → scim2_client-0.3.3}/tests/test_query.py +0 -0
  32. {scim2_client-0.3.2 → scim2_client-0.3.3}/tests/test_replace.py +0 -0
  33. {scim2_client-0.3.2 → scim2_client-0.3.3}/tests/test_search.py +0 -0
  34. {scim2_client-0.3.2 → scim2_client-0.3.3}/tests/test_utils.py +0 -0
  35. {scim2_client-0.3.2 → scim2_client-0.3.3}/uv.lock +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: scim2-client
3
- Version: 0.3.2
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,14 @@
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
+
4
12
  [0.3.2] - 2024-11-29
5
13
  --------------------
6
14
 
@@ -32,12 +40,12 @@ Fixed
32
40
  Added
33
41
  ^^^^^
34
42
  - The `Unknown resource type` request error keeps a reference to the faulty payload.
35
- - New `werkzeug` request engine for application development purpose.
36
- - New `AsyncSCIMClient` request engine. :issue:`1`
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`
37
45
 
38
46
  Changed
39
47
  ^^^^^^^
40
- - Separate httpx network code and SCIM code in separate file as a basis for async support (and maybe other request engines).
48
+ - Separate httpx network code and SCIM code in separate file as a basis for async support (and other request engines).
41
49
 
42
50
  [0.2.2] - 2024-11-12
43
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, resource_types=(User[EnterpriseUser], Group))
20
+ scim = SyncSCIMClient(client, resource_models=(User[EnterpriseUser], Group))
21
21
 
22
- You need to give to indicate to :class:`~scim2_client.SCIMClient` all the different :class:`~scim2_models.Resource` types that you will need to manipulate with the :code:`resource_types` parameter.
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:`resource_types` parameter.
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.BaseSCIMClient.create`
37
- - :meth:`~scim2_client.BaseSCIMClient.query`
38
- - :meth:`~scim2_client.BaseSCIMClient.replace`
39
- - :meth:`~scim2_client.BaseSCIMClient.delete`
40
- - :meth:`~scim2_client.BaseSCIMClient.search`
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
- - :code:`check_request_payload`:
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
- - :code:`check_response_payload`:
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
- - :code:`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.
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.2"
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"}
@@ -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
@@ -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="/")
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes