Skip to content

Examples

The pack ships one document per operation, small enough to read in a sitting and to lift into a real pipeline unchanged. They live in src/dirigent_dhis2/shelves/, on five shelves:

Shelf What is on it
dhis2/ The native adapter: exports in every form and their import strategies, the sign-off gate, the analytics reads and rebuilds, the three tracker collections, the metadata reads, the data store, SQL views, validation rules, predictors, waiting on a job, a system report.
dhis2-compose/ A dhis2.* block beside one of the engine's own: a schema gate, a jq reshape, a fan-out over org units, a write to storage and the read back.
dhis2-http/ The generic-HTTP way, for what no adapter covers: a CSV export, a period range, a stage-scoped event read.
validate/ A metadata read held to a shape: a fields= projection gated on validate.schema, with the schema carried and named.
schemas/ The JSON Schemas that pin the reads the DHIS2 series makes, applied on their own.

Seven of these documents are also starters: whole flows worth beginning a project from, which dg pipeline new copies.

Reaching them once the pack is installed

The shelves ship inside the distribution and the pack contributes them through the examples() hook, so an instance with the pack installed has the catalogue without a checkout:

dg examples list --plugin dhis2
dg examples show dhis2-rehearse-import

Running one

No document carries a credential. Each names the connections it uses under requires.connections, and the instance holds them: the native and composed shelves name the dhis2 connection dhis2-play, and the generic-HTTP and validation shelves the http connection dhis2-play-http, both against the public play demo. Create them once; dg connection create asks how to sign in, and the demo takes the login it publishes on its own sign-in page:

dg connection create dhis2 dhis2-play --set base_url=https://play.dhis2.org/2.43 --set timeout=2m
dg connection create http dhis2-play-http --set base_url=https://play.dhis2.org/2.43 \
    --set follow_redirects_with_auth=true --set timeout=2m
dg run examples/dhis2/dhis2-export-data-values.yaml

https://play.dhis2.org/2.43 is the demo's alias, which follows it as it moves. The documents that write to the playground name a connection for it too, and their top-of-file comment gives the command that makes it. Create the same codes against your own DHIS2, or rename them in a copy, and the documents read yours.

A --local run has no instance to hold a connection, so it is handed them in a file with --connections FILE; the two documents that carry a schema, which a server refuses, run that way.

dg pipeline new copies a starter into a project:

dg pipeline new dhis2-rehearse-import
dg apply pipelines/dhis2-rehearse-import.yaml
dg run dhis2-rehearse-import -p period=202507 --watch

dg run takes the pipeline's code, which is the second column below. --watch streams step transitions and block output as the run goes.

Two things to know before a run comes back empty. The demo shifts its data era from release to release, and every document that reads data takes the period as a parameter for that reason: an empty answer is usually a period outside the era rather than a wrong read. And nothing in these examples writes to the demo -- every import is a dry_run, dhis2-alert-on-threshold sends a message only when it is given a threshold, and every write in the dhis2-http shelf is posted at the playground, the request-and-response service every dirigent instance serves itself under /api/v1/playground.

That last one is why six documents on that shelf want a running instance, which serves the playground and holds the connection that names it:

dg dev &
dg connection create http receiver --set base_url=http://127.0.0.1:3333/api/v1/playground
dg run examples/dhis2-http/dhis2-sync-org-units.yaml

The native adapter

examples/dhis2/. These use the dhis2.* blocks this pack contributes. An instance without the pack refuses them at the block preflight.

Data value sets

File Code The operation
dhis2-export-data-values.yaml dhis2-export-data-values Read one data set for one period at one organisation unit.
dhis2-export-with-children.yaml dhis2-export-with-children The same export widened to the org unit's descendants with children.
dhis2-export-csv.yaml dhis2-export-csv Export one data set as CSV, XML or ADX, written whole to storage and inlined as far as it fits.
dhis2-import-dry-run.yaml dhis2-import-dry-run Send a hand-written data value set with dry_run on and read the summary.
dhis2-import-create.yaml dhis2-import-create import_strategy: CREATE -- fill the gaps, revise nothing.
dhis2-import-update.yaml dhis2-import-update import_strategy: UPDATE -- revise what is there, invent nothing.
dhis2-import-create-and-update.yaml dhis2-import-create-and-update import_strategy: CREATE_AND_UPDATE -- the file is the truth.
dhis2-import-delete.yaml dhis2-import-delete import_strategy: DELETE -- remove the values a document names.
dhis2-import-partial.yaml dhis2-import-partial atomic_mode: NONE -- take the good values, report the rest as conflicts.
dhis2-rehearse-import.yaml dhis2-rehearse-import Export one month of a data set, then hand it straight back as a dry run.
dhis2-rehearse-csv-import.yaml dhis2-rehearse-csv-import The same round trip in CSV, the import reading the export's file from storage, data elements named by code.
dhis2-data-value.yaml dhis2-data-value Read one data value, then rehearse setting it with dhis2.data_value.

