scim2-cli 0.6.0__tar.gz → 0.7.1__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: scim2-cli
3
- Version: 0.6.0
3
+ Version: 0.7.1
4
4
  Summary: SCIM application development CLI
5
5
  Keywords: scim,scim2,provisioning,rfc7643,rfc7644
6
6
  Author: Yaal Coop
@@ -207,19 +207,20 @@ License: Apache License
207
207
  See the License for the specific language governing permissions and
208
208
  limitations under the License.
209
209
  Classifier: Intended Audience :: Developers
210
- Classifier: Development Status :: 3 - Alpha
210
+ Classifier: Development Status :: 4 - Beta
211
211
  Classifier: Programming Language :: Python :: 3.11
212
212
  Classifier: Programming Language :: Python :: 3.12
213
213
  Classifier: Programming Language :: Python :: 3.13
214
214
  Classifier: Programming Language :: Python :: 3.14
215
+ Classifier: Programming Language :: Python :: 3.15
215
216
  Classifier: Programming Language :: Python :: Implementation :: CPython
216
217
  Classifier: License :: OSI Approved :: Apache Software License
217
218
  Classifier: Environment :: Web Environment
218
219
  Classifier: Programming Language :: Python
219
220
  Classifier: Operating System :: OS Independent
220
221
  Requires-Dist: click>=8.5.0
221
- Requires-Dist: scim2-client[httpx2]>=0.13.2
222
- Requires-Dist: scim2-tester>=0.5.1
222
+ Requires-Dist: scim2-client[httpx2]>=0.14.0
223
+ Requires-Dist: scim2-tester>=0.6.4
223
224
  Requires-Dist: sphinx-click-rst-to-ansi-formatter>=0.2.0
224
225
  Requires-Dist: pydanclick>=0.5.0
225
226
  Requires-Dist: pygments>=2.18.0
@@ -230,6 +231,8 @@ Project-URL: changelog, https://scim2-cli.readthedocs.io/en/latest/changelog.htm
230
231
  Project-URL: funding, https://github.com/sponsors/python-scim
231
232
  Description-Content-Type: text/markdown
232
233
 
234
+ <img alt="python-scim logo" src="https://raw.githubusercontent.com/python-scim/.github/refs/heads/main/python-scim.svg" height="72" align="right">
235
+
233
236
  # scim2-cli
234
237
 
