Aggregate plugin¶
dhis2w-core/plugins/aggregate/ wraps DHIS2's aggregate data-values endpoints: /api/dataValueSets (bulk) and /api/dataValues (single). It's the workhorse for reading and writing aggregated data — monthly counts, weekly indicators, period snapshots, etc.
What it exposes¶
| Operation | CLI | MCP tool |
|---|---|---|
| Fetch a data value set | dhis2 data aggregate get |
data_aggregate_get |
| Bulk push values | dhis2 data aggregate push <file> |
data_aggregate_push |
| Set a single value | dhis2 data aggregate set |
data_aggregate_set |
| Delete a single value | dhis2 data aggregate delete |
data_aggregate_delete |
CLI examples¶
# Fetch values for a dataset over a date range, limited to 50 rows
dhis2 data aggregate get \
--data-set eigJ6l6i7u9 \
--start-date 2024-01-01 \
--end-date 2024-01-31 \
--org-unit IWp9dQGM0bS \
--children \
--limit 50
# Bulk push from a JSON file (accepts either a dataValues array or an envelope)
echo '{"dataValues": [{"dataElement": "X", "orgUnit": "Y", "period": "202401", "value": "42"}]}' > values.json
dhis2 data aggregate push values.json --dry-run
# Set a single value
dhis2 data aggregate set --de X --pe 202401 --ou Y --value 42 --comment "corrected"
# Delete it
dhis2 data aggregate delete --de X --pe 202401 --ou Y
MCP examples¶
# Get
await mcp.call_tool("data_aggregate_get", {
"data_set": "eigJ6l6i7u9",
"start_date": "2024-01-01",
"end_date": "2024-01-31",
"org_unit": "IWp9dQGM0bS",
"children": True,
"limit": 50,
})
# Bulk push with dry-run
await mcp.call_tool("data_aggregate_push", {
"data_values": [
{"dataElement": "X", "orgUnit": "Y", "period": "202401", "value": "42"},
],
"dry_run": True,
})
# Single set
await mcp.call_tool("data_aggregate_set", {
"data_element": "X", "period": "202401", "org_unit": "Y", "value": "42",
})
Important parameters¶
periodvsstart_date+end_date— DHIS2 accepts either.periodis a single DHIS2 period (202401,2024W12,2024). Date range gives more flexibility across period types.org_unit+children=True—childrenincludes the unit's descendants. Without it you get only that specific unit.import_strategy— DHIS2 defaults toCREATE_AND_UPDATE. Override withCREATE,UPDATE, orDELETEfor bulk removal.dry_run— always validates; server returns an import-summary without writing. Use this to check a payload before a real push.
File shape for push¶
The CLI push command accepts either:
or an envelope:
{
"dataSet": "Z",
"dataValues": [
{"dataElement": "X", "orgUnit": "Y", "period": "202401", "value": "42"}
]
}
Envelope-level dataSet, period, orgUnit fields become POST-body fields and can be overridden by CLI flags if the caller prefers.
Errors and quirks¶
- 409 from
/api/dataValueSetson queries withoutorg_unit— DHIS2 requires at least one oforgUnit,orgUnitGroup, or a similar scope. The plugin doesn't enforce this — it's the caller's job to supply something scoped. - Single-value POST uses query params, not a JSON body — DHIS2's
/api/dataValuesacceptsde,pe,ou,valueas query params. Thedata_aggregate_setservice handles this transparently viaclient.post_raw(..., params=...). valueis always a string — even for numeric values. DHIS2 coerces server-side based on the data element'svalueType.
Not yet exposed¶
- Follow-up flags (
followup=trueon data values). - Attribute option combos via UIDs (params are threaded but not exposed in CLI for every command).
- Audit trail endpoints (
/api/dataValueSets/audit).
Add any of these to the plugin's service.py when the need arises; the CLI and MCP surfaces pick up new service functions by adding one decorator each.