Completeness

File Code The operation
dhis2-wait-for-complete.yaml dhis2-wait-for-complete Wait until a data set is marked complete for a period and org unit.
dhis2-complete-then-export.yaml dhis2-complete-then-export The sign-off gate, with the export that reads the month behind it.
dhis2-mark-complete.yaml dhis2-mark-complete Sign a data set off for a period and org unit with dhis2.data_set_completion, as a dry run.

Analytics

File Code The operation
dhis2-analytics-query.yaml dhis2-analytics-query Run an aggregate analytics query for one indicator over the last twelve months.
dhis2-analytics-data-elements.yaml dhis2-analytics-data-elements Read two data elements broken down by the districts under one organisation unit.
dhis2-analytics-pivot.yaml dhis2-analytics-pivot The pivot shape: dimension for the axes shown, filter for the axis pinned.
dhis2-analytics-event-query.yaml dhis2-analytics-event-query mode: event -- a line list of events for one program.
dhis2-analytics-enrollment-query.yaml dhis2-analytics-enrollment-query mode: enrollment -- one row per enrollment, its stages folded in.
dhis2-native-analytics.yaml dhis2-native-analytics dhis2.analytics_run submits the job and streams its notifications into the log.
dhis2-analytics-resource-tables.yaml dhis2-analytics-resource-tables The same job with every data table skipped: the run to make after a metadata change.
dhis2-rebuild-then-query.yaml dhis2-rebuild-then-query Rebuild, then read -- the edge that makes the query wait for the job to finish.
dhis2-analytics.yaml dhis2-analytics The production-shaped nightly: sign-off gate, rebuild, export, with a nightly's deadlines and retries.
dhis2-resource-tables.yaml dhis2-resource-tables dhis2.resource_tables_run: the resource tables as their own job, followed to the end.

Data quality and jobs

File Code The operation
dhis2-validation-run.yaml dhis2-validation-run Run validation rule analysis over a facility for a year and read the violations.
dhis2-predictor-run.yaml dhis2-predictor-run Run the predictors of each named predictor group over a quarter; none is named by default, so nothing is written.
dhis2-task-wait.yaml dhis2-task-wait Follow one DHIS2 background job by its job type and id until it settles.

Tracker

File Code The operation
dhis2-tracker-events.yaml dhis2-tracker-events A page of events for one program and org-unit subtree.
dhis2-tracker-entities.yaml dhis2-tracker-entities The people enrolled in a program, read with ou_mode: DESCENDANTS.
dhis2-tracker-enrollments.yaml dhis2-tracker-enrollments The open enrollments in a program, by status and updated_after.
dhis2-tracker-paged.yaml dhis2-tracker-paged One page of a large collection, with page and page_size as parameters.
dhis2-tracker-events-filtered.yaml dhis2-tracker-events-filtered Status, change window and a data element filter, at once.
dhis2-tracker-import-dry-run.yaml dhis2-tracker-import-dry-run Validate one event against the tracker importer, followed as a job.

Metadata

File Code The operation
dhis2-metadata-data-elements.yaml dhis2-metadata-data-elements The dataElements collection through the version-bound accessor.
dhis2-metadata-data-elements-filtered.yaml dhis2-metadata-data-elements-filtered The same read narrowed by filter and projected by fields.
dhis2-metadata-org-units.yaml dhis2-metadata-org-units Read the org units directly beneath one unit, with their hierarchy paths.
dhis2-metadata-data-set.yaml dhis2-metadata-data-set Read one data set's period type, data elements, and their disaggregations.
dhis2-metadata-paged.yaml dhis2-metadata-paged Read one page of organisation units and how many there are in total.
dhis2-metadata-create-data-element.yaml dhis2-metadata-create-data-element Create one data element with dhis2.metadata_import, validated only.
dhis2-metadata-round-trip.yaml dhis2-metadata-round-trip Export a few data elements and validate them straight back as an update.
dhis2-sql-view.yaml dhis2-sql-view Run the demo's data-element-by-value-type SQL view with a variable, every row keyed by column.
dhis2-data-store.yaml dhis2-data-store List a data store namespace's keys, then read the first one.
dhis2-system-report.yaml dhis2-system-report System info, a two-collection dhis2.metadata_export and an org unit count, rendered as the run's report:.

