dhis2w-cli 1.28.1__tar.gz → 1.30.0__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.4
2
2
  Name: dhis2w-cli
3
- Version: 1.28.1
3
+ Version: 1.30.0
4
4
  Summary: d2w command-line interface (Typer) — mounts plugins from dhis2w-core.
5
5
  Author: Morten Hansen
6
6
  Author-email: Morten Hansen <morten@winterop.com>
@@ -11,19 +11,20 @@ Classifier: Intended Audience :: Developers
11
11
  Classifier: Programming Language :: Python :: 3
12
12
  Classifier: Programming Language :: Python :: 3.13
13
13
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
14
- Requires-Dist: dhis2w-core>=1.28.1,<2.0
14
+ Requires-Dist: dhis2w-core>=1.30.0,<2.0
15
15
  Requires-Dist: typer>=0.27.1
16
16
  Requires-Dist: rich>=15
17
- Requires-Dist: dhis2w-fhir>=1.28.1,<2.0
18
- Requires-Dist: dhis2w-browser>=1.28.1,<2.0 ; extra == 'browser'
19
- Requires-Dist: dhis2w-security>=1.19.0,<2.0 ; extra == 'security'
20
- Requires-Dist: dhis2w-fhir-serve>=1.28.1,<2.0 ; extra == 'serve'
17
+ Requires-Dist: dhis2w-browser>=1.29.0,<2.0 ; extra == 'browser'
18
+ Requires-Dist: dhis2w-fhir>=1.29.0,<2.0 ; extra == 'fhir'
19
+ Requires-Dist: dhis2w-security>=1.29.0,<2.0 ; extra == 'security'
20
+ Requires-Dist: dhis2w-fhir-serve>=1.29.0,<2.0 ; extra == 'serve'
21
21
  Requires-Python: >=3.13
22
22
  Project-URL: Homepage, https://github.com/winterop-com/dhis2w
23
23
  Project-URL: Documentation, https://winterop-com.github.io/dhis2w/
24
24
  Project-URL: Repository, https://github.com/winterop-com/dhis2w
25
25
  Project-URL: Changelog, https://github.com/winterop-com/dhis2w/blob/main/CHANGELOG.md
26
26
  Provides-Extra: browser
27
+ Provides-Extra: fhir
27
28
  Provides-Extra: security
28
29
  Provides-Extra: serve
29
30
  Description-Content-Type: text/markdown
@@ -45,10 +46,18 @@ uv tool install 'dhis2w-cli[security]'
45
46
  uv tool install 'dhis2w-cli[browser]'
46
47
  playwright install chromium # one-time, after the install above
47
48
 
49
+ # With FHIR Implementation Guide tooling (the dhis2w-fhir pack mounts `d2w fhir`);
50
+ # add `serve` for the capture facade behind `d2w fhir serve`
51
+ uv tool install 'dhis2w-cli[fhir]'
52
+ uv tool install 'dhis2w-cli[fhir,serve]'
53
+
48
54
  # Update later
49
55
  uv tool upgrade dhis2w-cli
50
56
  ```
51
57
 
58
+ Extras combine (`'dhis2w-cli[fhir,security]'`). A pack's command without the pack installed -
59
+ `d2w fhir`, `d2w browser`, `d2w security` - prints the install command that adds it.
60
+
52
61
  Or run on demand without installing:
53
62
 
54
63
  ```bash
@@ -80,7 +89,7 @@ d2w browser Playwright UI automation (only with [browser] extra).
80
89
  d2w data DHIS2 data values (aggregate + tracker).
81
90
  d2w dev Developer/operator tools.
82
91
  d2w doctor Probe a DHIS2 instance for known gotchas + requirements.
83
- d2w fhir FHIR IG generation (SUSHI/FSH) from DHIS2 metadata.
92
+ d2w fhir FHIR IG generation, serving and capture (only with [fhir] extra).
84
93
  d2w files Manage DHIS2 documents + file resources.
85
94
  d2w maintenance DHIS2 maintenance (tasks, cache, integrity, cleanup, refresh).
86
95
  d2w messaging DHIS2 internal messaging.
@@ -99,4 +108,4 @@ d2w user-role DHIS2 user-role administration.
99
108
 
100
109
  Full CLI reference: https://winterop-com.github.io/dhis2w/cli-reference/.
101
110
 
