mantelo 2.2.1__tar.gz → 2.2.2__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 (61) hide show
  1. {mantelo-2.2.1 → mantelo-2.2.2}/.gitignore +1 -0
  2. mantelo-2.2.2/.release-please-manifest.json +1 -0
  3. {mantelo-2.2.1 → mantelo-2.2.2}/CHANGELOG.md +19 -0
  4. {mantelo-2.2.1 → mantelo-2.2.2}/CONTRIBUTING.md +2 -1
  5. {mantelo-2.2.1 → mantelo-2.2.2}/Makefile +8 -3
  6. {mantelo-2.2.1 → mantelo-2.2.2}/PKG-INFO +6 -2
  7. {mantelo-2.2.1 → mantelo-2.2.2}/README.md +4 -1
  8. {mantelo-2.2.1 → mantelo-2.2.2}/docker-compose.yml +1 -1
  9. {mantelo-2.2.1 → mantelo-2.2.2}/docs/00-getting_started.rst +2 -0
  10. {mantelo-2.2.1 → mantelo-2.2.2}/mantelo/__init__.py +1 -1
  11. {mantelo-2.2.1 → mantelo-2.2.2}/mantelo/connection.py +2 -5
  12. {mantelo-2.2.1 → mantelo-2.2.2}/mantelo/exceptions.py +4 -4
  13. {mantelo-2.2.1 → mantelo-2.2.2}/mantelo/version.py +3 -3
  14. {mantelo-2.2.1 → mantelo-2.2.2}/mantelo.egg-info/PKG-INFO +6 -2
  15. {mantelo-2.2.1 → mantelo-2.2.2}/mantelo.egg-info/SOURCES.txt +2 -0
  16. {mantelo-2.2.1 → mantelo-2.2.2}/mantelo.egg-info/requires.txt +1 -0
  17. mantelo-2.2.2/mantelo.egg-info/scm_file_list.json +58 -0
  18. mantelo-2.2.2/mantelo.egg-info/scm_version.json +8 -0
  19. {mantelo-2.2.1 → mantelo-2.2.2}/pyproject.toml +52 -4
  20. {mantelo-2.2.1 → mantelo-2.2.2}/tests/conftest.py +6 -7
  21. {mantelo-2.2.1 → mantelo-2.2.2}/tests/realms/orwell-realm.json +23 -0
  22. {mantelo-2.2.1 → mantelo-2.2.2}/tests/test_connection.py +12 -11
  23. mantelo-2.2.1/.release-please-manifest.json +0 -1
  24. {mantelo-2.2.1 → mantelo-2.2.2}/.readthedocs.yaml +0 -0
  25. {mantelo-2.2.1 → mantelo-2.2.2}/CODEOWNERS +0 -0
  26. {mantelo-2.2.1 → mantelo-2.2.2}/LICENSE +0 -0
  27. {mantelo-2.2.1 → mantelo-2.2.2}/MANIFEST.in +0 -0
  28. {mantelo-2.2.1 → mantelo-2.2.2}/docs/01-authentication.rst +0 -0
  29. {mantelo-2.2.1 → mantelo-2.2.2}/docs/02-making-calls.rst +0 -0
  30. {mantelo-2.2.1 → mantelo-2.2.2}/docs/03-examples.rst +0 -0
  31. {mantelo-2.2.1 → mantelo-2.2.2}/docs/04-faq.rst +0 -0
  32. {mantelo-2.2.1 → mantelo-2.2.2}/docs/90-api.rst +0 -0
  33. {mantelo-2.2.1 → mantelo-2.2.2}/docs/Makefile +0 -0
  34. {mantelo-2.2.1 → mantelo-2.2.2}/docs/_static/css/custom.css +0 -0
  35. {mantelo-2.2.1 → mantelo-2.2.2}/docs/_static/images/mantelo-128.png +0 -0
  36. {mantelo-2.2.1 → mantelo-2.2.2}/docs/_static/images/mantelo-256.png +0 -0
  37. {mantelo-2.2.1 → mantelo-2.2.2}/docs/_static/images/mantelo-512.png +0 -0
  38. {mantelo-2.2.1 → mantelo-2.2.2}/docs/_static/images/mantelo-social-preview.png +0 -0
  39. {mantelo-2.2.1 → mantelo-2.2.2}/docs/_static/images/mantelo-text-900.png +0 -0
  40. {mantelo-2.2.1 → mantelo-2.2.2}/docs/_static/images/mantelo.ico +0 -0
  41. {mantelo-2.2.1 → mantelo-2.2.2}/docs/_static/images/mantelo.svg +0 -0
  42. {mantelo-2.2.1 → mantelo-2.2.2}/docs/_templates/.gitkeep +0 -0
  43. {mantelo-2.2.1 → mantelo-2.2.2}/docs/_templates/layout.html +0 -0
  44. {mantelo-2.2.1 → mantelo-2.2.2}/docs/conf.py +0 -0
  45. {mantelo-2.2.1 → mantelo-2.2.2}/docs/index.rst +0 -0
  46. {mantelo-2.2.1 → mantelo-2.2.2}/docs/make.bat +0 -0
  47. {mantelo-2.2.1 → mantelo-2.2.2}/mantelo/client.py +0 -0
  48. {mantelo-2.2.1 → mantelo-2.2.2}/mantelo/internal/__init__.py +0 -0
  49. {mantelo-2.2.1 → mantelo-2.2.2}/mantelo/internal/api.py +0 -0
  50. {mantelo-2.2.1 → mantelo-2.2.2}/mantelo/internal/serializers.py +0 -0
  51. {mantelo-2.2.1 → mantelo-2.2.2}/mantelo/py.typed +0 -0
  52. {mantelo-2.2.1 → mantelo-2.2.2}/mantelo.egg-info/dependency_links.txt +0 -0
  53. {mantelo-2.2.1 → mantelo-2.2.2}/mantelo.egg-info/top_level.txt +0 -0
  54. {mantelo-2.2.1 → mantelo-2.2.2}/setup.cfg +0 -0
  55. {mantelo-2.2.1 → mantelo-2.2.2}/tests/__init__.py +0 -0
  56. {mantelo-2.2.1 → mantelo-2.2.2}/tests/constants.py +0 -0
  57. {mantelo-2.2.1 → mantelo-2.2.2}/tests/internal/test_api.py +1 -1
  58. {mantelo-2.2.1 → mantelo-2.2.2}/tests/internal/test_serialiers.py +0 -0
  59. {mantelo-2.2.1 → mantelo-2.2.2}/tests/realms/master-realm.json +0 -0
  60. {mantelo-2.2.1 → mantelo-2.2.2}/tests/test_client.py +0 -0
  61. {mantelo-2.2.1 → mantelo-2.2.2}/tox.ini +0 -0