Composed with the engine's own blocks

examples/dhis2-compose/. A dhis2.* step is rarely the whole pipeline: a DHIS2 read usually ends up checked, reshaped, repeated once per organisation unit, or left behind as a file.

A file is always a composition. A value moves through step outputs, and storage has two doors: storage.write puts a value out at a URI and storage.read brings one back in. No dhis2.* block opens either, so an export that ends in a file is two steps and a month moved between instances is four.

File Code What it composes
dhis2-alert-on-threshold.yaml dhis2-alert-on-threshold An analytics query read by transform.jq into at most one alert, and a dhis2.message fanned out over it, so a user group is messaged only when a district falls below the threshold. It sends nothing until it is given a threshold.
dhis2-export-validated.yaml dhis2-export-validated An export gated on validate.schema, ids and periods held to dhis2-uid and dhis2-period.
dhis2-export-reshaped.yaml dhis2-export-reshaped An export reshaped with transform.jq: the envelope's defaults pushed down, values made numeric, cells grouped per data element.
dhis2-export-per-org-unit.yaml dhis2-export-per-org-unit One export per organisation unit with for_each, items: continue so one district's failure costs only that district; a second fanned storage.write writes one file per district, and a manifest lists what landed.
dhis2-export-to-storage.yaml dhis2-export-to-storage An export left behind as a file: storage.write takes the export's body and reports the URI it landed at.
dhis2-import-from-storage.yaml dhis2-import-from-storage A month moved through a file: export, storage.write, storage.read, import -- both of storage's doors in one document.
dhis2-metadata-snapshot-to-storage.yaml dhis2-metadata-snapshot-to-storage A metadata collection read with a fields projection and kept as a file, the read a schedule repeats to diff metadata drift.

dhis2-export-validated.yaml gates on a schema the instance holds rather than one it carries, so the instance is given it first:

dg schema create examples/schemas/dhis2-data-value-set.json
dg run examples/dhis2-compose/dhis2-export-validated.yaml

The generic-HTTP way

examples/dhis2-http/. These talk to DHIS2 with dirigent's ordinary http.request and http.ready -- no adapter, nothing to install. It is the pattern for reaching a system that has no adapter, or a DHIS2 call this pack does not yet cover.

File Code What it demonstrates
dhis2-system-info.yaml dhis2-system-info Authentication and a minimal API call.
dhis2-org-unit-levels.yaml dhis2-org-unit-levels The configured hierarchy levels.
dhis2-org-units.yaml dhis2-org-units Save a snapshot of every DHIS2 organisation unit to storage.
dhis2-org-unit-detail.yaml dhis2-org-unit-detail Read one organisation unit, its hierarchy path, and its immediate children.
dhis2-forward-org-units.yaml dhis2-forward-org-units Select, reshape with transform.jq, and send an organisation-unit batch to the playground.
dhis2-run-analytics.yaml dhis2-run-analytics Start an analytics-table update and poll the asynchronous task with http.ready -- what dhis2.analytics_run does for you.
dhis2-sync-org-units.yaml dhis2-sync-org-units An organisation-unit sync: count before fetching, bound the read, ask for fields, order by path.
dhis2-export-data-elements.yaml dhis2-export-data-elements A metadata export with fields=:owner, and the import vocabulary: importStrategy, atomicMode, importMode=VALIDATE.
dhis2-fhir-to-data-values.yaml dhis2-fhir-to-data-values A FHIR QuestionnaireResponse translated into a /api/dataValueSets import, link id by link id.
dhis2-export-data-values-csv.yaml dhis2-export-data-values-csv A data value set as CSV rather than JSON -- the extension is the content negotiation -- written out with storage.write.
dhis2-export-data-values-range.yaml dhis2-export-data-values-range Every period inside a startDate/endDate window in one call, instead of a period at a time.
dhis2-data-values-validated.yaml dhis2-data-values-validated A data value set gated on a carried schema, every id held to dhis2-uid and every period to dhis2-period.
dhis2-mark-data-set-complete.yaml dhis2-mark-data-set-complete Reading a completion registration, and the POST that signs a period off.
dhis2-mark-data-set-incomplete.yaml dhis2-mark-data-set-incomplete Both ways of reopening a signed-off period: completed: false, and the outright DELETE.
dhis2-events-by-stage.yaml dhis2-events-by-stage Events of a single program stage in an occurrence window, and the orgUnitMode/ouMode split.

