1
1
import urllib .parse
2
-
2
+ import json
3
3
import requests
4
4
5
5
# Make sure these are set before trying to make requests
10
10
# TODO It might be clearer to create a Server object class and have this be the __init__() function
11
11
def configure_DHIS2_server (username = None , password = None , server_url = None ):
12
12
global DHIS2_SERVER_URL , DHIS2_USERNAME , DHIS2_PASSWORD
13
- DHIS2_USERNAME = username
14
- DHIS2_PASSWORD = password
15
- DHIS2_SERVER_URL = server_url
16
-
17
-
18
- def checkResponseStatus (res ):
19
- if res .status_code == 401 :
20
- raise ValueError ("Authentication failed. Check your username and password." )
21
- res .raise_for_status ()
22
-
13
+ if username is not None :
14
+ DHIS2_USERNAME = username
15
+ if password is not None :
16
+ DHIS2_PASSWORD = password
17
+ if server_url is not None :
18
+ DHIS2_SERVER_URL = server_url
23
19
24
20
def getAllUIDs (item_type , search_items ):
25
21
encoded_search_items = [urllib .parse .quote_plus (item ) for item in search_items ]
@@ -30,10 +26,7 @@ def getAllUIDs(item_type, search_items):
30
26
filter_param = 'filter=' + '&filter=' .join ([f'name:ilike:{ term } ' for term in encoded_search_items ])
31
27
32
28
url = f'{ DHIS2_SERVER_URL } /api/{ item_type } ?{ filter_param } '
33
- response = requests .get (url , auth = (DHIS2_USERNAME , DHIS2_PASSWORD ))
34
- checkResponseStatus (response )
35
-
36
- data = response .json ()
29
+ data = getResponse (url )
37
30
items = data [item_type ]
38
31
print (f"{ len (data [item_type ])} matches found for { search_items } " )
39
32
if len (items ) > 0 :
@@ -43,6 +36,15 @@ def getAllUIDs(item_type, search_items):
43
36
44
37
return uid
45
38
39
+ def getResponse (url ):
40
+ response = requests .get (url , auth = (DHIS2_USERNAME , DHIS2_PASSWORD ))
41
+
42
+ if response .status_code == 401 :
43
+ raise ValueError ("Authentication failed. Check your username and password." )
44
+ response .raise_for_status ()
45
+
46
+ data = response .json ()
47
+ return data
46
48
47
49
def getOrgUnitChildren (uid ):
48
50
"""
@@ -51,11 +53,7 @@ def getOrgUnitChildren(uid):
51
53
:return: List of (org unit child name, org unit child data sets))
52
54
"""
53
55
url = f'{ DHIS2_SERVER_URL } /api/organisationUnits/{ uid } ?includeChildren=true'
54
-
55
- response = requests .get (url , auth = (DHIS2_USERNAME , DHIS2_PASSWORD ))
56
- checkResponseStatus (response )
57
-
58
- data = response .json ()
56
+ data = getResponse (url )
59
57
items = data ['organisationUnits' ]
60
58
children = [(item ['name' ], item ['dataSets' ], item ['id' ]) for item in items if item ['id' ] != uid ]
61
59
@@ -73,71 +71,67 @@ def getDataSets(data_sets_uids):
73
71
uid = uid_obj ['id' ]
74
72
url = f'{ DHIS2_SERVER_URL } /api/dataSets/{ uid } '
75
73
76
- response = requests .get (url , auth = (DHIS2_USERNAME , DHIS2_PASSWORD ))
77
- checkResponseStatus (response )
78
-
79
- data = response .json ()
74
+ data = getResponse (url )
80
75
data_set = (data ['name' ], data ['id' ], data ['periodType' ])
81
76
data_sets .append (data_set )
82
77
83
78
return data_sets
84
79
85
- def getCategoryUIDs (dataSet_uid ):
80
+ def getFormJson (dataSet_uid , period , orgUnit_uid ):
86
81
"""
87
- Hierarchically searches DHIS2 to generate category UIDs for each dataElement. Also used for retreiving all data elements and categories present in a dataset.
88
- :param data_sets_uid: UID of the dataset
89
- :return: dataElement_to_id (dict[str, str]), dataElement_to_categoryCombo (dict[str, str]), categoryCombos (dict[str, str]), category_list (list[str]), dataElement_list (list[str])
90
- category list eg. ['0-11m','<5y'...]
82
+ Gets information about all forms associated with a organisation, dataset, period combination in DHIS2.
83
+ :param dataset UID, time period, organisation unit UID
84
+ :return json response containing hierarchical information about tabs, tables, non-tabular fields
91
85
"""
92
- url = f'{ DHIS2_SERVER_URL } /api/dataSets/{ dataSet_uid } ?fields=dataSetElements'
93
-
94
- response = requests .get (url , auth = (DHIS2_USERNAME , DHIS2_PASSWORD ))
95
- checkResponseStatus (response )
96
86
97
- data = response .json ()
98
-
99
- items = data ['dataSetElements' ]
100
-
101
- dataElement_to_categoryCombo = {}
102
- categoryCombos = {}
103
- categoryOptionCombos = {}
104
- for item in items :
105
- if 'categoryCombo' in item :
106
- dataElement_to_categoryCombo [item ['dataElement' ]['id' ]] = item ['categoryCombo' ]['id' ]
107
- categoryCombos [item ['categoryCombo' ]['id' ]] = {}
108
-
109
- for catCombo_id in categoryCombos :
110
- url = f'{ DHIS2_SERVER_URL } /api/categoryCombos/{ catCombo_id } ?fields=categoryOptionCombos'
111
-
112
- response = requests .get (url , auth = (DHIS2_USERNAME , DHIS2_PASSWORD ))
113
- checkResponseStatus (response )
114
-
115
- data = response .json ()
116
-
117
- items = data ['categoryOptionCombos' ]
118
-
119
- for item in items :
120
- url = f"{ DHIS2_SERVER_URL } /api/categoryOptionCombos/{ item ['id' ]} ?fields=name"
121
-
122
- response = requests .get (url , auth = (DHIS2_USERNAME , DHIS2_PASSWORD ))
123
- checkResponseStatus (response )
87
+ # POST empty data payload to trigger form generation
88
+ json_export = {}
89
+ json_export ["dataSet" ] = dataSet_uid
90
+ json_export ["period" ] = period
91
+ json_export ["orgUnit" ] = orgUnit_uid
92
+ json_export ["dataValues" ] = []
93
+ data_payload = json .dumps (json_export )
94
+ posturl = f'{ DHIS2_SERVER_URL } /api/dataValueSets?dryRun=true'
95
+
96
+ response = requests .post (
97
+ posturl ,
98
+ auth = (DHIS2_USERNAME , DHIS2_PASSWORD ),
99
+ headers = {'Content-Type' : 'application/json' },
100
+ data = data_payload
101
+ )
102
+ response .raise_for_status ()
103
+
104
+ # Get form now
105
+ url = f'{ DHIS2_SERVER_URL } /api/dataSets/{ dataSet_uid } /form.json?pe={ period } &ou={ orgUnit_uid } '
106
+ data = getResponse (url )
107
+ return data
124
108
125
- data = response .json ()
126
-
127
- categoryCombos [catCombo_id ][data ['name' ]] = item ['id' ]
128
-
129
- if data ['name' ] not in categoryOptionCombos :
130
- categoryOptionCombos [data ['name' ]] = ''
131
- category_list = list (categoryOptionCombos .keys ())
132
-
133
- url = f'{ DHIS2_SERVER_URL } /api/dataElements?filter=dataSetElements.dataSet.id:eq:{ dataSet_uid } &fields=id,formName'
134
- response = requests .get (url , auth = (DHIS2_USERNAME , DHIS2_PASSWORD ))
135
- checkResponseStatus (response )
136
- data = response .json ()
137
-
138
- dataElement_to_id = {item ["formName" ]:item ["id" ] for item in data ['dataElements' ]}
139
- dataElement_list = [item ["formName" ] for item in data ['dataElements' ]]
109
+ def get_DE_COC_List (form ):
110
+ """
111
+ Finds the list of all dataElements (row names in tables) and categoryOptionCombos (column names in tables) within a DHIS2 form
112
+ :param json data containing hierarchical information about tabs, tables, non-tabular fields within a organisation, dataset, period combination in DHIS2.
113
+ :return List of row names found, List of column names found
114
+ """
115
+ url = f'{ DHIS2_SERVER_URL } /api/dataElements?paging=false&fields=id,formName'
116
+ data = getResponse (url )
117
+ allDataElements = {item ['id' ]:item ['formName' ] for item in data ['dataElements' ] if 'formName' in item and 'id' in item }
118
+
119
+ url = f'{ DHIS2_SERVER_URL } /api/categoryOptionCombos?paging=false&fields=id,name'
120
+ data = getResponse (url )
121
+ allCategory = {item ['id' ]:item ['name' ] for item in data ['categoryOptionCombos' ] if 'name' in item and 'id' in item }
122
+
123
+ # Form tabs found in DHIS2
124
+ tabs = form ['groups' ]
125
+ dataElement_list = {}
126
+ categoryOptionCombo_list = {}
127
+ for tab in tabs :
128
+ for field in tab ['fields' ]:
129
+ DE_ID = field ['dataElement' ]
130
+ COC_ID = field ['categoryOptionCombo' ]
131
+ if allDataElements [DE_ID ] not in dataElement_list :
132
+ dataElement_list [allDataElements [DE_ID ]] = 1
133
+ if allCategory [COC_ID ] not in categoryOptionCombo_list :
134
+ categoryOptionCombo_list [allCategory [COC_ID ]] = 1
135
+ return list (dataElement_list .keys ()), list (categoryOptionCombo_list .keys ())
140
136
141
- return dataElement_to_id , dataElement_to_categoryCombo , categoryCombos , category_list , dataElement_list
142
-
143
137
0 commit comments