| Home | Trees | Indices | Help |
|
|---|
|
|
1 """GNUmed SOAP importer
2
3 (specification by Karsten Hilbert <Karsten.Hilbert@gmx.net>)
4
5 This script is designed for importing GNUmed SOAP input "bundles".
6
7 - "bundle" is list of dicts
8 - each "bundle" is processed dict by dict
9 - the dicts in the list are INDEPENDANT of each other
10 - each dict contains information for one new clin_narrative row
11 - each dict has the keys: 'soap', 'types', 'text', 'clin_context'
12 - 'soap':
13 - relates to clin_narrative.soap_cat
14 - 'types':
15 - a list of strings
16 - the strings must be found in clin_item_type.type
17 - strings not found in clin_item_type.type are ignored during
18 import and the user is warned about that
19 - 'text':
20 - the narrative for clin_narrative.narrative, imported as is
21 - 'clin_context':
22 - 'clin_context' is a dictionary containing clinical
23 context information, required to properly create clinical items.
24 Its 'episode_id' must always be supplied.
25 """
26 #===============================================================
27 __version__ = "$Revision: 1.24 $"
28 __author__ = "Carlos Moro <cfmoro1976@yahoo.es>"
29 __license__ = "GPL v2 or later (details at http://www.gnu.org)"
30
31 # stdlib
32 import sys, re, logging
33
34
35 # GNUmed
36 from Gnumed.pycommon import gmExceptions, gmI18N, gmDispatcher
37 from Gnumed.business import gmClinNarrative, gmPerson, gmPersonSearch
38
39
40 _log = logging.getLogger('gm.soap')
41
42
43 # module level constants
44 soap_bundle_SOAP_CAT_KEY = "soap"
45 soap_bundle_TYPES_KEY = "types"
46 soap_bundle_TEXT_KEY = "text"
47 soap_bundle_CLIN_CTX_KEY = "clin_context"
48 soap_bundle_TYPE_KEY = "type"
49 soap_bundle_EPISODE_ID_KEY = "episode_id"
50 soap_bundle_ENCOUNTER_ID_KEY = "encounter_id"
51 soap_bundle_STAFF_ID_KEY = "staff_id"
52 soap_bundle_SOAP_CATS = ['s','o','a','p'] # these are pretty much fixed
53 #===============================================================
55 """
56 Main SOAP importer class
57 """
58 #-----------------------------------------------------------
61 #-----------------------------------------------------------
62 # external API
63 #-----------------------------------------------------------
65 """
66 Import supplied GNUmed SOAP input "bundle". For details consult current
67 module's description information.
68
69 @param bundle: GNUmed SOAP input data (as described in module's information)
70 @type bundle: list of dicts
71 """
72 # process each entry in soap bundle independently
73 for soap_entry in bundle:
74 if not self.__import_narrative(soap_entry):
75 _log.error('skipping soap entry')
76 continue
77 gmDispatcher.send(signal = 'clin_item_updated')
78 return True
79 #-----------------------------------------------------------
80 # internal helpers
81 #-----------------------------------------------------------
83 """Import soap entry into GNUmed backend.
84
85 @param soap_entry: dictionary containing information related
86 to one SOAP input line
87 @type soap_entry: dictionary with keys 'soap', 'types', 'text'
88
89 FIXME: Later we may want to allow for explicitly setting a staff ID to be
90 FIXME: used for import. This would allow to import data "on behalf of" someone.
91 """
92 if not self.__verify_soap_entry(soap_entry=soap_entry):
93 _log.error('cannot verify soap entry')
94 return False
95 # obtain clinical context information
96 emr = gmPerson.gmCurrentPatient().get_emr()
97 epi_id = soap_entry[soap_bundle_CLIN_CTX_KEY][soap_bundle_EPISODE_ID_KEY]
98 try:
99 enc_id = soap_entry[soap_bundle_CLIN_CTX_KEY][soap_bundle_ENCOUNTER_ID_KEY]
100 except KeyError:
101 enc = emr.active_encounter
102 enc_id = enc['pk_encounter']
103
104 # create narrative row
105 status, narr = gmClinNarrative.create_clin_narrative (
106 narrative = soap_entry[soap_bundle_TEXT_KEY],
107 soap_cat = soap_entry[soap_bundle_SOAP_CAT_KEY],
108 episode_id = epi_id,
109 encounter_id = enc_id
110 )
111
112 # # attach types
113 # if soap_entry.has_key(soap_bundle_TYPES_KEY):
114 # print "code missing to attach types to imported narrative"
115
116 return status
117 #-----------------------------------------------------------
119 """Perform basic integrity check of a supplied SOAP entry.
120
121 @param soap_entry: dictionary containing information related to one
122 SOAP input
123 @type soap_entry: dictionary with keys 'soap', 'types', 'text'
124 """
125 required_keys = [
126 soap_bundle_SOAP_CAT_KEY,
127 soap_bundle_CLIN_CTX_KEY,
128 soap_bundle_TEXT_KEY
129 ]
130 # verify key existence
131 for a_key in required_keys:
132 try:
133 soap_entry[a_key]
134 except KeyError:
135 _log.error('key [%s] is missing from soap entry' % a_key)
136 _log.error('%s' % soap_entry)
137 return False
138 # verify key *values*
139 if not soap_entry[soap_bundle_SOAP_CAT_KEY] in soap_bundle_SOAP_CATS:
140 _log.error('invalid soap category [%s]' % soap_entry[soap_bundle_SOAP_CAT_KEY])
141 _log.error('%s' % soap_entry)
142 return False
143 try:
144 soap_entry[soap_bundle_CLIN_CTX_KEY][soap_bundle_EPISODE_ID_KEY]
145 except KeyError:
146 _log.error('SOAP entry does not provide mandatory episode ID')
147 _log.error('%s' % soap_entry)
148 return False
149 return True
150 #-----------------------------------------------------------
151 # def _verify_types(self, soap_entry):
152 # """
153 # Perform types key check of a supplied SOAP entry
154 #
155 # @param soap_entry: dictionary containing information related to one
156 # SOAP input
157 # @type soap_entry: dictionary with keys 'soap', 'types', 'text'
158 # """
159 #
160 # # FIXME fetch from backend
161 # allowed_types = ['Hx']
162 # for input_type in soap_entry[soap_bundle_TYPES_KEY]:
163 # if not input_type in allowed_types:
164 # _log.error('bad clin_item_type.type in supplied soap entry [%s]' %
165 # soap_entry)
166 # return False
167 # return True
168
169 #================================================================
170 # MAIN
171 #----------------------------------------------------------------
172 if __name__ == '__main__':
173 _log.info("starting SOAP importer...")
174
175 try:
176 # obtain patient
177 patient = gmPersonSearch.ask_for_patient()
178 if patient is None:
179 print "No patient. Exiting gracefully..."
180 sys.exit(0)
181 gmPerson.set_active_patient(patient=patient)
182
183 # now import
184 importer = cSOAPImporter()
185 bundle = [
186 {soap_bundle_SOAP_CAT_KEY: 's',
187 soap_bundle_TYPES_KEY: ['Hx'],
188 soap_bundle_TEXT_KEY: 'Test subjective narrative',
189 soap_bundle_CLIN_CTX_KEY: {soap_bundle_EPISODE_ID_KEY: '1'}
190 },
191 {soap_bundle_SOAP_CAT_KEY: 'o',
192 soap_bundle_TYPES_KEY: ['Hx'],
193 soap_bundle_TEXT_KEY: 'Test objective narrative',
194 soap_bundle_CLIN_CTX_KEY: {soap_bundle_EPISODE_ID_KEY: '1'}
195 },
196 {soap_bundle_SOAP_CAT_KEY: 'a',
197 soap_bundle_TYPES_KEY: ['Hx'],
198 soap_bundle_TEXT_KEY: 'Test assesment narrative',
199 soap_bundle_CLIN_CTX_KEY: {soap_bundle_EPISODE_ID_KEY: '1'}
200 },
201 {soap_bundle_SOAP_CAT_KEY: 'p',
202 soap_bundle_TYPES_KEY: ['Hx'],
203 soap_bundle_TEXT_KEY: 'Test plan narrative. [:tetanus:]. [:pneumoniae:].',
204 soap_bundle_CLIN_CTX_KEY: {
205 soap_bundle_EPISODE_ID_KEY: '1',
206 soap_bundle_ENCOUNTER_ID_KEY: '1',
207 soap_bundle_STAFF_ID_KEY: '1'
208 },
209 }
210 ]
211 importer.import_soap(bundle)
212
213 # clean up
214 if patient is not None:
215 try:
216 patient.cleanup()
217 except:
218 print "error cleaning up patient"
219 except StandardError:
220 _log.exception("unhandled exception caught !", sys.exc_info(), 1)
221 # but re-raise them
222 raise
223
224 _log.info("closing SOAP importer...")
225 #================================================================
226
| Home | Trees | Indices | Help |
|
|---|
| Generated by Epydoc 3.0.1 on Sat Oct 5 03:57:12 2013 | http://epydoc.sourceforge.net |