Examples index — canonical v42 set¶
Learning path · step 5 of 8 — Curated task index. Prev: Python tutorial. Next: API reference. The version-pinned
examples/v{41,42,43}/{cli,client,mcp}/trees are the source of truth for what's on disk; this page is the curated headline view.
The canonical example set lives under examples/v42/ and is what this page catalogues. v41 and v43 ship mirrors at examples/v41/ and examples/v43/ for the same example names — same surfaces, version-pinned imports. Version-specific examples (BUGS workarounds, schema divergences) live only under the version they target; see Schema diff: v41 -> v42 -> v43 for those.
Each entry below: file path → what it demonstrates → which concept doc explains it. This page is curated — it covers the headline examples per topic; not every single file under examples/v42/ shows up here. The full per-version listings live under examples/v{41,42,43}/{cli,client,mcp}/ and each surface tree has a top-level README pointing at the version-specific additions. ls examples/v42/{cli,client,mcp}/ is the source of truth for what's on disk.
Examples come in three flavours:
- CLI (
examples/v42/cli/*.sh) — bash invocations of thed2wTyper CLI. Run withbash examples/v42/cli/<name>.shwith the venv onPATH(viasource .venv/bin/activateoruv run -- bash ...). - Client (
examples/v42/client/*.py) — Python library usage. Run withuv run python examples/v42/client/<name>.py. - MCP (
examples/v42/mcp/*.py) — FastMCP tool calls through an in-process client. Run withuv run python examples/v42/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 — d2w system whoami + d2w system info |
system |
profile_list_verify.sh |
d2w 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 |
d2w 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 |
d2w metadata diff — bundle-vs-bundle or bundle-vs-live |
metadata plugin |
metadata_search.sh |
Cross-resource UID / code / name search via d2w metadata search <query> |
metadata plugin |
attribute_values.sh |
Cross-resource AttributeValue workflows via d2w metadata attributes |
metadata plugin |
options.sh |
OptionSet + Option workflows — d2w metadata option-sets get / find / sync |
metadata plugin |
legend_sets.sh |
d2w metadata legend-sets — create / get / clone / delete + the seeded LsDoseBand1 coverage dashboards |
legend sets API |
organisation_units.sh |
d2w metadata organisation-units + groups + group-sets + levels — tree walk, per-level rename, group + dimension round-trip |
organisation units API |
data_elements.sh |
d2w metadata data-elements + groups + group-sets — DE create, rename, legend-set attach, group + dimension round-trip |
data elements API |
indicators.sh |
d2w metadata indicators + groups + group-sets — numerator/denominator expression pre-flight, create, group + dimension round-trip |
indicators API |
program_indicators.sh |
d2w metadata program-indicators + groups — program-scoped expression validation + group membership (pair, no group-set) |
program indicators API |
category_options.sh |
d2w metadata category-options + groups + group-sets — validity-window creation + group + dimension round-trip |
category options API |
data_sets.sh |
d2w metadata data-sets + sections — DataSet create, DE attach (with per-set CC override), ordered Section round-trip |
data sets API |
validation_rules_predictors.sh |
d2w 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 |
d2w 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 |
d2w metadata programs — tracker + event Program authoring with PTEA enrollment form + OU scoping |
tracker schema API |
tracker_program_stages.sh |
d2w metadata program-stages — stage authoring with ordered PSDE list + reorder + per-DE compulsory flag |
tracker schema API |
messaging.sh |
d2w messaging send / get / reply / set-priority / assign / delete — ticket-workflow round-trip |
messaging plugin |
program_rules.sh |
d2w metadata program-rules — vars, validate-expression, where-de-is-used |
metadata plugin |
sql_views.sh |
d2w metadata list sqlViews / 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 |
d2w user — list / get / invite / reinvite / reset-password |
user plugin |
user_groups_and_roles.sh |
d2w user-group + d2w user-role admin workflows |
user groups + roles |
security.sh |
d2w security settings — read-only security posture (password policy, registration, lockout) |
CLI reference |
schema.sh |
d2w schema <type> — describe a generated type's fields (offline; reflects the active version tree) |
CLI reference |
route_register_and_run.sh |
d2w route lifecycle across every upstream auth type |
auth schemes |
customize_login.sh |
Brand the DHIS2 login page + top menu | customize plugin |
doctor.sh |
d2w doctor — probe every BUGS.md gotcha + metadata-health check |
doctor plugin |
maintenance.sh |
d2w maintenance — background tasks, cache, cleanup, integrity |
maintenance plugin |
files.sh |
d2w files — documents (URL + binary round-trip) + fileResource (MESSAGE_ATTACHMENT round-trip) |
files plugin |
validation_rules.sh |
d2w maintenance validation — expression validation, VR analysis, persisted results |
validation API |
predictors.sh |
d2w maintenance predictors run — run every predictor / one predictor / a predictor group |
validation API |
visualizations.sh |
d2w metadata visualizations + d2w metadata dashboards — flag-driven viz create, clone, dashboard compose |
visualizations guide |
visualization_screenshot.sh |
d2w browser viz screenshot — PNG capture via the Data Visualizer app (needs [browser] extra) |
visualizations guide |
maps.sh |
d2w metadata maps — thematic choropleth authoring via REST |
maps API |
map_screenshot.sh |
d2w browser map screenshot — PNG capture via the Maps app (needs [browser] extra) |
maps API |
apps.sh |
d2w apps list / hub-list / hub-url / update --dry-run / update --all / reload over /api/apps + /api/appHub |
apps API |
dev_codegen.sh |
d2w dev codegen — regenerate the typed client from a live instance |
codegen |
profile_pat.sh |
d2w profile pat create — provision a PAT as admin |
auth |
dev_sample.sh |
d2w 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 |
Cookbook — RetryPolicy for transient 5xx / connection errors on batch workflows |
client library tutorial |
task_await.py |
Cookbook — client.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 |
Cookbook — client.maintenance.iter_integrity_issues streams tagged issues, severity histogram, early-break scan |
maintenance plugin |
system_cache.py |
Cookbook — client.system cache: info() primed on connect, default_category_combo_uid(), per-key setting(), invalidate + refetch |
system API |
files_documents.py |
Cookbook — client.files documents + fileResource round-trip; external URL docs, binary two-step upload, MESSAGE_ATTACHMENT round-trip |
files plugin |
bulk_delete.py |
Cookbook — client.metadata.delete_bulk / delete_bulk_multi for one-call teardown via /api/metadata?importStrategy=DELETE |
metadata accessor |
metadata_patch_bulk.py |
Cookbook — client.metadata.patch_bulk fans out RFC 6902 patches across many UIDs with per-UID failure capture |
metadata accessor |
bulk_save_and_dry_run.py |
Cookbook — client.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 |
Cookbook — client.data_values.stream four ways: bytes, sync generator, Path (CSV), 1000-row file with timing |
data values streaming |
stream_analytics.py |
Cookbook — client.analytics.stream_to for JSON / CSV / rawData exports to disk with per-format timing |
analytics streaming |
messaging_with_attachment.py |
Cookbook — client.messaging.send + MESSAGE_ATTACHMENT fileResource pairing; full inbox lifecycle (list, reply, mark-read, delete) |
messaging plugin |
validation_rules.py |
Cookbook — client.validation workflow: expression validation, run analysis, list persisted results |
validation API |
predictors.py |
Cookbook — client.predictors.run_all over a date range with import-count envelope |
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 |
dashboard_item_users.py |
DashboardItem.user -> users (rename + reshape) |
schema diff v41 -> v42 -> v43 / versioning |
tracked_entity_attribute_favorites.py |
TrackedEntityAttribute.favorite -> favorites + 6 new search fields |
schema diff v41 -> v42 -> v43 |
program_set_labels.py |
v43-only — client.programs.set_labels overrides enrollmentsLabel / eventsLabel / programStagesLabel |
schema diff v41 -> v42 -> v43 |
program_set_change_log.py |
v43-only — toggle Program.enableChangeLog (server-side enrollment + event audit) |
schema diff v41 -> v42 -> v43 |
program_set_enrollment_category_combo.py |
v43-only — set the alt enrollmentCategoryCombo reference applied at enrollment time |
schema diff v41 -> v42 -> v43 |
event_visualization_fix_headers.py |
EventChart / EventReport / EventVisualization add fixColumnHeaders / fixRowHeaders / hideEmptyColumns |
schema diff v41 -> v42 -> v43 |
map_basemaps.py |
Map.basemaps v43-only addition + new Basemap model |
schema diff v41 -> v42 -> v43 |
section_user_removed.py |
Section.user removed in v43 (also Section.favorite) |
schema diff v41 -> v42 -> v43 |
removed_resources.py |
pushAnalysis / externalFileResource / dataInputPeriods removed in v43 |
schema diff v41 -> v42 -> v43 |
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 |
user_groups.py |
User groups + their sharing block via MCP (user_group_list, user_group_sharing_get) |
user groups + roles |
user_roles.py |
User roles + their authorities via MCP (user_role_list, user_role_authority_list) |
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 plugin group has representative examples. The 40-ish v42 MCP scripts can't cover all ~304 tools 1:1, but each plugin group (
metadata_*,analytics_*,data_*,apps_*, ...) gets at least one runnable example showing the expected input shape + how to unpack thestructured_contentreturn.
When adding a new plugin / command / MCP tool: update this file alongside the feature PR so the catalogue stays in sync.