Skip to content

Examples index

Every example in examples/ catalogued in one place. Each entry: file path → what it demonstrates → which concept doc explains it.

Examples come in three flavours:

  • CLI (examples/cli/*.sh) — bash invocations of the dhis2 Typer CLI. Run with bash examples/cli/<name>.sh with the venv on PATH (via source .venv/bin/activate or uv run -- bash ...).
  • Client (examples/client/*.py) — Python library usage. Run with uv run python examples/client/<name>.py.
  • MCP (examples/mcp/*.py) — FastMCP tool calls through an in-process client. Run with uv run python examples/mcp/<name>.py.

Every example reads the active DHIS2 profile from .dhis2/profiles.toml / ~/.config/dhis2/profiles.toml / DHIS2_PROFILE env (see profiles). Assume a seeded local stack (make dhis2-run) unless stated otherwise.

CLI examples

Example What it demonstrates Related docs
metadata_round_trip.sh Cookbook — export → jq transform → diff → dry-run → import → live verify → revert CLI tutorial / metadata plugin
whoami.sh Simplest invocation — dhis2 system whoami + dhis2 system info system
profile_list_verify.sh dhis2 profile list / verify / show profiles
profile_oidc_config.sh Populate an OAuth2 profile by discovering DHIS2's OIDC endpoints auth
profile_oidc_login.sh Full OIDC login flow — profile add → login → verify → whoami auth
metadata_list_get.sh dhis2 metadata list / get + client-side UID generation metadata plugin
metadata_patch.sh RFC 6902 JSON Patch — inline --set / --remove and file-based metadata plugin
metadata_export_import.sh Cross-instance bundle round-trip (export → import) metadata plugin
metadata_export_filter.sh Per-resource filters + dangling-reference warning on export metadata plugin
metadata_diff.sh dhis2 metadata diff — bundle-vs-bundle or bundle-vs-live metadata plugin
metadata_search.sh Cross-resource UID / code / name search via dhis2 metadata search <query> metadata plugin
attribute_values.sh Cross-resource AttributeValue workflows via dhis2 metadata attribute metadata plugin
options.sh OptionSet + Option workflows — dhis2 metadata options get / find / sync metadata plugin
legend_sets.sh dhis2 metadata legend-sets — create / get / clone / delete + the seeded LsDoseBand1 coverage dashboards legend sets API
organisation_units.sh dhis2 metadata organisation-units + groups + group-sets + levels — tree walk, per-level rename, group + dimension round-trip organisation units API
data_elements.sh dhis2 metadata data-elements + groups + group-sets — DE create, rename, legend-set attach, group + dimension round-trip data elements API
indicators.sh dhis2 metadata indicators + groups + group-sets — numerator/denominator expression pre-flight, create, group + dimension round-trip indicators API
program_indicators.sh dhis2 metadata program-indicators + groups — program-scoped expression validation + group membership (pair, no group-set) program indicators API
category_options.sh dhis2 metadata category-options + groups + group-sets — validity-window creation + group + dimension round-trip category options API
data_sets.sh dhis2 metadata data-sets + sections — DataSet create, DE attach (with per-set CC override), ordered Section round-trip data sets API
validation_rules_predictors.sh dhis2 metadata validation-rules + predictors + their groups — CRUD round-trip for the authoring flip side of maintenance validation run / maintenance predictors run validation rules + predictors API
tracker_schema.sh dhis2 metadata tracked-entity-attributes + tracked-entity-types — create a unique-generated TEA + a Person TET and wire them together tracker schema API
tracker_programs.sh dhis2 metadata programs — tracker + event Program authoring with PTEA enrollment form + OU scoping tracker schema API
tracker_program_stages.sh dhis2 metadata program-stages — stage authoring with ordered PSDE list + reorder + per-DE compulsory flag tracker schema API
messaging.sh dhis2 messaging send / get / reply / set-priority / assign / delete — ticket-workflow round-trip messaging plugin
program_rules.sh dhis2 metadata program-rule — vars, validate-expression, where-de-is-used metadata plugin
sql_views.sh dhis2 metadata sql-view list / get / execute / refresh / adhoc across the VIEW / QUERY / MATERIALIZED_VIEW shapes SQL views API
aggregate_data_values.sh Aggregate data values — read / write a single value / bulk file push aggregate
tracker_reads.sh Tracked entities by type, enrollments, events, bulk import tracker
tracker_register_and_followup.sh Canonical tracker-program clinic intake — register, log an event, query outstanding enrollments tracker
tracker_event_program.sh Event-only WITHOUT_REGISTRATION program — standalone events with no enrollment tracker
analytics_query.sh Aggregated analytics queries + resource-table refresh analytics
analytics_outlier_tracked_entities.sh Outlier detection + tracked-entity analytics analytics
user_administration.sh dhis2 user — list / get / invite / reinvite / reset-password user plugin
user_groups_and_roles.sh dhis2 user-group + dhis2 user-role admin workflows user groups + roles
route_register_and_run.sh dhis2 route lifecycle across every upstream auth type auth schemes
customize_login.sh Brand the DHIS2 login page + top menu customize plugin
doctor.sh dhis2 doctor — probe every BUGS.md gotcha + metadata-health check doctor plugin
maintenance.sh dhis2 maintenance — background tasks, cache, cleanup, integrity maintenance plugin
files.sh dhis2 files — documents (URL + binary round-trip) + fileResource (MESSAGE_ATTACHMENT round-trip) files plugin
validation_and_predictors.sh dhis2 maintenance validation + dhis2 maintenance predictors — expression validation, VR analysis, persisted results, predictor runs validation API
visualizations.sh dhis2 metadata viz + dhis2 metadata dashboard — flag-driven viz create, clone, dashboard compose visualizations guide
visualization_screenshot.sh dhis2 browser viz screenshot — PNG capture via the Data Visualizer app (needs [browser] extra) visualizations guide
maps.sh dhis2 metadata map — thematic choropleth authoring via REST maps API
map_screenshot.sh dhis2 browser map screenshot — PNG capture via the Maps app (needs [browser] extra) maps API
apps.sh dhis2 apps list / hub-list / hub-url / update --dry-run / update --all / reload over /api/apps + /api/appHub apps API
dev_codegen.sh dhis2 dev codegen — regenerate the typed client from a live instance codegen
dev_pat.sh dhis2 dev pat create — provision a PAT as admin auth
dev_sample.sh dhis2 dev sample ... — inject fixtures + verify end-to-end manual testing

Client examples (Python library)

Example What it demonstrates Related docs
bulk_patch_from_csv.py Cookbook — apply a CSV of patches concurrently via asyncio.gather + JsonPatchOpAdapter metadata plugin
profile_drift_check.py Cookbook — diff metadata between two profiles, exit non-zero on drift (CI template) metadata plugin
retry_policy.py CookbookRetryPolicy for transient 5xx / connection errors on batch workflows client library tutorial
task_await.py Cookbookclient.tasks.await_completion blocks on analytics refresh / metadata import / etc. client library tutorial
concurrent_bulk.py Cookbook — fan-out patterns (naive gather → bounded semaphore → tuned pool + retries) with live timings client architecture
integrity_issues_stream.py Cookbookclient.maintenance.iter_integrity_issues streams tagged issues, severity histogram, early-break scan maintenance plugin
system_cache.py Cookbookclient.system cache: info() primed on connect, default_category_combo_uid(), per-key setting(), invalidate + refetch system API
files_documents.py Cookbookclient.files documents + fileResource round-trip; external URL docs, binary two-step upload, MESSAGE_ATTACHMENT round-trip files plugin
bulk_delete.py Cookbookclient.metadata.delete_bulk / delete_bulk_multi for one-call teardown via /api/metadata?importStrategy=DELETE metadata accessor
metadata_patch_bulk.py Cookbookclient.metadata.patch_bulk fans out RFC 6902 patches across many UIDs with per-UID failure capture metadata accessor
bulk_save_and_dry_run.py Cookbookclient.resources.<res>.save_bulk(items) for typed bulk create/update + client.metadata.dry_run(...) as the pre-commit safety gate metadata accessor
stream_data_values.py Cookbookclient.data_values.stream four ways: bytes, sync generator, Path (CSV), 1000-row file with timing data values streaming
stream_analytics.py Cookbookclient.analytics.stream_to for JSON / CSV / rawData exports to disk with per-format timing analytics streaming
messaging_with_attachment.py Cookbookclient.messaging.send + MESSAGE_ATTACHMENT fileResource pairing; full inbox lifecycle (list, reply, mark-read, delete) messaging plugin
validation_and_predictors.py Cookbookclient.validation + client.predictors workflow: expression validation, run analysis, list persisted results, run predictors validation API
whoami.py Minimal — default profile → call /api/me client library tutorial
library_only_auth.py Library-only auth for PyPI consumers without dhis2w-core auth
profile_resolver.py Use a DHIS2 profile from Python via dhis2w-core.open_client profiles
profile_crud.py Profile CRUD — in-memory Profile(...) + on-disk add/rename/set-default/remove through the profile-plugin service profiles
oidc_login.py OAuth 2.1 authorization-code + PKCE flow; auto-dispatches to Playwright when DHIS2_USERNAME+DHIS2_PASSWORD are set auth
oidc_playwright_login.py Fully automated end-to-end OIDC via drive_oauth2_login — CLI subprocess + Chromium IdP form + consent screen auth / browser
list_data_elements.py Generated typed resource accessors metadata CRUD
enum_round_trip.py Generated StrEnums — type-safe access to DHIS2 CONSTANT values typed schemas
metadata_filter_order_paging.py Full query DSL — filters, rootJunction, order, server-side paging metadata plugin
metadata_patch.py RFC 6902 JSON Patch — generated accessor + service + adapter paths metadata plugin
metadata_export_import.py Export + import round-trip via the service layer metadata plugin
metadata_diff.py service.diff_bundles + diff_bundle_against_instance metadata plugin
metadata_bulk_import.py Typed dry-run + real bulk import metadata plugin
metadata_search.py Cross-resource UID / code / name search via client.metadata.search metadata plugin
metadata_usage.py Reverse-reference lookup "what points at this UID?" via client.metadata.usage metadata plugin
attribute_values.py AttributeValuesAccessor across every resource with an attributeValues field metadata plugin
options_integration.py Every method on OptionSetsAccessor — list / get / find / sync metadata plugin
legend_sets.py client.legend_sets.create_from_spec + VisualizationSpec(legend_set=...) — colour bands attached to a throw-away viz legend sets API
organisation_units.py client.organisation_units + groups + group-sets + levels — descendants walk, rename-by-level, membership + dimension round-trip organisation units API
data_elements.py client.data_elements + groups + group-sets — keyword-arg create, rename, per-item membership, dimension data elements API
indicators.py client.indicators.validate_expression pre-flight + numerator/denominator create + group + dimension round-trip indicators API
program_indicators.py client.program_indicators + groups — program-scoped expression validation + EVENT/ENROLLMENT create + group round-trip (pair, no group-set) program indicators API
category_options.py client.category_options validity-window helper + groups + group-sets round-trip category options API
data_sets.py client.data_sets + client.sections — DataSet create, DE attach, ordered Section round-trip data sets API
validation_rules_predictors.py client.validation_rules + client.predictors (plus their groups) — CRUD round-trip + group membership validation rules + predictors API
tracker_schema.py client.tracked_entity_attributes + client.tracked_entity_types — TEA + TET round-trip with the TETA linkage helpers tracker schema API
tracker_programs.py client.programs — tracker Program with PTEA + OU linkage, using the TET + TEA from step 1 tracker schema API
program_rules.py Every method on ProgramRulesAccessor — get, vars, validate, where-DE-used metadata plugin
sql_views.py SqlViewsAccessor list / get / execute / refresh / adhoc across the three view shapes SQL views API
sql_view_runner.py Three ways to use SqlViewRunner — by UID, ad-hoc query, named bindings SQL views API
indicator_crud.py Create a typed Indicator with a formula, use it, clean up metadata CRUD
data_set_crud.py Full CRUD lifecycle for a data set metadata CRUD
org_unit_crud.py Full CRUD lifecycle for an organisation unit metadata CRUD
geojson_org_units.py Pull org units as GeoJSON (validated via geojson-pydantic) metadata CRUD
push_data_value.py Write one aggregate data value against the seeded dataset aggregate
tracker_lifecycle.py Create a tracked entity with an enrollment + event tracker
tracker_clinic_intake.py Canonical tracker-program intake via client.tracker.register / add_event / outstanding tracker
tracker_event_program.py WITHOUT_REGISTRATION event-only program — one-shot events via add_event without an enrollment tracker
analytics_query.py Aggregated analytics + resource-table refresh analytics
analytics_events_enrollments.py Event + enrollment analytics queries analytics
analytics_outlier_tracked_entities.py Outlier detection + tracked-entity analytics analytics
task_polling.py Watch an analytics-refresh job to completion maintenance plugin
doctor.py Programmatic probe results for CI / monitoring doctor plugin
user_administration.py User administration via the Python client user plugin
user_groups_and_roles.py User groups + user roles via the Python client user groups + roles
sharing.py Typed sharing helpers — read + replace on any object sharing
customize_login.py Brand a DHIS2 instance programmatically customize plugin
error_handling.py Dhis2ApiError, WebMessage conflicts, AuthenticationError errors
bootstrap_zero_to_data.py End-to-end — zero org unit to a data value in one script client library tutorial
viz_create_basic.py Simplest visualization spec → create → verify axes visualizations guide
viz_multiline_by_province.py Multi-line time-series with analytics-probe sanity check visualizations guide
viz_pivot_and_kpi.py PIVOT_TABLE + SINGLE_VALUE default placements side-by-side visualizations guide
viz_clone_and_modify.py Clone an existing chart, verify independence visualizations guide
dashboard_compose.py Assemble a dashboard from scratch with typed DashboardSlots visualizations guide
map_create_choropleth.py Build a thematic choropleth from a typed MapSpec + MapLayerSpec maps API
apps.py client.apps.list_apps / hub_list / get_hub_url — library surface for the apps plugin apps API

MCP examples

Example What it demonstrates Related docs
whoami.py whoami + system_info MCP tools in-process MCP
profile_tools.py Read-only profile MCP tools profiles
metadata.py Browse metadata via MCP metadata plugin
metadata_patch.py RFC 6902 JSON Patch via the metadata_patch tool metadata plugin
metadata_diff.py metadata_diff tool against two bundles metadata plugin
metadata_export_import.py Bundle round-trip via MCP tools metadata plugin
metadata_search.py metadata_search — cross-resource UID / code / name lookup for agents metadata plugin
metadata_usage.py metadata_usage — "what references this UID?" reverse lookup for agents metadata plugin
legend_sets.py metadata_legend_set_* — list / create / get / delete via MCP legend sets API
organisation_units.py metadata_organisation_unit_* — tree walk + levels + group + group-set via MCP organisation units API
data_elements.py metadata_data_element_* — DE + group + group-set round-trip via MCP data elements API
indicators.py metadata_indicator_* — expression validation + create + group + group-set via MCP indicators API
program_indicators.py metadata_program_indicator_* — program-scoped expression + group round-trip via MCP program indicators API
category_options.py metadata_category_option_* — validity window + group + group-set via MCP category options API
data_sets.py metadata_data_set_* + metadata_section_* — DataSet + Section round-trip via MCP data sets API
validation_rules_predictors.py metadata_validation_rule_* + metadata_predictor_* (plus groups) — CRUD round-trip via MCP validation rules + predictors API
tracker_schema.py metadata_tracked_entity_attribute_* + metadata_tracked_entity_type_* — TEA + TET round-trip via MCP tracker schema API
tracker_programs.py metadata_program_* — tracker + event Program authoring via MCP tracker schema API
aggregate_data_values.py GET / SET / DELETE data values via MCP aggregate
tracker_reads.py Discover TET types, list entities/events via MCP tracker
tracker_workflow.py Agent flow — tracker_register, tracker_add_event, tracker_outstanding for a tracker program tracker
analytics_query.py Aggregated analytics + refresh via MCP analytics
analytics_events_enrollments.py Event + enrollment analytics via MCP analytics
analytics_outlier_tracked_entities.py Outlier detection + tracked-entity analytics via MCP analytics
maintenance.py Tasks, cache, cleanup, data-integrity via MCP maintenance plugin
route_register_and_run.py Route CRUD + run via MCP auth schemes
doctor.py Structured probe results for an agent via doctor_run doctor plugin
user_administration.py User plugin MCP tools user plugin
sharing_and_user_groups.py Sharing + user-group admin via MCP user groups + roles
customize_login.py Branding via MCP customize plugin
apps.py apps_list, apps_hub_list (plus apps_install_*, apps_uninstall, apps_update{,_all}, apps_hub_url_{get,set} available) apps API

External plugin example

examples/plugin-external/ — a minimal runnable external plugin (own pyproject.toml, entry-point registration, CLI + MCP hooks). See external plugins for the contract.

How example coverage maps to features

  • Every top-level CLI domain has at least one example. See CLI reference for the full command tree.
  • Every plugin with a service layer has both a CLI and client example. Pairs are intentional — the CLI shows the user-facing path, the client shows what library callers do.
  • Every MCP tool has at least one example call showing the expected input shape + how to unpack the structured_content return.

When adding a new plugin / command / MCP tool: update this file alongside the feature PR so the catalogue stays in sync.