Skip to main content

dhis2w-browser

A dhis2w plugin pack for Playwright-driven DHIS2 UI automation: dashboard, map and visualization screenshots, a logged-in browser session from any profile, and Personal Access Token minting. It lives in its own repository so that installing dhis2w-client or dhis2w-cli never pulls in Chromium.

Documentation: https://winterop-com.github.io/dhis2w-browser/

Install

uv tool install 'dhis2w-cli[browser]'   # the d2w CLI with this pack
playwright install chromium             # one-off; the browser the flows drive

Library-only consumers (no CLI) can uv add dhis2w-browser on its own.

Surface

The CLI lives on the main d2w entry point as a plugin; there's no separate dhis2w-browser binary. Workflows mount under d2w browser <subcommand>:

d2w browser pat --url http://localhost:8080 --username admin --password district
d2w browser dashboard screenshot --output-dir /tmp/out --only <uid>
d2w browser viz screenshot --output-dir /tmp/out --only <uid>
d2w browser map screenshot --output-dir /tmp/out --only <uid>

Library callers import from dhis2w_browser directly:

Entry point Purpose
dhis2w_browser.logged_in_page(url, username, password) Async context manager yielding a (BrowserContext, Page) tuple logged into DHIS2 via the React login form.
dhis2w_browser.session_from_cookie(url, jsessionid) Fast-path variant — inject a pre-minted JSESSIONID instead of driving the login form.
dhis2w_browser.create_pat(url, username, password, options=...) Mint a Personal Access Token V2 (POST /api/apiToken) through an authenticated browser session. Returns the d2p_... token string. DHIS2 only returns the token value once — store it immediately.
dhis2w_browser.drive_oauth2_login(profile_name, *, username, password) Run d2w profile login <name> --no-browser end-to-end — spawns the CLI, reads the authorize URL from its stderr, and drives Chromium through the DHIS2 React login + Spring AS consent screen + loopback redirect. Returns an OAuth2LoginResult model.
dhis2w_browser.drive_login_form(auth_url, *, username, password) Lower-level companion to drive_oauth2_login — navigates Chromium to an already-built authorize URL, fills the login form + consent screen, waits for the loopback redirect. For wiring Playwright into an in-process OAuth2Auth.redirect_capturer.
dhis2w_browser.capture_dashboard(...) / capture_visualization(...) / capture_map(...) Render a DHIS2 dashboard / chart / map as a PNG via the respective web app. Banner + background-trim helpers available for report-friendly output.

Headless vs headful

Headless by default. Two ways to flip to visible:

  1. Env var: DHIS2_HEADFUL=1 (or true/yes/on) — applies to every Playwright entry point in this package.
  2. Explicit kwarg: logged_in_page(..., headless=False) — overrides env.

The d2w browser pat CLI command defaults to headful (--headful) so first-time users can watch the login; pass --headless to flip.

Why: automation wants headless for speed; humans debugging a flow want to see it. One env var covers every caller (CLI, library, tests) uniformly. See docs/decisions.md 2026-04-17.

Example

import asyncio
from dhis2w_browser import PatOptions, create_pat


async def main() -> None:
    token = await create_pat(
        "http://localhost:8080",
        "admin",
        "district",
        options=PatOptions(
            name="automation-bot",
            expires_in_days=90,
            allowed_methods=["GET", "POST"],
        ),
    )
    print(token)  # d2p_...


asyncio.run(main())

Architecture

See docs/architecture/browser.md for the longer write-up: why PAT creation has to go through a browser (DHIS2 gates /api/apiToken behind a session cookie), how logged_in_page drives the React login form, and what's on the roadmap.

Development

make install      # uv sync --all-groups
make lint         # ruff, mypy, pyright
make test         # the suite, without the live-stack Playwright tests
make test-slow    # the live-stack tests: a running DHIS2 and `playwright install chromium`
make docs         # the documentation site, strictly

The pack releases the same version as the dhis2w host; see CLAUDE.md.

Metadata

Release files for dhis2w-browser 1.32.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for dhis2w-browser 1.32.0
File Size Uploaded
dhis2w_browser-1.32.0.tar.gz 41.4 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for dhis2w-browser 1.32.0
File Interpreter ABI Platform
dhis2w_browser-1.32.0-py3-none-any.whl Python 3 none any Details

Total release size: 98.0 kB

Release files / dhis2w_browser-1.32.0.tar.gz

Download URL dhis2w_browser-1.32.0.tar.gz
Size 41.4 kB
Tags Source
SHA-256 checksum
How to use checksums
224c7d9011686f0894343880be9a654dda54523e686cc6f234d655c58f5883b2
BLAKE2b-256 checksum
How to use checksums
f0f11ed3b509f7e8a4d6644fa23e07de7ec8c131f2e84a6e53f5c776132f8693
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 6, 2026.

Transparency log

Release files / dhis2w_browser-1.32.0-py3-none-any.whl

Download URL dhis2w_browser-1.32.0-py3-none-any.whl
Size 56.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
10165753d0134b988360ace7c757fc0639b0a8f187c49c1c6c7801787a617828
BLAKE2b-256 checksum
How to use checksums
4fc374fddcad15e40ff3d71aacc1db9c2afa0665a6b1b95994dbc97310ac0129
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 6, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

1.32.0 This release

2 release files

1.30.1

2 release files

1.30.0

2 release files

1.29.0

2 release files

1.28.1

2 release files

1.28.0

2 release files

1.27.0

2 release files

1.26.0

2 release files

1.25.0

2 release files

1.24.2

2 release files

1.24.1

2 release files

1.24.0

2 release files

1.23.0

2 release files

1.22.0

2 release files

1.21.0

2 release files

1.20.0

2 release files

1.19.0

2 release files

1.18.0

2 release files

1.17.0

2 release files

1.16.0

2 release files

1.15.0

2 release files

1.14.0

2 release files

1.9.0

2 release files

1.8.3

2 release files

1.8.2

2 release files

1.8.1

2 release files

1.8.0

2 release files

1.7.0

2 release files

1.6.0

2 release files

1.5.0

2 release files

1.3.0

2 release files

1.2.0

2 release files

1.1.0

2 release files

1.0.0

2 release files

0.99.0

2 release files

0.23.0

2 release files

0.22.0

2 release files

0.21.0

2 release files

0.14.2

2 release files

0.14.1

2 release files

0.14.0

2 release files

0.13.1

2 release files

0.13.0

2 release files

0.12.0

2 release files

0.11.0

2 release files

0.10.0

2 release files

0.7.0

2 release files

0.6.0

2 release files

0.5.6

2 release files

0.5.5

2 release files

0.5.4

2 release files

0.5.3

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page