Tracker reads¶
Typed instance models returned by /api/tracker/* reads: TrackerTrackedEntity, TrackerEnrollment, TrackerEvent, TrackerRelationship + nested value types + EventStatus / EnrollmentStatus StrEnums.
Tracker models are version-scoped because /api/tracker/* shapes drift across DHIS2 majors. Import from the version your client is pinned to: from dhis2w_client.generated.v42.tracker import TrackerBundle, TrackerEvent, .... The matching write path lives on client.tracker (register / enroll / add_event / outstanding) — see the tracker plugin architecture.
When to reach for it¶
- Reading instance data from
/api/tracker/trackedEntities,/api/tracker/enrollments,/api/tracker/eventswith typed results. - Parsing a raw tracker bundle response (e.g. from a file fixture or a webhook) into typed models before processing.
- Branching on
EventStatus/EnrollmentStatusexhaustively viamatch.
Worked example — typed reads via get_raw + model_validate¶
from dhis2w_client.generated.v42.tracker import TrackerEvent
from dhis2w_core.client_context import open_client
from dhis2w_core.profile import profile_from_env
async with open_client(profile_from_env()) as client:
# Tracker reads land via raw paths today; the typed models above are
# the parse target. The accessor surface (`client.tracker.*`) covers
# writes; reads are still raw-path-based.
raw = await client.get_raw(
"/api/tracker/events",
params={
"program": "IpHINAT79UW",
"orgUnit": "ImspTQPwCqd",
"ouMode": "DESCENDANTS",
"pageSize": "10",
},
)
for row in raw.get("events") or []:
event = TrackerEvent.model_validate(row)
print(f"{event.event} status={event.status} ou={event.orgUnit}")
Worked example — register a tracked entity, enroll, add events¶
The write side lives on client.tracker. register returns a typed RegisterResult carrying the freshly-generated UIDs + the underlying WebMessageResponse; add_event returns an EventResult with the new event UID + its response envelope:
async with open_client(profile_from_env()) as client:
# 1. Register a new tracked entity + enroll in one call.
result = await client.tracker.register(
program="IpHINAT79UW",
org_unit="DiszpKrYNg8",
tracked_entity_type="nEenWmSyUEp",
attributes={"w75KJ2mc4zz": "Jane", "zDhUuAYrxNC": "Doe"},
)
print(
f"TE={result.tracked_entity} enrollment={result.enrollment} "
f"status={result.response.status}"
)
# 2. Add an event to the new enrollment.
event = await client.tracker.add_event(
program="IpHINAT79UW",
program_stage="A03MvHHogjR",
enrollment=result.enrollment,
org_unit="DiszpKrYNg8",
data_values={"a3kGcGDCuk6": "BCG"},
)
print(f"event={event.event} status={event.response.status}")
Worked example — outstanding follow-up¶
async with open_client(profile_from_env()) as client:
# ACTIVE enrollments missing events on a non-repeatable stage —
# the "what's due" report. `program` is positional; `org_unit`
# narrows the OU subtree (DESCENDANTS by default).
rows = await client.tracker.outstanding("IpHINAT79UW", org_unit="ImspTQPwCqd")
for row in rows:
print(
f" enrollment={row.enrollment} TE={row.tracked_entity} "
f"missing={row.missing_stages}"
)
Related examples¶
examples/v42/client/tracker_lifecycle.py— full register + enroll + add event lifecycle.examples/v42/client/tracker_clinic_intake.py— canonical tracker-program intake viaclient.tracker.register / add_event / outstanding.examples/v42/client/tracker_event_program.py— WITHOUT_REGISTRATION event-only flow.
tracker
¶
Typed models for DHIS2 v42 tracker instance data.
Thin shim over the OpenAPI-derived models under generated/v42/oas/. Re-exports
the wire-shape classes (TrackerTrackedEntity, TrackerEnrollment,
TrackerEvent, TrackerRelationship, TrackerRelationshipItem,
TrackerDataValue, TrackerAttribute, TrackerNote) plus the status enums
(EnrollmentStatus, EventStatus), and defines the client-side TrackerBundle
wrapper used for POST /api/tracker (not in OpenAPI — it's the wire envelope
DHIS2 accepts for bulk writes).
Tracker shapes drift across DHIS2 majors; keeping this under
dhis2w_client.generated.v42 means a v43 bump can ship its own
generated/v43/oas/ + tracker.py without touching v42 callers.
Classes¶
EnrollmentStatus
¶
EventStatus
¶
Bases: StrEnum
EventStatus.
Source code in packages/dhis2w-client/src/dhis2w_client/generated/v42/oas/_enums.py
TrackerAttribute
¶
Bases: BaseModel
OpenAPI schema TrackerAttribute.
Source code in packages/dhis2w-client/src/dhis2w_client/generated/v42/oas/tracker_attribute.py
TrackerDataValue
¶
Bases: BaseModel
OpenAPI schema TrackerDataValue.
Source code in packages/dhis2w-client/src/dhis2w_client/generated/v42/oas/tracker_data_value.py
TrackerEnrollment
¶
Bases: BaseModel
OpenAPI schema TrackerEnrollment.
Source code in packages/dhis2w-client/src/dhis2w_client/generated/v42/oas/tracker_enrollment.py
TrackerEvent
¶
Bases: BaseModel
OpenAPI schema TrackerEvent.
Source code in packages/dhis2w-client/src/dhis2w_client/generated/v42/oas/tracker_event.py
TrackerNote
¶
Bases: BaseModel
OpenAPI schema TrackerNote.
Source code in packages/dhis2w-client/src/dhis2w_client/generated/v42/oas/tracker_note.py
TrackerRelationship
¶
Bases: BaseModel
OpenAPI schema TrackerRelationship.
Source code in packages/dhis2w-client/src/dhis2w_client/generated/v42/oas/tracker_relationship.py
TrackerRelationshipItem
¶
Bases: BaseModel
OpenAPI schema TrackerRelationshipItem.
Source code in packages/dhis2w-client/src/dhis2w_client/generated/v42/oas/tracker_relationship_item.py
TrackerTrackedEntity
¶
Bases: BaseModel
OpenAPI schema TrackerTrackedEntity.
Source code in packages/dhis2w-client/src/dhis2w_client/generated/v42/oas/tracker_tracked_entity.py
TrackerBundle
¶
Bases: BaseModel
Typed payload for POST /api/tracker — any mix of tracker objects in one atomic write.
DHIS2 accepts nested construction (a tracked entity carrying its own
enrollments[] which carry their own events[]) or flat construction
(all four arrays populated independently). Callers pick whichever fits
their data shape; DHIS2 collapses both forms server-side.
Produce the wire payload with
bundle.model_dump(by_alias=True, exclude_none=True, mode="json").
Bundle fields are typed lists of the OpenAPI-derived tracker models, so
enum fields like EventStatus.COMPLETED validate at construction time.
Not in the OpenAPI spec — POST /api/tracker is documented but the
request body shape is described only in prose. This class is a
hand-written mirror of that shape.