The six that write -- forward, sync, the metadata export, the FHIR translation and both completeness documents -- post to the playground, so each wants a dg dev running. dhis2-fhir-to-data-values.yaml wants nothing else: its capture is inline, so it reaches no DHIS2 at all.

dhis2-export-data-elements.yaml marks the sharpest trap in the DHIS2 API: a dry run is importMode=VALIDATE on /api/metadata and dryRun=true on /api/dataValueSets, and reaching for the wrong spelling does not fail -- it imports.

A read held to a shape

examples/validate/. Each asks DHIS2 for a fields= projection with http.request and gates the answer with validate.schema before anything downstream reads it. A mismatch is rejected, so the same value against the same schema is never retried.

File Code What it demonstrates
org-units-shape.yaml org-units-shape fields=id,displayName,level on organisation units, validated as an array of typed records against the dhis2-org-units instance schema.
data-elements-carried.yaml data-elements-carried fields=id,name,valueType,domainType on data elements, with the shape carried in the document's own schemas: section.
data-elements-named.yaml data-elements-named The same check against the dhis2-data-elements schema the instance holds.
numbers-only.yaml numbers-only A filter narrows the read to NUMBER-valued elements; the schema sharpens, proving none of another type slipped through.
system-info-shape.yaml system-info-shape /api/system/info validated as a top-level object -- a schema needs no list to gate on.

A carried schema is for a --local run, handed its connection with --connections FILE; a server refuses a document that carries one. A named schema is declared under requires.schemas, so an instance that does not hold it refuses the document until dg schema create gives it the file.

Schemas

examples/schemas/. Each file is a plain JSON Schema (Draft 2020-12): the shape a read is expected to return, written down once so a pipeline can be refused the moment a payload moves out from under it. A schema is locally authored, never fetched from the source, which is why these are applied on their own rather than from inside a pipeline document:

dg schema create examples/schemas/dhis2-org-units.json

A schema carries its own identity in its keywords: $id becomes the code it is addressed by, title its name, and description its body.

File Code The shape it pins
dhis2-org-units.json dhis2-org-units An object with an organisationUnits array of UID/name/level items.
dhis2-data-elements.json dhis2-data-elements A dataElements array whose valueType and domainType are held to the DHIS2 enums.
dhis2-system-info.json dhis2-system-info A top-level object, not a list: an instance version and a serverDate.
dhis2-number-data-elements.json dhis2-number-data-elements A dataElements array whose every valueType is NUMBER.
dhis2-data-elements-v42.json dhis2-data-elements-v42 The v42-pinned dataElements shape: the 2.42 valueType enum and closed rows, so a 2.43 bump is caught.
dhis2-data-value-set.json dhis2-data-value-set The /api/dataValueSets envelope, every id held to dhis2-uid and every period to dhis2-period.

Starters

A starter is a document worth beginning a project from: a flow rather than one call, with the comments that say what each hop is for. They are not a shelf of their own -- each one sits with the documents it belongs beside, tagged starter. The menu is dg examples list --plugin dhis2 --starter.

Each names the dhis2-play connection under requires.connections, so it runs as it stands on an instance that holds one, and so does its copy:

dg connection create dhis2 dhis2-play --set base_url=https://play.dhis2.org/2.43 --set timeout=2m
dg pipeline new dhis2-rehearse-import

The copy is the document verbatim apart from two lines: the code: and the dropped starter tag. The comments come with it, and each ends with a TO MAKE IT YOURS paragraph naming the edits a real instance needs -- the uids are the play demo's.

Code Shelf What it starts you with
dhis2-rehearse-import dhis2/ The round trip: read a data value set and hand it to an import, rehearsed with dry_run.
dhis2-complete-then-export dhis2/ A sensor gate: hold until a month is marked complete, then read it.
dhis2-rebuild-then-query dhis2/ The analytics ordering: rebuild the tables, then read an indicator out of them.
dhis2-export-validated dhis2-compose/ An export held to a named schema, so a changed payload stops at the step it arrived in.
dhis2-export-reshaped dhis2-compose/ An export reshaped with transform.jq into the shape the next system reads.
dhis2-import-from-storage dhis2-compose/ A month moved through a file: export, write, read back, import.
dhis2-metadata-snapshot-to-storage dhis2-compose/ A metadata collection read with a fields projection and written to storage.