Program rules¶
client.program_rules — read-side accessor over /api/programRules plus its companion endpoints for variable resolution + expression validation. Program rules drive conditional UI behaviour in DHIS2 Tracker Capture (hide / show fields, set values, assign warnings, validate input).
async with Dhis2Client(...) as client:
rules = await client.program_rules.list_for_program("Lt6P15ps7f6")
one = await client.program_rules.get(rule_uid)
# Resolve the variables a program rule expression can reference.
vars_ = await client.program_rules.list_variables_for_program("Lt6P15ps7f6")
# Parse-check an expression before saving.
description = await client.program_rules.validate_expression(
"#{age} > 1 && #{sex} == 'M'",
)
# Reverse-reference: which rules reference a given DataElement?
using = await client.program_rules.where_data_element_is_used("dataEl0001U")
CRUD on the rules themselves stays on the generic metadata surface (client.resources.program_rules). This accessor focuses on the read + analysis surface that downstream tooling (rule diffing, dependency analysis, expression validators) needs.
Worked example: examples/v42/client/program_rules.py.
program_rules
¶
Integration-grade helpers for DHIS2 ProgramRule workflows.
/api/programRules + /api/programRuleVariables + /api/programRuleActions
ship the tracker-side business-logic surface. Generic CRUD works via the
generated client.resources.program_rules accessor (and the other two).
This accessor layers the authoring + debugging helpers that generic
CRUD doesn't provide:
list_all(program_uid=None)— rules for a program (or every rule) sorted by priority + with actions resolved inline. One round-trip.get_rule(uid)— one rule with its actions.variables_for(program_uid)— every variable in scope for a program, with source-type + the referenced DE / TEA surfaced on a typed model.actions_for(rule_uid)— the actions that fire for one rule.validate_expression(expression)— parse-check via the shared/api/expressions/descriptionpath used by validation rules + predictors (reusesclient.validation.describe_expression).
Two DHIS2 quirks worked around under the hood (BUGS.md #22):
- POST bodies use
programRuleVariableSourceType(notsourceTypeper/api/schemas). The generated model withextra="allow"accepts either, but GETs only surface the wire name, so this accessor asks for it by name in fields selectors. fields=*silently omitsprogramRuleVariableSourceType. Every list/get call here names the field explicitly.
Classes¶
ProgramRulesAccessor
¶
Dhis2Client.program_rules — author + debug helpers over DHIS2 program rules.
Source code in packages/dhis2w-client/src/dhis2w_client/v42/program_rules.py
65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 | |
Functions¶
__init__(client)
¶
Bind to the sharing client — reuses its auth + HTTP pool for every request.
list_all(program_uid=None)
async
¶
List every ProgramRule (optionally scoped to one program) ordered by priority.
Fields selector pulls actions inline so callers get the full shape in one round-trip — tracker integrations typically want every rule's triggering conditions + effects at once. Paging off for small sets (DHIS2 rule catalogues rarely exceed a few hundred entries per program).
Source code in packages/dhis2w-client/src/dhis2w_client/v42/program_rules.py
get_rule(rule_uid)
async
¶
Fetch one ProgramRule with actions resolved inline.
Source code in packages/dhis2w-client/src/dhis2w_client/v42/program_rules.py
variables_for(program_uid)
async
¶
Every ProgramRuleVariable in scope for a program, sorted by name.
Expression authors typically need this first when debugging a rule —
"what values can my condition reference?" The typed model populates
programRuleVariableSourceType explicitly (see BUGS.md #22).
Source code in packages/dhis2w-client/src/dhis2w_client/v42/program_rules.py
actions_for(rule_uid)
async
¶
Every ProgramRuleAction attached to one rule.
Fetches the rule with programRuleActions[...] inline and returns
that collection. A direct filter on /api/programRuleActions would
be cleaner but DHIS2 strips the programRule back-reference from
action responses (same one-way-ownership pattern documented
alongside BUGS.md #22), so the rule-forward path is the only
reliable route.
Source code in packages/dhis2w-client/src/dhis2w_client/v42/program_rules.py
validate_expression(expression, *, context='program-indicator')
async
¶
Parse-check a program-rule condition via /api/.../expression/description.
DHIS2 exposes one validator per expression family (validation-rule /
indicator / predictor / program-indicator). Program-rule conditions
use the program-indicator grammar — same #{UID} / A{TEA} /
V{current_date} / d2:fn(...) shape. Delegates to
client.validation.describe_expression so every context routes
through the same plumbing.
Source code in packages/dhis2w-client/src/dhis2w_client/v42/program_rules.py
where_de_is_used(data_element_uid)
async
¶
Find every ProgramRule whose actions reference a specific DataElement.
Useful for impact analysis before editing a DE — "what rules break
if I rename / remove this?" DHIS2 strips the programRule
back-reference from /api/programRuleActions responses (one-way
ownership), so a direct filter like dataElement.id:eq:X can't
map back to owning rules. This walks every rule with actions inline
and filters client-side.