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 # $Source: /cvsroot/gnumed/gnumed/gnumed/client/business/gmSOAPimporter.py,v $ 28 # $Id: gmSOAPimporter.py,v 1.24 2009/12/21 14:59:31 ncq Exp $ 29 __version__ = "$Revision: 1.24 $" 30 __author__ = "Carlos Moro <cfmoro1976@yahoo.es>" 31 __license__ = "GPL (details at http://www.gnu.org)" 32 33 # stdlib 34 import sys, re, logging 35 36 37 # 3rd party 38 import mx.DateTime as mxDT 39 40 41 # GnuMed 42 from Gnumed.pycommon import gmExceptions, gmI18N, gmDispatcher 43 from Gnumed.business import gmClinNarrative, gmPerson 44 45 46 _log = logging.getLogger('gm.soap') 47 48 49 # module level constants 50 soap_bundle_SOAP_CAT_KEY = "soap" 51 soap_bundle_TYPES_KEY = "types" 52 soap_bundle_TEXT_KEY = "text" 53 soap_bundle_CLIN_CTX_KEY = "clin_context" 54 soap_bundle_TYPE_KEY = "type" 55 soap_bundle_EPISODE_ID_KEY = "episode_id" 56 soap_bundle_ENCOUNTER_ID_KEY = "encounter_id" 57 soap_bundle_STAFF_ID_KEY = "staff_id" 58 soap_bundle_SOAP_CATS = ['s','o','a','p'] # these are pretty much fixed 59 #===============================================================61 """ 62 Main SOAP importer class 63 """ 64 65 #----------------------------------------------------------- 68 #----------------------------------------------------------- 69 # external API 70 #-----------------------------------------------------------157 #----------------------------------------------------------- 158 # def _verify_types(self, soap_entry): 159 # """ 160 # Perform types key check of a supplied SOAP entry 161 # 162 # @param soap_entry: dictionary containing information related to one 163 # SOAP input 164 # @type soap_entry: dictionary with keys 'soap', 'types', 'text' 165 # """ 166 # 167 # # FIXME fetch from backend 168 # allowed_types = ['Hx'] 169 # for input_type in soap_entry[soap_bundle_TYPES_KEY]: 170 # if not input_type in allowed_types: 171 # _log.error('bad clin_item_type.type in supplied soap entry [%s]' % 172 # soap_entry) 173 # return False 174 # return True 175 176 #================================================================ 177 # MAIN 178 #---------------------------------------------------------------- 179 if __name__ == '__main__': 180 _log.info("starting SOAP importer...") 181 182 try: 183 # obtain patient 184 patient = gmPerson.ask_for_patient() 185 if patient is None: 186 print "No patient. Exiting gracefully..." 187 sys.exit(0) 188 gmPerson.set_active_patient(patient=patient) 189 190 # now import 191 importer = cSOAPImporter() 192 bundle = [ 193 {soap_bundle_SOAP_CAT_KEY: 's', 194 soap_bundle_TYPES_KEY: ['Hx'], 195 soap_bundle_TEXT_KEY: 'Test subjective narrative', 196 soap_bundle_CLIN_CTX_KEY: {soap_bundle_EPISODE_ID_KEY: '1'} 197 }, 198 {soap_bundle_SOAP_CAT_KEY: 'o', 199 soap_bundle_TYPES_KEY: ['Hx'], 200 soap_bundle_TEXT_KEY: 'Test objective narrative', 201 soap_bundle_CLIN_CTX_KEY: {soap_bundle_EPISODE_ID_KEY: '1'} 202 }, 203 {soap_bundle_SOAP_CAT_KEY: 'a', 204 soap_bundle_TYPES_KEY: ['Hx'], 205 soap_bundle_TEXT_KEY: 'Test assesment narrative', 206 soap_bundle_CLIN_CTX_KEY: {soap_bundle_EPISODE_ID_KEY: '1'} 207 }, 208 {soap_bundle_SOAP_CAT_KEY: 'p', 209 soap_bundle_TYPES_KEY: ['Hx'], 210 soap_bundle_TEXT_KEY: 'Test plan narrative. [:tetanus:]. [:pneumoniae:].', 211 soap_bundle_CLIN_CTX_KEY: { 212 soap_bundle_EPISODE_ID_KEY: '1', 213 soap_bundle_ENCOUNTER_ID_KEY: '1', 214 soap_bundle_STAFF_ID_KEY: '1' 215 }, 216 } 217 ] 218 importer.import_soap(bundle) 219 220 # clean up 221 if patient is not None: 222 try: 223 patient.cleanup() 224 except: 225 print "error cleaning up patient" 226 except StandardError: 227 _log.exception("unhandled exception caught !", sys.exc_info(), 1) 228 # but re-raise them 229 raise 230 231 _log.info("closing SOAP importer...") 232 #================================================================ 233 # $Log: gmSOAPimporter.py,v $ 234 # Revision 1.24 2009/12/21 14:59:31 ncq 235 # - typo 236 # 237 # Revision 1.23 2009/09/13 18:25:54 ncq 238 # - no more get-active-encounter() 239 # 240 # Revision 1.22 2008/02/25 17:31:41 ncq 241 # - logging cleanup 242 # 243 # Revision 1.21 2008/01/30 13:34:50 ncq 244 # - switch to std lib logging 245 # 246 # Revision 1.20 2007/12/23 11:55:21 ncq 247 # - cleanup 248 # 249 # Revision 1.19 2007/12/11 12:59:11 ncq 250 # - cleanup and explicit signal handling 251 # 252 # Revision 1.18 2007/03/08 11:31:08 ncq 253 # - just cleanup 254 # 255 # Revision 1.17 2006/10/31 11:27:15 ncq 256 # - remove use of gmPG 257 # 258 # Revision 1.16 2006/10/25 07:17:40 ncq 259 # - no more gmPG 260 # - no more cClinItem 261 # 262 # Revision 1.15 2006/10/23 13:06:54 ncq 263 # - vaccs DB object not yet converted 264 # 265 # Revision 1.14 2006/07/19 21:37:51 ncq 266 # - cleanup 267 # 268 # Revision 1.13 2006/06/17 13:58:39 ncq 269 # - cleanup 270 # 271 # Revision 1.12 2006/05/12 12:05:04 ncq 272 # - cleanup 273 # 274 # Revision 1.11 2006/05/04 09:49:20 ncq 275 # - get_clinical_record() -> get_emr() 276 # - adjust to changes in set_active_patient() 277 # - need explicit set_active_patient() after ask_for_patient() if wanted 278 # 279 # Revision 1.10 2005/10/19 09:14:46 ncq 280 # - remove half-baked support for embedded data, now handled elsewhere 281 # - general cleanup/doc fixes 282 # 283 # Revision 1.9 2005/10/11 21:50:33 ncq 284 # - create_clin_narrative() should not be aware of emr object 285 # 286 # Revision 1.8 2005/10/08 12:33:08 sjtan 287 # tree can be updated now without refetching entire cache; done by passing emr object to create_xxxx methods and calling emr.update_cache(key,obj);refresh_historical_tree non-destructively checks for changes and removes removed nodes and adds them if cache mismatch. 288 # 289 # Revision 1.7 2005/05/17 08:03:30 ncq 290 # - cleanup 291 # 292 # Revision 1.6 2005/04/12 09:59:16 ncq 293 # - cleanup 294 # - enable actual backend storage 295 # 296 # Revision 1.5 2005/01/31 13:00:40 ncq 297 # - use ask_for_patient() in gmPerson 298 # 299 # Revision 1.4 2005/01/31 10:37:26 ncq 300 # - gmPatient.py -> gmPerson.py 301 # 302 # Revision 1.3 2004/12/20 09:51:28 ncq 303 # - tie constants to bundle not importer re naming 304 # 305 # Revision 1.2 2004/12/19 18:41:55 cfmoro 306 # Struct keys made module level constants 307 # 308 # Revision 1.1 2004/12/18 16:14:13 ncq 309 # - moved here from test area 310 # 311 # Revision 1.7 2004/12/18 16:00:37 ncq 312 # - final touch up before moving over 313 # 314 # Revision 1.6 2004/12/16 17:59:38 cfmoro 315 # Encapsulation syntax fixed (_ replaced by __). Using tab indentation, in consistency with the rest of gnumed files 316 # 317 # Revision 1.5 2004/12/13 19:37:08 ncq 318 # - cleanup after review by Carlos 319 # - will be moved to main trunk RSN 320 # 321 # 32272 """ 73 Import supplied GnuMed SOAP input "bundle". For details consult current 74 module's description information. 75 76 @param bundle: GnuMed SOAP input data (as described in module's information) 77 @type bundle: list of dicts 78 """ 79 # process each entry in soap bundle independently 80 for soap_entry in bundle: 81 if not self.__import_narrative(soap_entry): 82 _log.error('skipping soap entry') 83 continue 84 gmDispatcher.send(signal = 'clin_item_updated') 85 return True86 #----------------------------------------------------------- 87 # internal helpers 88 #-----------------------------------------------------------90 """Import soap entry into GnuMed backend. 91 92 @param soap_entry: dictionary containing information related 93 to one SOAP input line 94 @type soap_entry: dictionary with keys 'soap', 'types', 'text' 95 96 FIXME: Later we may want to allow for explicitly setting a staff ID to be 97 FIXME: used for import. This would allow to import data "on behalf of" someone. 98 """ 99 if not self.__verify_soap_entry(soap_entry=soap_entry): 100 _log.error('cannot verify soap entry') 101 return False 102 # obtain clinical context information 103 emr = gmPerson.gmCurrentPatient().get_emr() 104 epi_id = soap_entry[soap_bundle_CLIN_CTX_KEY][soap_bundle_EPISODE_ID_KEY] 105 try: 106 enc_id = soap_entry[soap_bundle_CLIN_CTX_KEY][soap_bundle_ENCOUNTER_ID_KEY] 107 except KeyError: 108 enc = emr.active_encounter 109 enc_id = enc['pk_encounter'] 110 111 # create narrative row 112 status, narr = gmClinNarrative.create_clin_narrative ( 113 narrative = soap_entry[soap_bundle_TEXT_KEY], 114 soap_cat = soap_entry[soap_bundle_SOAP_CAT_KEY], 115 episode_id = epi_id, 116 encounter_id = enc_id 117 ) 118 119 # # attach types 120 # if soap_entry.has_key(soap_bundle_TYPES_KEY): 121 # print "code missing to attach types to imported narrative" 122 123 return status124 #-----------------------------------------------------------126 """Perform basic integrity check of a supplied SOAP entry. 127 128 @param soap_entry: dictionary containing information related to one 129 SOAP input 130 @type soap_entry: dictionary with keys 'soap', 'types', 'text' 131 """ 132 required_keys = [ 133 soap_bundle_SOAP_CAT_KEY, 134 soap_bundle_CLIN_CTX_KEY, 135 soap_bundle_TEXT_KEY 136 ] 137 # verify key existence 138 for a_key in required_keys: 139 try: 140 soap_entry[a_key] 141 except KeyError: 142 _log.error('key [%s] is missing from soap entry' % a_key) 143 _log.error('%s' % soap_entry) 144 return False 145 # verify key *values* 146 if not soap_entry[soap_bundle_SOAP_CAT_KEY] in soap_bundle_SOAP_CATS: 147 _log.error('invalid soap category [%s]' % soap_entry[soap_bundle_SOAP_CAT_KEY]) 148 _log.error('%s' % soap_entry) 149 return False 150 try: 151 soap_entry[soap_bundle_CLIN_CTX_KEY][soap_bundle_EPISODE_ID_KEY] 152 except KeyError: 153 _log.error('SOAP entry does not provide mandatory episode ID') 154 _log.error('%s' % soap_entry) 155 return False 156 return True
Trees | Indices | Help |
|
---|
Generated by Epydoc 3.0.1 on Tue Feb 9 04:02:35 2010 | http://epydoc.sourceforge.net |