235
238
  An utility command line to help you perform requests against a SCIM server, while validating input and response payloads. It also uses [scim2-tester](https://scim2-tester.readthedocs.io) to perform a [SCIM server compliance test](https://scim2-cli.readthedocs.io/en/latest/reference.html#scim-url-test).
@@ -1,3 +1,5 @@
1
+ <img alt="python-scim logo" src="https://raw.githubusercontent.com/python-scim/.github/refs/heads/main/python-scim.svg" height="72" align="right">
2
+
1
3
  # scim2-cli
2
4
 
3
5
  An utility command line to help you perform requests against a SCIM server, while validating input and response payloads. It also uses [scim2-tester](https://scim2-tester.readthedocs.io) to perform a [SCIM server compliance test](https://scim2-cli.readthedocs.io/en/latest/reference.html#scim-url-test).
@@ -4,7 +4,7 @@ build-backend = "uv_build"
4
4
 
5
5
  [project]
6
6
  name = "scim2-cli"
7
- version = "0.6.0"
7
+ version = "0.7.1"
8
8
  description = "SCIM application development CLI"
9
9
  readme = "README.md"
10
10
  keywords = [
@@ -16,11 +16,12 @@ keywords = [
16
16
  ]
17
17
  classifiers = [
18
18
  "Intended Audience :: Developers",
19
- "Development Status :: 3 - Alpha",
19
+ "Development Status :: 4 - Beta",
20
20
  "Programming Language :: Python :: 3.11",
21
21
  "Programming Language :: Python :: 3.12",
22
22
  "Programming Language :: Python :: 3.13",
23
23
  "Programming Language :: Python :: 3.14",
24
+ "Programming Language :: Python :: 3.15",
24
25
  "Programming Language :: Python :: Implementation :: CPython",
25
26
  "License :: OSI Approved :: Apache Software License",
26
27
  "Environment :: Web Environment",
@@ -30,8 +31,8 @@ classifiers = [
30
31
  requires-python = ">= 3.11"
31
32
  dependencies = [
32
33
  "click>=8.5.0",
33
- "scim2-client[httpx2]>=0.13.2",
34
- "scim2-tester>=0.5.1",
34
+ "scim2-client[httpx2]>=0.14.0",
35
+ "scim2-tester>=0.6.4",
35
36
  "sphinx-click-rst-to-ansi-formatter>=0.2.0",
36
37
  "pydanclick>=0.5.0",
37
38
  "pygments>=2.18.0",
@@ -161,6 +162,7 @@ env_list = [
161
162
  "py312",
162
163
  "py313",
163
164
  "py314",
165
+ "py315",
164
166
  "minversions",
165
167
  "doc",
166
168
  "bundle",
@@ -4,7 +4,7 @@ build-backend = "uv_build"
4
4
 
5
5
  [project]
6
6
  name = "scim2-cli"
7
- version = "0.6.0"
7
+ version = "0.7.1"
8
8
  description = "SCIM application development CLI"
9
9
  authors = [{name="Yaal Coop", email="contact@yaal.coop"}]
10
10
  license = {file = "LICENSE.md"}
@@ -12,11 +12,12 @@ readme = "README.md"
12
12
  keywords = ["scim", "scim2", "provisioning", "rfc7643", "rfc7644"]
13
13
  classifiers = [
14
14
  "Intended Audience :: Developers",
15
- "Development Status :: 3 - Alpha",
15
+ "Development Status :: 4 - Beta",
16
16
  "Programming Language :: Python :: 3.11",
17
17
  "Programming Language :: Python :: 3.12",
18
18
  "Programming Language :: Python :: 3.13",
19
19
  "Programming Language :: Python :: 3.14",
20
+ "Programming Language :: Python :: 3.15",
20
21
  "Programming Language :: Python :: Implementation :: CPython",
21
22
  "License :: OSI Approved :: Apache Software License",
22
23
  "Environment :: Web Environment",
@@ -27,8 +28,8 @@ classifiers = [
27
28
  requires-python = ">= 3.11"
28
29
  dependencies = [
29
30
  "click>=8.5.0",
30
- "scim2-client[httpx2]>=0.13.2",
31
- "scim2-tester>=0.5.1",
31
+ "scim2-client[httpx2]>=0.14.0",
32
+ "scim2-tester>=0.6.4",
32
33
  "sphinx-click-rst-to-ansi-formatter>=0.2.0",
33
34
  "pydanclick>=0.5.0",
34
35
  "pygments>=2.18.0",
@@ -148,6 +149,7 @@ env_list = [
148
149
  "py312",
149
150
  "py313",
150
151
  "py314",
152
+ "py315",
151
153
  "minversions",
152
154
  "doc",
153
155
  "bundle",
@@ -0,0 +1,124 @@
1
+ import secrets
2
+ import sys
3
+ from collections import Counter
4
+
5
+ import click
6
+ from scim2_tester import Outcome
7
+ from scim2_tester import Status
8
+ from scim2_tester import iter_check_server
9
+ from sphinx_click.rst_to_ansi_formatter import make_rst_to_ansi_formatter
10
+
11
+ from .utils import DOC_URL
12
+ from .utils import Color
13
+ from .utils import escape_control_characters
14
+
15
+ OUTCOME_COLORS = {
16
+ Outcome.PASSED: Color.green,
17
+ Outcome.WARNING: Color.yellow,
18
+ Outcome.FAILED: Color.red,
19
+ Outcome.SKIPPED: Color.bright_black,
20
+ }
21
+ OUTCOME_LABELS = {
22
+ Outcome.PASSED: ("passed", "passed"),
23
+ Outcome.WARNING: ("warning", "warnings"),
24
+ Outcome.FAILED: ("failed", "failed"),
25
+ Outcome.SKIPPED: ("skipped", "skipped"),
26
+ }
27
+ STATUS_WIDTH = max(len(status.name) for status in Status)
28
+
29
+
30
+ def summary(outcomes: Counter[Outcome], seed: int) -> str:
31
+ """Count the results of each outcome, in the order of the outcomes."""
32
+ counts = []
33
+ for outcome in Outcome:
34
+ count = outcomes[outcome]
35
+ if not count:
36
+ continue
37
+ singular, plural = OUTCOME_LABELS[outcome]
38
+ counts.append(f"{count} {plural if count > 1 else singular}")
39
+ return f"{', '.join(counts) or 'no checks ran'} (seed {seed})"
40
+
41
+
42
+ @click.command(cls=make_rst_to_ansi_formatter(DOC_URL), name="test")
43
+ @click.pass_context
44
+ @click.option(
45
+ "-v",
46
+ "--verbose",
47
+ count=True,
48
+ help="Show every result with its reason. Pass it twice to also show the data.",
49
+ )
50
+ @click.option(
51
+ "--check-status-code/--dont-check-status-code",
52
+ is_flag=True,
53
+ default=True,
54
+ help="Fail on unexpected return codes.",
55
+ )
56
+ @click.option(
57
+ "--check-content-type/--dont-check-content-type",
58
+ is_flag=True,
59
+ default=True,
60
+ help="Fail on unexpected content types.",
61
+ )
62
+ @click.option(
63
+ "--strict",
64
+ is_flag=True,
65
+ help="Fail on deviations from the recommendations of the RFCs.",
66
+ )
67
+ @click.option(
68
+ "--seed",
69
+ type=int,
70
+ help="Send the same generated values as the run that printed this seed.",
71
+ )
72
+ def test_cli(
73
+ ctx: click.Context,
74
+ verbose: int,
75
+ check_status_code: bool,
76
+ check_content_type: bool,
77
+ strict: bool,
78
+ seed: int | None,
79
+ ) -> None:
80
+ """Perform a server SCIM compliance check using :doc:`scim2-tester <scim2_tester:index>`.
81
+
82
+ .. code-block:: bash
83
+
84
+ test
85
+ """
86
+ client = ctx.obj.client
87
+ client.check_response_status_codes = check_status_code
88
+ client.check_response_content_type = check_content_type
89
+ if seed is None:
90
+ seed = secrets.randbelow(2**32)
91
+ click.echo(f"Performing a SCIM compliance check on {client.client.base_url} ...")
92
+ results = iter_check_server(client, seed=seed)
93
+ failed = False
94
+ outcomes: Counter[Outcome] = Counter()
95
+ for result in results:
96
+ outcome = result.status.outcome
97
+ outcomes[outcome] += 1
98
+ if outcome is Outcome.FAILED or (strict and outcome is Outcome.WARNING):
99
+ failed = True
100
+ if not verbose and outcome in (Outcome.PASSED, Outcome.SKIPPED):
101
+ continue
102
+ status = click.style(
103
+ result.status.name.ljust(STATUS_WIDTH), fg=OUTCOME_COLORS[outcome]
104
+ )
105
+ label = " ".join(
106
+ escape_control_characters(part)
107
+ for part in (result.title, result.resource_type, result.attribute)
108
+ if part
109
+ )
110
+ click.echo(f"{status} {label}")
111
+
112
+ if result.reason:
113
+ click.echo(f" {escape_control_characters(result.reason)}")
114
+ if verbose > 1 and result.data:
115
+ click.echo(f" {escape_control_characters(result.data)}")
116
+
117
+ if failed:
118
+ color = Color.red
119
+ elif outcomes[Outcome.WARNING] or not outcomes:
120
+ color = Color.yellow
121
+ else:
122
+ color = Color.green
123
+ click.secho(summary(outcomes, seed), fg=color)
124
+ sys.exit(1 if failed else 0)
@@ -1,56 +0,0 @@
1
- import sys
2
-
3
- import click
4
- from scim2_tester import Status
5
- from scim2_tester import check_server
6
- from sphinx_click.rst_to_ansi_formatter import make_rst_to_ansi_formatter
7
-
8
- from .utils import DOC_URL
9
- from .utils import Color
10
- from .utils import escape_control_characters
11
-
12
-
13
- @click.command(cls=make_rst_to_ansi_formatter(DOC_URL), name="test")
14
- @click.pass_context
15
- @click.option("-v", "--verbose", is_flag=True, help="Enables verbose mode")
16
- @click.option(
17
- "--check-status-code/--dont-check-status-code",
18
- is_flag=True,
19
- default=True,
20
- help="Fail on unexpected return codes.",
21
- )
22
- @click.option(
23
- "--check-content-type/--dont-check-content-type",
24
- is_flag=True,
25
- default=True,
26
- help="Fail on unexpected content types.",
27
- )
28
- def test_cli(
29
- ctx: click.Context, verbose: bool, check_status_code: bool, check_content_type: bool
30
- ) -> None:
31
- """Perform a server SCIM compliance check using :doc:`scim2-tester <scim2_tester:index>`.
32
-
33
- .. code-block:: bash
34
-
35
- test
36
- """
37
- client = ctx.obj.client
38
- client.check_response_status_codes = check_status_code
39
- client.check_response_content_type = check_content_type
40
- results = check_server(client)
41
- click.echo(f"Performing a SCIM compliance check on {client.client.base_url} ...")
42
- success = True
43
- for result in results:
44
- if result.status == Status.SUCCESS:
45
- status = click.style(result.status.name, fg=Color.green)
46
- else:
47
- status = click.style(result.status.name, fg=Color.red)
48
- success = False
49
- click.echo(f"{status} {escape_control_characters(result.title)}")
50
-
51
- if result.reason:
52
- click.echo(f" {escape_control_characters(result.reason)}")
53
- if verbose and result.data:
54
- click.echo(f" {escape_control_characters(result.data)}")
55
-
56
- sys.exit(0 if success else 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