Sharing helpers¶
Typed helpers over /api/sharing. Use them to read and replace the sharing block of any DHIS2 object without hand-writing JSON Patch.
Access strings¶
DHIS2 packs four capabilities into an 8-char string:
| Positions | Meaning |
|---|---|
| 0–1 | metadata read / write — rw, r-, -- |
| 2–3 | data read / write (only meaningful on dataValue-carrying objects) |
| 4–7 | reserved; always ---- |
from dhis2w_client import access_string, ACCESS_READ_METADATA, ACCESS_READ_WRITE_DATA
access_string() # '--------'
access_string(metadata="rw") # 'rw------'
access_string(metadata="r-", data="r-") # 'r-r-----'
ACCESS_READ_METADATA # 'r-------'
ACCESS_READ_WRITE_DATA # 'rwrw----'
The four constants cover >95% of callsites; access_string() handles the rest without concatenation at the use site.
Get / apply¶
from dhis2w_client import Dhis2Client, SharingBuilder, apply_sharing, get_sharing
async with Dhis2Client(url, auth) as client:
current = await get_sharing(client, "dataSet", ds_uid)
# current is a `SharingObject` (publicAccess, externalAccess, user, userAccesses[], userGroupAccesses[]).
sharing = (
SharingBuilder(owner_user_id=admin_uid)
.grant_user(admin_uid, "rwrw----")
.grant_user_group(group_uid, "r-------")
)
envelope = await apply_sharing(client, "dataSet", ds_uid, sharing)
assert envelope.status == "OK"
apply_sharing accepts either a SharingBuilder or a raw SharingObject (use the builder for ergonomics, drop down to the object when you already have one from get_sharing).
Resource types¶
resource_type is DHIS2's singular metadata name as it appears in filter strings and in the sharing API's ?type= param. Common values:
dataSet,dataElement,categoryCombo,categoryOptionprogram,programStage,trackedEntityTypeuser,userGroup,userRoledashboard,visualization,map,report,eventChart,eventReport
DHIS2 returns 400 on unknown types — if you get that, check the resource's schema at /api/schemas/{type} (the sharing endpoint uses the same names).
Why this exists¶
Before this helper, callers typically reached for JSON Patch against /api/<resource>/<uid>:
# Old pattern — works but verbose, error-prone, untyped.
await client.patch_raw(
f"/api/dataSets/{uid}",
[{"op": "add", "path": "/sharing/users", "value": {admin_uid: {"id": admin_uid, "access": "rwrw----"}}}],
)
The typed helper replaces that with one line, and get_sharing + builder composition makes additive edits (preserve everything, append one grant) straightforward. See examples/client/bootstrap_zero_to_data.py step 5 for the before/after.
sharing
¶
Typed helpers for DHIS2's sharing API.
DHIS2 models access to every persistable object as a sharing block: a
public-access string, an owning user, and two lists of per-user / per-user-group
grants. The wire shape has two flavours:
SharingObject— what/api/sharing?type=<t>&id=<uid>returns insideSharingInfo.object. CarriespublicAccess,userAccesses,userGroupAccesses.Sharing— what metadata resources carry on theirsharingfield. Same information butuserAccesses[]becomes a keyed mapusers: {uid: {...}}(same for groups), matching how DHIS2 stores it internally.
This module ships three utilities:
access_string(metadata="rw", data="rw")— compose the 8-char access string DHIS2 uses ("rwrw----","r-------", etc.). Constants for the common forms.get_sharing(client, resource_type, uid)— fetch the current block viaGET /api/sharing.apply_sharing(client, resource_type, uid, sharing)— replace it viaPOST /api/sharing. Returns aWebMessageResponse.- A
SharingBuilderconvenience for building upSharingObjectwithout typing the map-vs-list details by hand.
Classes¶
Sharing
¶
Bases: BaseModel
OpenAPI schema Sharing.
Source code in packages/dhis2w-client/src/dhis2w_client/generated/v42/oas/sharing.py
SharingObject
¶
Bases: BaseModel
OpenAPI schema SharingObject.
Source code in packages/dhis2w-client/src/dhis2w_client/generated/v42/oas/sharing_object.py
SharingBuilder
¶
Bases: BaseModel
Fluent-ish builder for SharingObject so callers don't hand-assemble maps.
Callers that want to attach fresh sharing to an object work in terms of
"grant user X read+write", not "build a SharingUserAccess and append it
to the list". The builder hides that boilerplate while producing the exact
wire shape POST /api/sharing wants.
Source code in packages/dhis2w-client/src/dhis2w_client/sharing.py
Functions¶
grant_user(user_id, access)
¶
Grant access to one user (overwrites any existing grant).
grant_user_group(group_id, access)
¶
Grant access to one user group (overwrites any existing grant).
Source code in packages/dhis2w-client/src/dhis2w_client/sharing.py
to_sharing_object()
¶
Materialise the builder into the SharingObject wire shape.
Source code in packages/dhis2w-client/src/dhis2w_client/sharing.py
Functions¶
access_string(*, metadata='--', data='--')
¶
Compose an 8-char DHIS2 access string from metadata + data r/w pairs.
Examples:
>>> access_string(metadata="rw") # metadata-only read/write
'rw------'
>>> access_string(metadata="r-", data="r-") # read-everything
'r-r-----'
>>> access_string(metadata="rw", data="rw") # full access
'rwrw----'
Source code in packages/dhis2w-client/src/dhis2w_client/sharing.py
get_sharing(client, resource_type, uid)
async
¶
Fetch GET /api/sharing?type=<resource_type>&id=<uid> → SharingObject.
resource_type is the DHIS2 singular metadata-resource name as it appears
in filter syntax and in the sharing API's ?type= param — e.g.
"dataSet", "dataElement", "program", "user". DHIS2 returns a
{meta, object} envelope; callers almost always want just .object.
Source code in packages/dhis2w-client/src/dhis2w_client/sharing.py
apply_sharing(client, resource_type, uid, sharing)
async
¶
Replace the sharing block via POST /api/sharing?type=<t>&id=<uid>.
DHIS2 ignores unknown fields and preserves the owner user when the payload
omits it. Accepts either a SharingObject (raw wire shape) or a
SharingBuilder (convenience form).