102
- `dhis2w-cli` is one member of the [`dhis2w`](https://github.com/winterop-com/dhis2w) workspace. The MCP server (`dhis2w-mcp`) exposes the same plugin surface as MCP tools.
111
+ `dhis2w-cli` is one member of the [`dhis2w`](https://github.com/winterop-com/dhis2w) workspace. The MCP server ([`dhis2w-mcp`](https://github.com/winterop-com/dhis2w-mcp), a plugin pack in its own repository) exposes the same plugin surface as MCP tools.
@@ -15,10 +15,18 @@ uv tool install 'dhis2w-cli[security]'
15
15
  uv tool install 'dhis2w-cli[browser]'
16
16
  playwright install chromium # one-time, after the install above
17
17
 
18
+ # With FHIR Implementation Guide tooling (the dhis2w-fhir pack mounts `d2w fhir`);
19
+ # add `serve` for the capture facade behind `d2w fhir serve`
20
+ uv tool install 'dhis2w-cli[fhir]'
21
+ uv tool install 'dhis2w-cli[fhir,serve]'
22
+
18
23
  # Update later
19
24
  uv tool upgrade dhis2w-cli
20
25
  ```
21
26
 
27
+ Extras combine (`'dhis2w-cli[fhir,security]'`). A pack's command without the pack installed -
28
+ `d2w fhir`, `d2w browser`, `d2w security` - prints the install command that adds it.
29
+
22
30
  Or run on demand without installing:
23
31
 
24
32
  ```bash
@@ -50,7 +58,7 @@ d2w browser Playwright UI automation (only with [browser] extra).
50
58
  d2w data DHIS2 data values (aggregate + tracker).
51
59
  d2w dev Developer/operator tools.
52
60
  d2w doctor Probe a DHIS2 instance for known gotchas + requirements.
53
- d2w fhir FHIR IG generation (SUSHI/FSH) from DHIS2 metadata.
61
+ d2w fhir FHIR IG generation, serving and capture (only with [fhir] extra).
54
62
  d2w files Manage DHIS2 documents + file resources.
55
63
  d2w maintenance DHIS2 maintenance (tasks, cache, integrity, cleanup, refresh).
56
64
  d2w messaging DHIS2 internal messaging.
@@ -69,4 +77,4 @@ d2w user-role DHIS2 user-role administration.
69
77
 
70
78
  Full CLI reference: https://winterop-com.github.io/dhis2w/cli-reference/.
71
79
 
72
- `dhis2w-cli` is one member of the [`dhis2w`](https://github.com/winterop-com/dhis2w) workspace. The MCP server (`dhis2w-mcp`) exposes the same plugin surface as MCP tools.
80
+ `dhis2w-cli` is one member of the [`dhis2w`](https://github.com/winterop-com/dhis2w) workspace. The MCP server ([`dhis2w-mcp`](https://github.com/winterop-com/dhis2w-mcp), a plugin pack in its own repository) exposes the same plugin surface as MCP tools.
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "dhis2w-cli"
3
- version = "1.28.1"
3
+ version = "1.30.0"
4
4
  description = "d2w command-line interface (Typer) — mounts plugins from dhis2w-core."
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.13"
@@ -14,10 +14,9 @@ classifiers = [
14
14
  "Topic :: Software Development :: Libraries :: Python Modules",
15
15
  ]
16
16
  dependencies = [
17
- "dhis2w-core>=1.28.1,<2.0",
17
+ "dhis2w-core>=1.30.0,<2.0",
18
18
  "typer>=0.27.1",
19
19
  "rich>=15",
20
- "dhis2w-fhir>=1.28.1,<2.0",
21
20
  ]
22
21
 
23
22
  [[project.authors]]
@@ -25,9 +24,10 @@ name = "Morten Hansen"
25
24
  email = "morten@winterop.com"
26
25
 
27
26
  [project.optional-dependencies]
28
- browser = ["dhis2w-browser>=1.28.1,<2.0"]
29
- serve = ["dhis2w-fhir-serve>=1.28.1,<2.0"]
30
- security = ["dhis2w-security>=1.19.0,<2.0"]
27
+ browser = ["dhis2w-browser>=1.29.0,<2.0"]
28
+ serve = ["dhis2w-fhir-serve>=1.29.0,<2.0"]
29
+ security = ["dhis2w-security>=1.29.0,<2.0"]
30
+ fhir = ["dhis2w-fhir>=1.29.0,<2.0"]
31
31
 
32
32
  [project.scripts]
33
33
  d2w = "dhis2w_cli.main:main"
@@ -41,9 +41,3 @@ Changelog = "https://github.com/winterop-com/dhis2w/blob/main/CHANGELOG.md"
41
41
  [build-system]
42
42
  requires = ["uv_build>=0.12.12,<0.13.0"]
43
43
  build-backend = "uv_build"
44
-
45
- [tool.uv.sources.dhis2w-fhir]
46
- workspace = true
47
-
48
- [tool.uv.sources.dhis2w-fhir-serve]
49
- workspace = true
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "dhis2w-cli"
3
- version = "1.28.1"
3
+ version = "1.30.0"
4
4
  description = "d2w command-line interface (Typer) — mounts plugins from dhis2w-core."
5
5
  readme = "README.md"
6
6
  authors = [{ name = "Morten Hansen", email = "morten@winterop.com" }]
@@ -15,19 +15,23 @@ classifiers = [
15
15
  "Topic :: Software Development :: Libraries :: Python Modules",
16
16
  ]
17
17
  dependencies = [
18
- "dhis2w-core>=1.28.1,<2.0",
18
+ "dhis2w-core>=1.30.0,<2.0",
19
19
  "typer>=0.27.1",
20
20
  "rich>=15",
21
- "dhis2w-fhir>=1.28.1,<2.0",
22
21
  ]
23
22
 
24
23
  [project.optional-dependencies]
25
- browser = ["dhis2w-browser>=1.28.1,<2.0"]
24
+ browser = [
25
+ "dhis2w-browser>=1.29.0,<2.0",
26
+ ]
26
27
  serve = [
27
- "dhis2w-fhir-serve>=1.28.1,<2.0",
28
+ "dhis2w-fhir-serve>=1.29.0,<2.0",
28
29
  ]
29
30
  security = [
30
- "dhis2w-security>=1.19.0,<2.0",
31
+ "dhis2w-security>=1.29.0,<2.0",
32
+ ]
33
+ fhir = [
34
+ "dhis2w-fhir>=1.29.0,<2.0",
31
35
  ]
32
36
 
33
37
  [project.scripts]
@@ -42,7 +46,3 @@ Changelog = "https://github.com/winterop-com/dhis2w/blob/main/CHANGELOG.md"
42
46
  [build-system]
43
47
  requires = ["uv_build>=0.12.12,<0.13.0"]
44
48
  build-backend = "uv_build"
45
-
46
- [tool.uv.sources]
47
- dhis2w-fhir = { workspace = true }
48
- dhis2w-fhir-serve = { workspace = true }
@@ -15,6 +15,8 @@ from dhis2w_core.plugin import DEFAULT_VERSION_KEY, load_plugin_host, resolve_st
15
15
  from dhis2w_core.rich_console import STDERR_CONSOLE
16
16
  from rich.logging import RichHandler
17
17
 
18
+ from dhis2w_cli.packs import mount_install_hints
19
+
18
20
 
19
21
  def _extract_profile_from_argv(argv: list[str]) -> str | None:
20
22
  """Pre-scan argv for the profile Click will apply: the last root `--profile` / `-p` value.
@@ -196,7 +198,9 @@ def build_app() -> typer.Typer:
196
198
  # invocation must not leak into the next one.
197
199
  JSON_OUTPUT.set(json_)
198
200
 
199
- load_plugin_host(resolve_startup_version()).mount_cli(app)
201
+ host = load_plugin_host(resolve_startup_version())
202
+ host.mount_cli(app)
203
+ mount_install_hints(app, host.names)
200
204
  return app
201
205
 
202
206
 
@@ -0,0 +1,74 @@
1
+ """The optional plugin packs `d2w` knows by name, and the hint it prints when one is not installed."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from collections.abc import Callable
6
+
7
+ import typer
8
+ from pydantic import BaseModel, ConfigDict
9
+
10
+
11
+ class OptionalPack(BaseModel):
12
+ """A plugin pack that mounts a `d2w` command group when installed, and the extra that installs it."""
13
+
14
+ model_config = ConfigDict(frozen=True)
15
+
16
+ command: str
17
+ distribution: str
18
+ extra: str
19
+ summary: str
20
+
21
+
22
+ OPTIONAL_PACKS: tuple[OptionalPack, ...] = (
23
+ OptionalPack(
24
+ command="fhir",
25
+ distribution="dhis2w-fhir",
26
+ extra="fhir",
27
+ summary="FHIR Implementation Guides from DHIS2 metadata, and the capture server",
28
+ ),
29
+ OptionalPack(
30
+ command="browser",
31
+ distribution="dhis2w-browser",
32
+ extra="browser",
33
+ summary="Playwright-driven DHIS2 UI automation",
34
+ ),
35
+ OptionalPack(
36
+ command="security",
37
+ distribution="dhis2w-security",
38
+ extra="security",
39
+ summary="a security audit of a DHIS2 instance",
40
+ ),
41
+ )
42
+
43
+
44
+ def install_hint(pack: OptionalPack) -> str:
45
+ """The message `d2w <command>` prints when the pack providing it is not installed."""
46
+ return (
47
+ f"`d2w {pack.command}` is not installed. It comes with the {pack.distribution} pack "
48
+ f"({pack.summary}):\n\n"
49
+ f' uv tool install "dhis2w-cli[{pack.extra}]"\n\n'
50
+ f"or, in a project: uv add {pack.distribution}"
51
+ )
52
+
53
+
54
+ def _hint_command(pack: OptionalPack) -> Callable[[typer.Context], None]:
55
+ """The command body standing in for `d2w <command>`: print the install hint and exit 1."""
56
+
57
+ def _hint(context: typer.Context) -> None:
58
+ typer.echo(install_hint(pack), err=True)
59
+ raise typer.Exit(1)
60
+
61
+ return _hint
62
+
63
+
64
+ def mount_install_hints(app: typer.Typer, mounted: tuple[str, ...]) -> None:
65
+ """Mount a hidden `d2w <command>` for every known pack that is not installed, printing how to install it."""
66
+ for pack in OPTIONAL_PACKS:
67
+ if pack.command in mounted:
68
+ continue
69
+ app.command(
70
+ pack.command,
71
+ hidden=True,
72
+ add_help_option=False,
73
+ context_settings={"allow_extra_args": True, "ignore_unknown_options": True},
74
+ )(_hint_command(pack))
File without changes