@@ -12,3 +12,4 @@ mantelo/version.py
12
12
  __pycache__
13
13
 
14
14
  docs/_build
15
+ .ruff_cache/
@@ -0,0 +1 @@
1
+ {".":"2.2.2"}
@@ -1,5 +1,24 @@
1
1
  # Changelog
2
2
 
3
+ ## [2.2.2](https://github.com/derlin/mantelo/compare/v2.2.1...v2.2.2) (2026-11-11)
4
+
5
+
6
+ ### 🐛 Bug Fixes
7
+
8
+ * grant kc-admin-api scope to test client for keycloak 26.8.2 ([458eee9](https://github.com/derlin/mantelo/commit/458eee9f2ce9a4969adf2be1aa1aea8ba0349caa))
9
+
10
+
11
+ ### 💬 Documentation
12
+
13
+ * state tested keycloak versions ([a0a07bc](https://github.com/derlin/mantelo/commit/a0a07bc97ea7a5092d69429fdddf1e0f30ddd663))
14
+
15
+
16
+ ### 🦀 Build and CI
17
+
18
+ * keep a stable build check for branch protection ([94d655b](https://github.com/derlin/mantelo/commit/94d655b852bf28ac44d56a1730630f954a5d4ee4))
19
+ * test against oldest supported and latest keycloak ([55bf108](https://github.com/derlin/mantelo/commit/55bf108a0d7f096748b0a0a2bb9114dde23c0f35))
20
+ * update actions to latest ([764f83b](https://github.com/derlin/mantelo/commit/764f83be18aa37c249b7a15b30738fcf6e1966d8))
21
+
3
22
  ## [2.2.1](https://github.com/derlin/mantelo/compare/v2.2.0...v2.2.1) (2026-04-13)
4
23
 
5
24
 
@@ -54,7 +54,8 @@ Documentation
54
54
  docs-open Open the documentation locally (requires make docs to have ran).
55
55
 
56
56
  Development
57
- lint Run ruff to format and lint (inside docker).
57
+ lint Check formatting and lint with ruff.
58
+ format Format and auto-fix with ruff.
58
59
  test Run tests with tox (inside docker).
59
60
  mypy Run mypy locally to check types.
60
61
  export-realms Export test realms after changes in Keycloak Test Server.
@@ -1,4 +1,4 @@
1
- .PHONY: all help build docs lint test mypy export-realms
1
+ .PHONY: all help build docs lint format test mypy export-realms
2
2
 
3
3
  default: help
4
4
 
@@ -30,8 +30,13 @@ docs-test: ## Test the documentation code snippets.
30
30
 
31
31
  ##@ Development
32
32
 
33
- lint: ## Run ruff to format and lint (inside docker).
34
- docker run --rm -e LINT_FOLDER_PYTHON=mantelo -v $(CURDIR):/app divio/lint /bin/lint ${ARGS} --run=python
33
+ lint: ## Check formatting and lint with ruff.
34
+ ruff format --check mantelo tests
35
+ ruff check mantelo tests
36
+
37
+ format: ## Format and auto-fix with ruff.
38
+ ruff format mantelo tests
39
+ ruff check --fix --show-fixes mantelo tests
35
40
 
36
41
  test: ## Run tests with tox (inside docker).
37
42
  coverage erase || true
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mantelo
3
- Version: 2.2.1
3
+ Version: 2.2.2
4
4
  Summary: ✨ Keycloak Admin REST Api Client for Python ✨
5
5
  Author-email: Lucy Linder <lucy.derlin@gmail.com>
6
6
  License: Apache License
@@ -230,6 +230,7 @@ Requires-Dist: attrs
230
230
  Requires-Dist: requests
231
231
  Provides-Extra: dev
232
232
  Requires-Dist: build; extra == "dev"
233
+ Requires-Dist: ruff; extra == "dev"
233
234
  Requires-Dist: coverage; extra == "dev"
234
235
  Requires-Dist: tox; extra == "dev"
235
236
  Requires-Dist: mypy; extra == "dev"
@@ -313,6 +314,8 @@ To get started, install the package:
313
314
  pip install mantelo
314
315
  ```
315
316
 
317
+ CI tests mantelo against Keycloak 26.0 and the latest release. Older versions may work, but are not tested.
318
+
316
319
  Now, assuming you have a Keycloak Server running, what's left is to:
317
320
 
318
321
  1. authenticate, see [🔐 Authenticate to Keycloak](#-authenticate-to-keycloak)
@@ -408,7 +411,8 @@ client = KeycloakAdmin.from_username_password(
408
411
  > - to have "Client authentication" enabled,
409
412
  > - to support the `Service accounts roles` authentication flow,
410
413
  >
411
- > - to have one or more service account roles granting access to Admin endpoints.
414
+ > - to have one or more service account roles granting access to Admin endpoints,
415
+ > - since Keycloak 26.8.2, to have the `kc-admin-api` client scope as a default scope.
412
416
  >
413
417
  > Go to your client's "Credentials" tab to find the client secret.
414
418
 
@@ -64,6 +64,8 @@ To get started, install the package:
64
64
  pip install mantelo
65
65
  ```
66
66
 
67
+ CI tests mantelo against Keycloak 26.0 and the latest release. Older versions may work, but are not tested.
68
+
67
69
  Now, assuming you have a Keycloak Server running, what's left is to:
68
70
 
69
71
  1. authenticate, see [🔐 Authenticate to Keycloak](#-authenticate-to-keycloak)
@@ -159,7 +161,8 @@ client = KeycloakAdmin.from_username_password(
159
161
  > - to have "Client authentication" enabled,
160
162
  > - to support the `Service accounts roles` authentication flow,
161
163
  >
162
- > - to have one or more service account roles granting access to Admin endpoints.
164
+ > - to have one or more service account roles granting access to Admin endpoints,
165
+ > - since Keycloak 26.8.2, to have the `kc-admin-api` client scope as a default scope.
163
166
  >
164
167
  > Go to your client's "Credentials" tab to find the client secret.
165
168
 
@@ -1,6 +1,6 @@
1
1
  services:
2
2
  keycloak:
3
- image: quay.io/keycloak/keycloak:latest
3
+ image: quay.io/keycloak/keycloak:${KEYCLOAK_VERSION:-latest}
4
4
  command: start-dev --import-realm
5
5
  ports:
6
6
  - 9090:8080
@@ -15,6 +15,8 @@ To get started, install the package:
15
15
 
16
16
  pip install mantelo
17
17
 
18
+ CI tests mantelo against Keycloak 26.0 and the latest release. Older versions may work, but are not tested.
19
+
18
20
  Now, assuming you have a Keycloak Server running, what's left is to:
19
21
 
20
22
  1. authenticate to Keycloak, :ref:`authentication`
@@ -8,4 +8,4 @@ from .client import KeycloakAdmin
8
8
  from .exceptions import AuthenticationException, HttpException
9
9
 
10
10
 
11
- __all__ = ["KeycloakAdmin", "AuthenticationException", "HttpException"]
11
+ __all__ = ["AuthenticationException", "HttpException", "KeycloakAdmin"]
@@ -116,11 +116,8 @@ class Token:
116
116
 
117
117
  :return: True if a refresh token exists and is still valid.
118
118
  """
119
- if (exp := self.refresh_expires_at) and _now() < (
120
- exp - timedelta(seconds=2)
121
- ):
122
- return True
123
- return False
119
+ exp = self.refresh_expires_at
120
+ return bool(exp and _now() < (exp - timedelta(seconds=2)))
124
121
 
125
122
  @classmethod
126
123
  def from_dict(cls, data: dict, now: datetime | None = None) -> "Token":
@@ -1,3 +1,5 @@
1
+ import contextlib
2
+
1
3
  import requests
2
4
  from attrs import field, frozen
3
5
 
@@ -41,11 +43,9 @@ class HttpException(ManteloException):
41
43
  @classmethod
42
44
  def from_response(cls, response: requests.Response) -> "HttpException":
43
45
  json = {}
44
- try:
45
- # Most API use JSON, but not all!
46
+ # Most API use JSON, but not all!
47
+ with contextlib.suppress(Exception):
46
48
  json = response.json()
47
- except Exception: # noqa: S110
48
- pass
49
49
 
50
50
  return cls(
51
51
  url=response.request.url or "",
@@ -18,7 +18,7 @@ version_tuple: tuple[int | str, ...]
18
18
  commit_id: str | None
19
19
  __commit_id__: str | None
20
20
 
21
- __version__ = version = '2.2.1'
22
- __version_tuple__ = version_tuple = (2, 2, 1)
21
+ __version__ = version = '2.2.2'
22
+ __version_tuple__ = version_tuple = (2, 2, 2)
23
23
 
24
- __commit_id__ = commit_id = 'g19e2c97f3'
24
+ __commit_id__ = commit_id = 'g40c5e5f7a'
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mantelo
3
- Version: 2.2.1
3
+ Version: 2.2.2
4
4
  Summary: ✨ Keycloak Admin REST Api Client for Python ✨
5
5
  Author-email: Lucy Linder <lucy.derlin@gmail.com>
6
6
  License: Apache License
@@ -230,6 +230,7 @@ Requires-Dist: attrs
230
230
  Requires-Dist: requests
231
231
  Provides-Extra: dev
232
232
  Requires-Dist: build; extra == "dev"
233
+ Requires-Dist: ruff; extra == "dev"
233
234
  Requires-Dist: coverage; extra == "dev"
234
235
  Requires-Dist: tox; extra == "dev"
235
236
  Requires-Dist: mypy; extra == "dev"
@@ -313,6 +314,8 @@ To get started, install the package:
313
314
  pip install mantelo
314
315
  ```
315
316
 
317
+ CI tests mantelo against Keycloak 26.0 and the latest release. Older versions may work, but are not tested.
318
+
316
319
  Now, assuming you have a Keycloak Server running, what's left is to:
317
320
 
318
321
  1. authenticate, see [🔐 Authenticate to Keycloak](#-authenticate-to-keycloak)
@@ -408,7 +411,8 @@ client = KeycloakAdmin.from_username_password(
408
411
  > - to have "Client authentication" enabled,
409
412
  > - to support the `Service accounts roles` authentication flow,
410
413
  >
411
- > - to have one or more service account roles granting access to Admin endpoints.
414
+ > - to have one or more service account roles granting access to Admin endpoints,
415
+ > - since Keycloak 26.8.2, to have the `kc-admin-api` client scope as a default scope.
412
416
  >
413
417
  > Go to your client's "Credentials" tab to find the client secret.
414
418
 
@@ -41,6 +41,8 @@ mantelo.egg-info/PKG-INFO
41
41
  mantelo.egg-info/SOURCES.txt
42
42
  mantelo.egg-info/dependency_links.txt
43
43
  mantelo.egg-info/requires.txt
44
+ mantelo.egg-info/scm_file_list.json
45
+ mantelo.egg-info/scm_version.json
44
46
  mantelo.egg-info/top_level.txt
45
47
  mantelo/internal/__init__.py
46
48
  mantelo/internal/api.py
@@ -3,6 +3,7 @@ requests
3
3
 
4
4
  [dev]
5
5
  build
6
+ ruff
6
7
  coverage
7
8
  tox
8
9
  mypy
@@ -0,0 +1,58 @@
1
+ {
2
+ "files": [
3
+ ".github/workflows/build.yml",
4
+ ".github/workflows/release-please-config.json",
5
+ ".github/workflows/release.yml",
6
+ ".github/workflows/weekly.yml",
7
+ ".gitignore",
8
+ ".readthedocs.yaml",
9
+ ".release-please-manifest.json",
10
+ "CHANGELOG.md",
11
+ "CODEOWNERS",
12
+ "CONTRIBUTING.md",
13
+ "LICENSE",
14
+ "MANIFEST.in",
15
+ "Makefile",
16
+ "README.md",
17
+ "docker-compose.yml",
18
+ "docs/00-getting_started.rst",
19
+ "docs/01-authentication.rst",
20
+ "docs/02-making-calls.rst",
21
+ "docs/03-examples.rst",
22
+ "docs/04-faq.rst",
23
+ "docs/90-api.rst",
24
+ "docs/Makefile",
25
+ "docs/_static/css/custom.css",
26
+ "docs/_static/images/mantelo-128.png",
27
+ "docs/_static/images/mantelo-256.png",
28
+ "docs/_static/images/mantelo-512.png",
29
+ "docs/_static/images/mantelo-social-preview.png",
30
+ "docs/_static/images/mantelo-text-900.png",
31
+ "docs/_static/images/mantelo.ico",
32
+ "docs/_static/images/mantelo.svg",
33
+ "docs/_templates/.gitkeep",
34
+ "docs/_templates/layout.html",
35
+ "docs/conf.py",
36
+ "docs/index.rst",
37
+ "docs/make.bat",
38
+ "mantelo/__init__.py",
39
+ "mantelo/client.py",
40
+ "mantelo/connection.py",
41
+ "mantelo/exceptions.py",
42
+ "mantelo/internal/__init__.py",
43
+ "mantelo/internal/api.py",
44
+ "mantelo/internal/serializers.py",
45
+ "mantelo/py.typed",
46
+ "pyproject.toml",
47
+ "tests/__init__.py",
48
+ "tests/conftest.py",
49
+ "tests/constants.py",
50
+ "tests/internal/test_api.py",
51
+ "tests/internal/test_serialiers.py",
52
+ "tests/realms/master-realm.json",
53
+ "tests/realms/orwell-realm.json",
54
+ "tests/test_client.py",
55
+ "tests/test_connection.py",
56
+ "tox.ini"
57
+ ]
58
+ }
@@ -0,0 +1,8 @@
1
+ {
2
+ "tag": "2.2.2",
3
+ "distance": 0,
4
+ "node": "g40c5e5f7a89f4a1b717762d7b0e77d203eceedb2",
5
+ "dirty": false,
6
+ "branch": "HEAD",
7
+ "node_date": "2026-11-11"
8
+ }
@@ -47,6 +47,7 @@ dependencies = [
47
47
  [project.optional-dependencies]
48
48
  dev = [
49
49
  "build",
50
+ "ruff",
50
51
  "coverage",
51
52
  "tox",
52
53
  "mypy",
@@ -98,14 +99,61 @@ write_to = "mantelo/version.py"
98
99
 
99
100
 
100
101
  [tool.ruff]
101
- extend = "/presets/ruff.toml"
102
- target-version = "py310" # lowest supported version
102
+ line-length = 79
103
+ target-version = "py310" # lowest supported version
103
104
 
104
105
  [tool.ruff.lint]
105
- extend-ignore = [
106
- "S101", # allow asserts
106
+ # S101 (assert used) is deliberately not selected: we allow asserts.
107
+ select = [
108
+ "F", # Pyflakes
109
+ "E", # pycodestyle errors
110
+ "W", # pycodestyle warnings
111
+ "I", # isort
112
+ "UP", # pyupgrade
113
+ "YTT", # flake8-2020 (usage of sys package)
114
+ "S110", # try-except-pass detected, consider logging the exception
115
+ "B", # flake8-bugbear
116
+ "C4", # flake8-comprehensions
117
+ "T10", # flake8-debugger
118
+ "EXE", # flake8-executable
119
+ "FA", # flake8-future-annotations
120
+ "ISC", # flake8-implicit-str-concat
121
+ "PIE", # flake8-pie (misc lints)
122
+ "T20", # flake8-print
123
+ "PT", # flake8-pytest-style
124
+ "RSE", # flake8-raise
125
+ "RET", # flake8-return
126
+ "SIM", # flake8-simplify
127
+ "DTZ", # flake8-datetimez (token expiry relies on aware datetimes)
128
+ "LOG", # flake8-logging
129
+ "G", # flake8-logging-format
130
+ "PERF", # perflint
131
+ "PLE", # pylint ("E" subset)
132
+ "PLW", # pylint ("W" subset)
133
+ "FLY", # static join to f-string
134
+ "RUF", # ruff miscellaneous lints
107
135
  ]
108
136
 
137
+ ignore = [
138
+ "E501", # line too long (the formatter owns line length)
139
+ "B904", # raise-without-from-inside-except
140
+ "RET505", # superfluous else return
141
+ "PLW2901", # redefined loop name
142
+ "RUF012", # mutable class default
143
+ # Tests assert on the exception message via `excinfo.value`, which is
144
+ # stricter than `match=`, so requiring `match=` would be a step back.
145
+ "PT011", # pytest.raises too broad
146
+
147
+ # conflicts with the ruff formatter
148
+ "W191",
149
+ "ISC001",
150
+ "ISC002",
151
+ ]
152
+
153
+ [tool.ruff.lint.isort]
154
+ lines-after-imports = 2
155
+ lines-between-types = 0
156
+
109
157
 
110
158
  [tool.coverage.report]
111
159
  # Regexes for lines to exclude from consideration
@@ -2,17 +2,16 @@ from unittest.mock import MagicMock
2
2
 
3
3
  import pytest
4
4
 
5
- from mantelo.internal import serializers
6
5
  from mantelo.connection import (
7
6
  ClientCredentialsConnection,
8
7
  UsernamePasswordConnection,
9
8
  )
10
- from mantelo.internal import api
9
+ from mantelo.internal import api, serializers
11
10
 
12
11
  from . import constants
13
12
 
14
13
 
15
- @pytest.fixture()
14
+ @pytest.fixture
16
15
  def openid_connection_password():
17
16
  return UsernamePasswordConnection(
18
17
  server_url=constants.TEST_SERVER_URL,
@@ -23,7 +22,7 @@ def openid_connection_password():
23
22
  )
24
23
 
25
24
 
26
- @pytest.fixture()
25
+ @pytest.fixture
27
26
  def openid_connection_sa():
28
27
  return ClientCredentialsConnection(
29
28
  server_url=constants.TEST_SERVER_URL,
@@ -33,7 +32,7 @@ def openid_connection_sa():
33
32
  )
34
33
 
35
34
 
36
- @pytest.fixture()
35
+ @pytest.fixture
37
36
  def openid_connection_admin():
38
37
  return UsernamePasswordConnection(
39
38
  server_url=constants.TEST_SERVER_URL,
@@ -44,7 +43,7 @@ def openid_connection_admin():
44
43
  )
45
44
 
46
45
 
47
- @pytest.fixture()
46
+ @pytest.fixture
48
47
  def mock_session():
49
48
  session = MagicMock()
50
49
  session.request.return_value = MagicMock(status_code=200)
@@ -55,7 +54,7 @@ def mock_session():
55
54
  return session
56
55
 
57
56
 
58
- @pytest.fixture()
57
+ @pytest.fixture
59
58
  def mock_store(mock_session):
60
59
  return api.Store(
61
60
  base_url="https://example.com",
@@ -574,6 +574,28 @@
574
574
  ]
575
575
  },
576
576
  "clientScopes": [
577
+ {
578
+ "attributes": {
579
+ "display.on.consent.screen": "false",
580
+ "include.in.token.scope": "true"
581
+ },
582
+ "description": "Grants access to the Keycloak Admin REST API by adding its required audience to the token",
583
+ "name": "kc-admin-api",
584
+ "protocol": "openid-connect",
585
+ "protocolMappers": [
586
+ {
587
+ "config": {
588
+ "access.token.claim": "true",
589
+ "introspection.token.claim": "true",
590
+ "lightweight.claim": "true"
591
+ },
592
+ "consentRequired": false,
593
+ "name": "admin-api-audience",
594
+ "protocol": "openid-connect",
595
+ "protocolMapper": "oidc-admin-api-audience-mapper"
596
+ }
597
+ ]
598
+ },
577
599
  {
578
600
  "attributes": {
579
601
  "consent.screen.text": "${offlineAccessScopeConsentText}",
@@ -1375,6 +1397,7 @@
1375
1397
  "defaultClientScopes": [
1376
1398
  "web-origins",
1377
1399
  "acr",
1400
+ "kc-admin-api",
1378
1401
  "profile",
1379
1402
  "roles",
1380
1403
  "email"
@@ -1,14 +1,15 @@
1
- import pytest
1
+ from datetime import datetime, timedelta, timezone
2
2
 
3
+ import pytest
4
+ import requests
3
5
  from attrs import evolve
6
+
4
7
  from mantelo.connection import (
5
- Token,
6
8
  AuthenticationException,
7
9
  ClientCredentialsConnection,
10
+ Token,
8
11
  UsernamePasswordConnection,
9
12
  )
10
- from datetime import datetime, timedelta, timezone
11
- import requests
12
13
 
13
14
 
14
15
  def test_token_from_dict():
@@ -35,7 +36,7 @@ def test_token_from_dict():
35
36
 
36
37
 
37
38
  def test_refresh_without_expire():
38
- with pytest.raises(TypeError, match="Missing refresh_expires_in."):
39
+ with pytest.raises(TypeError, match=r"Missing refresh_expires_in\."):
39
40
  Token(
40
41
  access_token="<any>",
41
42
  expires_in=123,
@@ -145,12 +146,12 @@ def test_ClientCredentialsconnection_init():
145
146
 
146
147
 
147
148
  def test_openidconnection_default_values():
148
- args = dict(
149
- server_url="https://kc.test",
150
- realm_name="test",
151
- client_id="foo-client",
152
- client_secret="s3cr3t",
153
- )
149
+ args = {
150
+ "server_url": "https://kc.test",
151
+ "realm_name": "test",
152
+ "client_id": "foo-client",
153
+ "client_secret": "s3cr3t",
154
+ }
154
155
 
155
156
  # Defaults
156
157
  conn = ClientCredentialsConnection(**args)
@@ -1 +0,0 @@
1
- {".":"2.2.1"}
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
@@ -3,8 +3,8 @@ from unittest.mock import MagicMock, Mock, PropertyMock
3
3
  import pytest
4
4
  import requests
5
5
 
6
- from mantelo.internal import api as _api
7
6
  from mantelo import exceptions
7
+ from mantelo.internal import api as _api
8
8
  from mantelo.internal.serializers import JsonSerializer
9
9
 
10
10
 
File without changes
File without changes