Aggregate data values¶
DataValue and DataValueSet — the typed wire shapes for DHIS2's aggregate-data path (/api/dataValueSets GET / POST and the per-value /api/dataValues endpoint). Pairs with Data values (streaming), which exposes the same shape via client.data_values.stream(...) for very large imports.
When to reach for it¶
- Pushing a small or medium batch of aggregate values from a script (CSV-to-DHIS2 sync, ETL pipeline, integration test fixture).
- Reading values back to verify a write landed or to drive an analytics-side check.
- Building the typed payload the streaming accessor and the bulk-grouped helper both consume.
Worked example — typed write, then read-back¶
from dhis2w_client import DataValue, DataValueSet
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:
# Push two values. `import_grouped_by_dataset` is the cross-version
# write path (required on v43 BUGS #35, accepted on v41 + v42). The
# typed `DataValue`s are validated by pydantic before they hit the wire.
values = [
DataValue(
dataElement="fbfJHSPpUQD",
period="202604",
orgUnit="ImspTQPwCqd",
categoryOptionCombo="HllvX50cXC0",
attributeOptionCombo="HllvX50cXC0",
value="42",
),
DataValue(
dataElement="fbfJHSPpUQD",
period="202605",
orgUnit="ImspTQPwCqd",
categoryOptionCombo="HllvX50cXC0",
attributeOptionCombo="HllvX50cXC0",
value="43",
),
]
# `import_grouped_by_dataset` POSTs one envelope per DataSet group
# (required on v43 BUGS #35). Returns a list — one WebMessageResponse
# per POST. Aggregate the per-envelope counts to get a total.
envelopes = await client.data_values.import_grouped_by_dataset(values)
total_imported = sum((env.import_count().imported if env.import_count() else 0) for env in envelopes)
print(f"posted {len(envelopes)} group(s) total imported={total_imported}")
for env in envelopes:
print(f" status={env.status} message={env.message!r}")
# Read back. `/api/dataValueSets` returns the typed DataValueSet shape;
# validate the raw dict through the pydantic model.
raw = await client.get_raw(
"/api/dataValueSets",
params={"dataSet": "lyLU2wR22tC", "period": "202604", "orgUnit": "ImspTQPwCqd"},
)
dvs = DataValueSet.model_validate(raw)
for v in dvs.dataValues or []:
print(f" DE={v.dataElement} pe={v.period} ou={v.orgUnit} value={v.value}")
When to use which write path¶
import_grouped_by_dataset(values) is the safe cross-version default. It pre-fetches each DataElement's DataSet membership and POSTs one {"dataSet": …, "dataValues": [...]} envelope per group — required on DHIS2 v43 for any DE that belongs to multiple DataSets (BUGS #35: v43 rejects mixed batches with 409 E8002). v41 + v42 accept the same envelope shape, so the call is portable.
client.data_values.stream(values, ...) is the streaming alternative for very large imports — wraps the values as an async-byte stream so httpx doesn't have to materialise the full payload in memory.
Related examples¶
examples/v42/client/push_data_value.py— minimal single-value push.examples/v42/client/stream_data_values.py— streaming reads, four shapes (bytes, sync generator, Path/CSV, 1000-row file with timing).examples/v42/client/aggregate_bulk_grouped.py— the grouped bulk path.
aggregate
¶
Typed models for DHIS2 aggregate data values (shim over generated/v42/oas).
Covers the /api/dataValueSets GET response (a DataValueSet envelope
containing a list of DataValues). The corresponding POST/import path
returns a WebMessageResponse (see dhis2w_client/envelopes.py).
Distinct from the generated DataElement / DataSet / CategoryOptionCombo
metadata models (those come out of /api/schemas codegen) — these describe
the runtime values captured against that metadata. OpenAPI ships both
shapes under components/schemas/{DataValue,DataValueSet}.
Classes¶
DataValue
¶
Bases: BaseModel
OpenAPI schema DataValue.
Source code in packages/dhis2w-client/src/dhis2w_client/generated/v42/oas/data_value.py
DataValueSet
¶
Bases: BaseModel
OpenAPI schema DataValueSet.