Weekly data
Read twelve weeks of disease counts per district from DHIS2 analytics, with the periods in DHIS2's own calendar.
This page follows Setup in the Outbreak alerts series. Facilities report their counts, and the analytics API returns them added up to any level of the organisation unit hierarchy. One request gives the counts of every disease in every district for the week just ended and the eleven weeks before it, which is what the thresholds on the next page are computed from.
The request
The analytics API takes one dimension parameter per dimension of the result - dx for the data elements, pe for the periods and ou for the organisation units:
# -*- coding: utf-8 -*-
# Zato
from zato.server.service import Service
class CheckWeek(Service):
name = 'dhis2.alerts.check-week'
def read_analytics(self) -> 'dict':
alerts = self.config.alerts
# One data element per disease ..
data_elements = []
for disease in alerts.diseases.values():
data_elements.append(disease.data_element)
# .. twelve weeks ending with the one just ended, and every district.
dx = ';'.join(data_elements)
level = alerts.analytics.district_level
dimensions = [f'dx:{dx}', 'pe:LAST_12_WEEKS', f'ou:LEVEL-{level}']
params = {'dimension': dimensions}
conn = self.rest['DHIS2 Analytics']
response = conn.get(params=params)
out = response.data
return out
A list in params becomes a query parameter repeated once per item. LAST_12_WEEKS is a relative period, which DHIS2 resolves on its own side, and LEVEL-2 selects every organisation unit on the second level of the hierarchy.
The counts
Each row of the response is a data element, a week, a district and a count, in that order. A week in which a district reported no cases of a disease has no row, so each series starts at zero for every week and the rows fill it in:
def read_series(self) -> 'tuple[list, dict]':
analytics = self.read_analytics()
# The weeks in calendar order, the last one being the week just ended ..
metadata = analytics['metaData']
dimensions = metadata['dimensions']
weeks = dimensions['pe']
week_count = len(weeks)
series = {}
# .. and each row is a count of one disease in one district and one week.
for data_element, week, district, value in analytics['rows']:
# Every week of a district and disease starts at zero ..
key = (data_element, district)
if key not in series:
series[key] = [0.0] * week_count
# .. and the count goes into its week.
counts = series[key]
index = weeks.index(week)
counts[index] = float(value)
out = weeks, series
return out
metaData.dimensions.pe lists the weeks in calendar order. The rows come in no particular order, which is why each count is placed by the position of its week in that list.
Periods
DHIS2 identifies each period by a string, and every value a service reads or writes carries one:
| Period | Identifier | Example |
|---|---|---|
| ISO week | yyyyWn | 2026W40 |
| Week starting on Wednesday | yyyyWedWn | 2026WedW40 |
| Month | yyyyMM | 202609 |
| Day | yyyyMMdd | 20261005 |
The week number has no leading zero, so 2026W9 comes before 2026W10 although it sorts after it as a string. A data set whose weeks start on a day other than Monday uses the matching weekly period type, such as WedW for Wednesday, and takes values only for periods of that type.
A DHIS2 instance can also run on a calendar other than the Gregorian one, such as the Ethiopian or the Nepali calendar. Its period identifiers are then in that calendar, and a week or month computed in Python from a Gregorian date names a different period.
Relative periods such as LAST_12_WEEKS, LAST_WEEK or LAST_MONTH are resolved by DHIS2 in its own calendar. The identifiers it returns in metaData are the ones to use in anything written back, which is why the services in this series do not compute any period themselves.
The schedule
The service runs from a scheduler job once a week, after the reporting deadline of the week and after DHIS2 has updated its analytics tables:

Next
Thresholds checks each series against the rule of its disease.
See also
| Feature | What it does |
|---|---|
| Setup | The DHIS2 Analytics connection and alerts.ini |
| Calling REST APIs | Query parameters, payloads and response objects |
| Scheduler | Interval-based jobs |