def post_data(self, date_onset=None, date_resolution=None, name=None, name_type=None, name_value=None, name_abbrev=None, comments=None, diagnosed_by=None): """ SZ: More error checking needs to be performed in this method """ if date_onset: date_onset=iso8601.parse_utc_date(date_onset) if date_resolution: date_resolution=iso8601.parse_utc_date(date_resolution) try: problem_obj = Problem.objects.create( date_onset=date_onset, date_resolution=date_resolution, name=name, name_type=name_type, name_value=name_value, name_abbrev=name_abbrev, comments=comments, diagnosed_by=diagnosed_by) return problem_obj except Exception, e: raise ValueError("problem processing problemlist report " + str(e))
def post_data(self, date_started=None, date_stopped=None, name=None, vendor=None, description=None): """ SZ: More error checking needs to be performed in this method """ try: if date_started: date_started = iso8601.parse_utc_date(date_started) if date_stopped: date_stopped = iso8601.parse_utc_date(date_stopped) equipment_obj = Equipment.objects.create( date_started=date_started, date_stopped=date_stopped, name=name, vendor=vendor, description=description) return equipment_obj except Exception, e: raise ValueError("problem processing equipment report " + str(e))
def post_data(self, date_started=None, date_stopped=None, name=None, vendor=None, description=None): """ SZ: More error checking needs to be performed in this method """ try: if date_started: date_started = iso8601.parse_utc_date(date_started) if date_stopped: date_stopped = iso8601.parse_utc_date(date_stopped) equipment_obj = Equipment.objects.create(date_started=date_started, date_stopped=date_stopped, name=name, vendor=vendor, description=description) return equipment_obj except Exception, e: raise ValueError("problem processing equipment report " + str(e))
def parse_date_range(value): field, start_date, end_date = value.split('*') start_date = None if start_date == '' else iso8601.parse_utc_date( start_date) end_date = None if end_date == '' else iso8601.parse_utc_date( end_date) return { 'field': field, 'start_date': start_date, 'end_date': end_date }
def _get_data(self, doc_etree): """ Parse the etree and return a dict of key-value pairs for object construction. """ ret = {} _t = self._tag # name name_node = doc_etree.find(_t('name')) ret['name_text'] = name_node.text ret['name_type'] = name_node.get('type') ret['name_type'] = name_node.get('value') ret['name_type'] = name_node.get('abbrev') # planType ret['planType'] = doc_etree.findtext(_t('planType')) # reportedBy ret['reportedBy'] = doc_etree.findtext(_t('reportedBy')) # dateReported date_reported = doc_etree.findtext(_t('dateReported')) if date_reported: ret['dateReported'] = parse_utc_date(date_reported) # actions actions_node = doc_etree.find(_t('actions')) if actions_node: ret['actions'] = etree.tostring(actions_node, xml_declaration=False) return ret
def post_data(self, date_measured, lab_type=None, lab_name=None, lab_address=None, lab_comments=None, first_panel_name=None, first_lab_test_name=None, first_lab_test_value=None): """ SZ: More error checking needs to be performed in this method """ if date_measured: date_measured = iso8601.parse_utc_date(date_measured) try: lab_obj = Lab.objects.create( date_measured=date_measured, lab_type=lab_type, lab_name=lab_name, lab_address=lab_address, lab_comments=lab_comments, first_panel_name = first_panel_name, first_lab_test_name = first_lab_test_name, first_lab_test_value = first_lab_test_value) return lab_obj except Exception, e: raise ValueError("problem processing lab report " + str(e))
def post_data(self, date_performed=None, name=None, name_type=None, name_value=None, name_abbrev=None, provider_name=None, provider_institution=None, location=None, comments=None): """ SZ: More error checking needs to be performed in this method """ if date_performed: date_performed = iso8601.parse_utc_date(date_performed) try: procedure_obj = Procedure.objects.create( date_performed=date_performed, name=name, name_type=name_type, name_value=name_value, name_abbrev=name_abbrev, provider_name=provider_name, provider_institution=provider_institution, location=location, comments=comments) return procedure_obj except Exception, e: raise ValueError("problem processing procedure report " + str(e))
def _get_data(self, doc_etree): """ Parse the etree and return a dict of key-value pairs for object construction. """ ret = {} _t = self._tag # name name_node = doc_etree.find(_t('name')) ret['name_text'] = name_node.text ret['name_type'] = name_node.get('type') ret['name_type'] = name_node.get('value') ret['name_type'] = name_node.get('abbrev') # planType ret['planType'] = doc_etree.findtext(_t('planType')) # reportedBy ret['reportedBy'] = doc_etree.findtext(_t('reportedBy')) # dateReported date_reported = doc_etree.findtext(_t('dateReported')) if date_reported: ret['dateReported'] = parse_utc_date(date_reported) # actions actions_node = doc_etree.find(_t('actions')) ret['actions'] = etree.tostring(actions_node, xml_declaration=False) return ret
def surl_verify(request): """ Verify a signed URL. The URL must contain the following GET parameters: * *surl_timestamp*: when the url was generated. Must be within the past hour, to avoid permitting old surls. * *surl_token* The access token used to sign the url. * *surl_sig* The computed signature (base-64 encoded sha1) of the url. Will always return :http:statuscode:`200`. The response body will be one of: * ``<result>ok</result>``: The surl was valid. * ``<result>old</result>``: The surl was too old. * ``<result>mismatch</result>``: The surl's signature was invalid. """ OK = HttpResponse("<result>ok</result>", mimetype="application/xml") # May want to add more explanation here OLD = HttpResponse("<result>old</result>", mimetype="application/xml") MISMATCH = HttpResponse("<result>mismatch</result>", mimetype="application/xml") url = request.GET["url"] parsed_url = urlparse.urlparse(url) query = urlparse.parse_qs(parsed_url.query) # check timestamp (cheapest thing to check, we check it first) url_timestamp = iso8601.parse_utc_date(query["surl_timestamp"][0]) if (datetime.datetime.utcnow() - url_timestamp) > datetime.timedelta(hours=1): return OLD # generate the secret that should be used here try: token = AccessToken.objects.get(token=query["surl_token"][0]) except AccessToken.DoesNotExist: return MISMATCH # compute the surl secret # the string conversion on the secret is required because of a python 2.6 bug secret = base64.b64encode(hmac.new(str(token.token_secret), "SURL-SECRET", hashlib.sha1).digest()) # extract the signature surl_sig = query["surl_sig"][0] # remove the signature from the URL to verify the rest of it # technically this means the signature can be inserted in the middle of the URL, # but we'll live with that for now, it shouldn't present a problem url_without_sig = url.replace("&%s" % urllib.urlencode({"surl_sig": surl_sig}), "") expected_signature = base64.b64encode(hmac.new(secret, url_without_sig, hashlib.sha1).digest()) if expected_signature == surl_sig: return OK else: return MISMATCH
def surl_verify(request): """ Verify a signed URL. The URL must contain the following GET parameters: * *surl_timestamp*: when the url was generated. Must be within the past hour, to avoid permitting old surls. * *surl_token* The access token used to sign the url. * *surl_sig* The computed signature (base-64 encoded sha1) of the url. Will always return :http:statuscode:`200`. The response body will be one of: * ``<result>ok</result>``: The surl was valid. * ``<result>old</result>``: The surl was too old. * ``<result>mismatch</result>``: The surl's signature was invalid. """ OK = HttpResponse("<result>ok</result>", mimetype="application/xml") # May want to add more explanation here OLD = HttpResponse("<result>old</result>", mimetype="application/xml") MISMATCH = HttpResponse("<result>mismatch</result>", mimetype="application/xml") url = request.GET['url'] parsed_url = urlparse.urlparse(url) query = urlparse.parse_qs(parsed_url.query) # check timestamp (cheapest thing to check, we check it first) url_timestamp = iso8601.parse_utc_date(query['surl_timestamp'][0]) if (datetime.datetime.utcnow() - url_timestamp) > datetime.timedelta(hours=1): return OLD # generate the secret that should be used here try: token = AccessToken.objects.get(token = query['surl_token'][0]) except AccessToken.DoesNotExist: return MISMATCH # compute the surl secret # the string conversion on the secret is required because of a python 2.6 bug secret = base64.b64encode(hmac.new(str(token.token_secret), "SURL-SECRET", hashlib.sha1).digest()) # extract the signature surl_sig = query['surl_sig'][0] # remove the signature from the URL to verify the rest of it # technically this means the signature can be inserted in the middle of the URL, # but we'll live with that for now, it shouldn't present a problem url_without_sig = url.replace('&%s' % urllib.urlencode({'surl_sig': surl_sig}), '') expected_signature = base64.b64encode(hmac.new(secret, url_without_sig, hashlib.sha1).digest()) if expected_signature == surl_sig: return OK else: return MISMATCH
def post_data(self, date_of_visit=None, finalized_at=None, visit_type=None, visit_type_type=None, visit_type_value=None, visit_type_abbrev=None, visit_location=None, specialty=None, specialty_type=None, specialty_value=None, specialty_abbrev=None, signed_at=None, provider_name=None, provider_institution=None, chief_complaint=None, content=None): """ SZ: More error checking needs to be performed in this method """ if date_of_visit: date_of_visit = iso8601.parse_utc_date(date_of_visit) if finalized_at: finalized_at = iso8601.parse_utc_date(finalized_at) if signed_at: signed_at = iso8601.parse_utc_date(signed_at) try: simple_clinical_note = SimpleClinicalNote.objects.create( date_of_visit=date_of_visit, finalized_at=finalized_at, visit_type=visit_type, visit_type_type=visit_type_type, visit_type_value=visit_type_value, visit_type_abbrev=visit_type_abbrev, visit_location=visit_location, specialty=specialty, specialty_type=specialty_type, specialty_value=specialty_value, specialty_abbrev=specialty_abbrev, signed_at=signed_at, provider_name=provider_name, provider_institution=provider_institution, chief_complaint=chief_complaint, content=content) return simple_clinical_note except Exception, e: raise ValueError("problem processing clinical note report " + str(e))
def _get_data(self, doc_etree): """ Parse the etree and return a dict of key-value pairs for object construction. """ ret = {} _t = self._tag # name name_node = doc_etree.find(_t('name')) ret['name_text'] = name_node.text ret['name_type'] = name_node.get('type') ret['name_type'] = name_node.get('value') ret['name_type'] = name_node.get('abbrev') # planType ret['planType'] = doc_etree.findtext(_t('planType')) # plannedBy ret['plannedBy'] = doc_etree.findtext(_t('plannedBy')) # datePlanned ret['datePlanned'] = parse_utc_date( doc_etree.findtext(_t('datePlanned'))) # dateExpires date_expires = doc_etree.findtext(_t('dateExpires')) if date_expires: ret['dateExpires'] = parse_utc_date(date_expires) # indication ret['indication'] = doc_etree.findtext(_t('indication')) # instructions ret['instructions'] = doc_etree.findtext(_t('instructions')) # system system_node = doc_etree.find(_t('system')) ret['system_text'] = name_node.text ret['system_type'] = name_node.get('type') ret['system_type'] = name_node.get('value') ret['system_type'] = name_node.get('abbrev') # actions actions_node = doc_etree.find(_t('actions')) ret['actions'] = etree.tostring(actions_node, xml_declaration=False) return ret
def _get_data(self, doc_etree): """ Parse the etree and return a dict of key-value pairs for object construction. """ ret = {} _t = self._tag # name name_node = doc_etree.find(_t('name')) ret['name_text'] = name_node.text ret['name_type'] = name_node.get('type') ret['name_type'] = name_node.get('value') ret['name_type'] = name_node.get('abbrev') # planType ret['planType'] = doc_etree.findtext(_t('planType')) # plannedBy ret['plannedBy'] = doc_etree.findtext(_t('plannedBy')) # datePlanned ret['datePlanned'] = parse_utc_date(doc_etree.findtext(_t('datePlanned'))) # dateExpires date_expires = doc_etree.findtext(_t('dateExpires')) if date_expires: ret['dateExpires'] = parse_utc_date(date_expires) # indication ret['indication'] = doc_etree.findtext(_t('indication')) # instructions ret['instructions'] = doc_etree.findtext(_t('instructions')) # system system_node = doc_etree.find(_t('system')) ret['system_text'] = name_node.text ret['system_type'] = name_node.get('type') ret['system_type'] = name_node.get('value') ret['system_type'] = name_node.get('abbrev') # actions actions_node = doc_etree.find(_t('actions')) if actions_node: ret['actions'] = etree.tostring(actions_node, xml_declaration=False) return ret
def post_data(self, type, value, unit, datetime): try: measurement_obj = Measurement.objects.create( type=type, value=value, unit=unit, datetime=iso8601.parse_utc_date(datetime)) return measurement_obj except Exception, e: raise ValueError("problem processing measurement report " + str(e))
def post_data(self, date_of_visit=None, finalized_at = None, visit_type=None, visit_type_type=None, visit_type_value=None, visit_type_abbrev=None, visit_location=None, specialty=None, specialty_type=None, specialty_value=None, specialty_abbrev=None, signed_at=None, provider_name=None, provider_institution=None, chief_complaint=None, content=None): """ SZ: More error checking needs to be performed in this method """ if date_of_visit: date_of_visit = iso8601.parse_utc_date(date_of_visit) if finalized_at: finalized_at = iso8601.parse_utc_date(finalized_at) if signed_at: signed_at = iso8601.parse_utc_date(signed_at) try: simple_clinical_note = SimpleClinicalNote.objects.create( date_of_visit=date_of_visit, finalized_at = finalized_at, visit_type=visit_type, visit_type_type=visit_type_type, visit_type_value=visit_type_value, visit_type_abbrev=visit_type_abbrev, visit_location=visit_location, specialty=specialty, specialty_type=specialty_type, specialty_value=specialty_value, specialty_abbrev=specialty_abbrev, signed_at=signed_at, provider_name=provider_name, provider_institution=provider_institution, chief_complaint=chief_complaint, content=content) return simple_clinical_note except Exception, e: raise ValueError("problem processing clinical note report " + str(e))
def from_xml(klass, xml): attrs = {} _tag = lambda tag_name: "{%s}%s"%("http://indivo.org/vocab/xml/documents#", tag_name) # build etree try: root = etree.XML(xml) except Exception as e: raise ValueError("Input document didn't parse as XML, error was: %s"%(str(e))) # validate XML try: with open(os.path.join(settings.APP_HOME, 'indivo/schemas/data/core/demographics/schema.xsd'), 'r') as schema_file: schema = etree.XMLSchema(etree.parse(schema_file)) schema.assertValid(root) except etree.DocumentInvalid as e: raise ValueError("Input document didn't validate, error was: %s"%(str(e))) # parse XML attrs['bday'] = parse_utc_date(root.findtext(_tag('dateOfBirth'))) attrs['gender'] = root.findtext(_tag('gender')) attrs['email'] = root.findtext(_tag('email')) attrs['ethnicity'] = root.findtext(_tag('ethnicity')) attrs['race'] = root.findtext(_tag('race')) attrs['preferred_language'] = root.findtext(_tag('preferredLanguage')) nameElement = root.find(_tag('Name')) attrs['name_family'] = nameElement.findtext(_tag('familyName')) attrs['name_given'] = nameElement.findtext(_tag('givenName')) attrs['name_middle'] = nameElement.findtext(_tag('middleName')) attrs['name_prefix'] = nameElement.findtext(_tag('prefix')) attrs['name_suffix'] = nameElement.findtext(_tag('suffix')) telephoneElements = root.findall(_tag('Telephone')) if len(telephoneElements) > 0: tel_1 = telephoneElements[0] attrs['tel_1_type'] = tel_1.findtext(_tag('type')) attrs['tel_1_number'] = tel_1.findtext(_tag('number')) attrs['tel_1_preferred_p'] = 'false' != tel_1.findtext(_tag('preferred')) if len(telephoneElements) > 1: tel_2 = telephoneElements[1] attrs['tel_2_type'] = tel_2.findtext(_tag('type')) attrs['tel_2_number'] = tel_2.findtext(_tag('number')) attrs['tel_2_preferred_p'] = 'false' != tel_2.findtext(_tag('preferred')) addressElement = root.find(_tag('Address')) if addressElement is not None: attrs['adr_country'] = addressElement.findtext(_tag('country')) attrs['adr_city'] = addressElement.findtext(_tag('city')) attrs['adr_postalcode'] = addressElement.findtext(_tag('postalCode')) attrs['adr_region'] = addressElement.findtext(_tag('region')) attrs['adr_street'] = addressElement.findtext(_tag('street')) return klass(**attrs)
def post_data(self, date_measured=None, name=None, date_measured_end=None, name_type=None, name_value=None, name_abbrev=None, value=None, unit=None, unit_type=None, unit_value=None, unit_abbrev=None, site=None, position=None, comments=None): """ SZ: More error checking needs to be performed in this method """ if date_measured: date_measured = iso8601.parse_utc_date(date_measured) if date_measured_end: date_measured_end = iso8601.parse_utc_date(date_measured_end) try: vitals_obj = Vitals.objects.create( date_measured=date_measured, name=name, date_measured_end=date_measured_end, name_type=name_type, name_value=name_value, name_abbrev=name_abbrev, value=value, unit=unit, unit_type=unit_type, unit_value=unit_value, unit_abbrev=unit_abbrev, site=site, position=position, comments=comments) return vitals_obj except Exception, e: raise ValueError("problem processing vitals report " + str(e))
def surl_verify(request): """Verifies a signed URL The URL should contain a bunch of GET parameters, including - surl_timestamp - surl_token - surl_sig which are used to verify the rest of the URL """ OK = HttpResponse("<result>ok</result>", mimetype="application/xml") # May want to add more explanation here OLD = HttpResponse("<result>old</result>", mimetype="application/xml") MISMATCH = HttpResponse("<result>mismatch</result>", mimetype="application/xml") url = request.GET["url"] parsed_url = urlparse.urlparse(url) query = urlparse.parse_qs(parsed_url.query) # check timestamp (cheapest thing to check, we check it first) url_timestamp = iso8601.parse_utc_date(query["surl_timestamp"][0]) if (datetime.datetime.utcnow() - url_timestamp) > datetime.timedelta(hours=1): return OLD # generate the secret that should be used here try: token = AccessToken.objects.get(token=query["surl_token"][0]) except AccessToken.DoesNotExist: return MISMATCH # compute the surl secret # the string conversion on the secret is required because of a python 2.6 bug secret = base64.b64encode(hmac.new(str(token.token_secret), "SURL-SECRET", hashlib.sha1).digest()) # extract the signature surl_sig = query["surl_sig"][0] # remove the signature from the URL to verify the rest of it # technically this means the signature can be inserted in the middle of the URL, # but we'll live with that for now, it shouldn't present a problem url_without_sig = url.replace("&%s" % urllib.urlencode({"surl_sig": surl_sig}), "") expected_signature = base64.b64encode(hmac.new(secret, url_without_sig, hashlib.sha1).digest()) if expected_signature == surl_sig: return OK else: return MISMATCH
def post_data(self, date_administered=None, administered_by=None, vaccine_type=None, vaccine_type_type=None, vaccine_type_value=None, vaccine_type_abbrev=None, vaccine_manufacturer=None, vaccine_lot=None, vaccine_expiration=None, sequence=None, anatomic_surface=None, anatomic_surface_type=None, anatomic_surface_value=None, anatomic_surface_abbrev=None, adverse_event=None): """ SZ: More error checking needs to be performed in this method """ if date_administered: date_administered = iso8601.parse_utc_date(date_administered) try: immunization_obj = Immunization.objects.create( date_administered=date_administered, administered_by=administered_by, vaccine_type=vaccine_type, vaccine_type_type=vaccine_type_type, vaccine_type_value=vaccine_type_value, vaccine_type_abbrev=vaccine_type_abbrev, vaccine_manufacturer=vaccine_manufacturer, vaccine_lot=vaccine_lot, vaccine_expiration=vaccine_expiration, sequence=sequence, anatomic_surface=anatomic_surface, anatomic_surface_type=anatomic_surface_type, anatomic_surface_value=anatomic_surface_value, anatomic_surface_abbrev=anatomic_surface_abbrev, adverse_event=adverse_event) return immunization_obj except Exception, e: raise ValueError("problem processing immunization report " + str(e))
def test_get_connect_credentials(self): # Test a valid call url = '/accounts/%s/apps/%s/connect_credentials'%(self.account.email, self.pha.email) data = {'record_id': self.record.id} response = self.client.post(url, data=urlencode(data), content_type='application/x-www-form-urlencoded') self.assertEqual(response.status_code, 200) data = etree.XML(response.content) self.assertEqual(self.pha.email, data.find('App').get('id', None)) self.assertEqual(settings.SITE_URL_PREFIX, data.findtext('APIBase')) ct = data.findtext('ConnectToken') cs = data.findtext('ConnectSecret') self.assertNotRaises(Exception, AccessToken.objects.get, token=ct, token_secret=cs, connect_auth_p=True) rt = data.findtext('RESTToken') rs = data.findtext('RESTSecret') self.assertNotRaises(Exception, AccessToken.objects.get, token=rt, token_secret=rs, connect_auth_p=False) db_rt = AccessToken.objects.get(token=rt) self.assertEqual(db_rt.expires_at, iso8601.parse_utc_date(data.findtext('ExpiresAt'))) # Get a 404 for invalid accounts, apps, and records url = '/accounts/%s/apps/%s/connect_credentials'%('BOGUS_ACCOUNT', self.pha.email) data = {'record_id': self.record.id} response = self.client.post(url, data=urlencode(data), content_type='application/x-www-form-urlencoded') self.assertEqual(response.status_code, 404) url = '/accounts/%s/apps/%s/connect_credentials'%(self.account.email, 'BOGUS_APP') data = {'record_id': self.record.id} response = self.client.post(url, data=urlencode(data), content_type='application/x-www-form-urlencoded') self.assertEqual(response.status_code, 404) url = '/accounts/%s/apps/%s/connect_credentials'%(self.account.email, self.pha.email) data = {'record_id': 'BOGUS_RECORD'} response = self.client.post(url, data=urlencode(data), content_type='application/x-www-form-urlencoded') self.assertEqual(response.status_code, 404)
def post_data(self, date_measured=None, name=None, name_type=None, name_value=None, name_abbrev=None, value=None, unit=None, unit_type=None, unit_value=None, unit_abbrev=None, site=None, position=None, comments=None): """ SZ: More error checking needs to be performed in this method """ if date_measured: date_measured = iso8601.parse_utc_date(date_measured) try: vitals_obj = Vitals.objects.create(date_measured=date_measured, name=name, name_type=name_type, name_value=name_value, name_abbrev=name_abbrev, value=value, unit=unit, unit_type=unit_type, unit_value=unit_value, unit_abbrev=unit_abbrev, site=site, position=position, comments=comments) return vitals_obj except Exception, e: raise ValueError("problem processing vitals report " + str(e))
def post_data(self, date_diagnosed=None, diagnosed_by=None, allergen_type=None, allergen_type_type=None, allergen_type_value=None, allergen_type_abbrev=None, allergen_name=None, allergen_name_type=None, allergen_name_value=None, allergen_name_abbrev=None, reaction=None, specifics=None): """ SZ: More error checking needs to be performed in this method """ if date_diagnosed: date_diagnosed = iso8601.parse_utc_date(date_diagnosed) try: allergy_obj = Allergy.objects.create( date_diagnosed=date_diagnosed, diagnosed_by=diagnosed_by, allergen_type=allergen_type, allergen_type_type=allergen_type_type, allergen_type_value=allergen_type_value, allergen_type_abbrev=allergen_type_abbrev, allergen_name=allergen_name, allergen_name_type=allergen_name_type, allergen_name_value=allergen_name_value, allergen_name_abbrev=allergen_name_abbrev, reaction=reaction, specifics=specifics) return allergy_obj except Exception, e: raise ValueError("problem processing allergy report " + str(e))
def post_data(self, date_measured, lab_type=None, lab_name=None, lab_address=None, lab_comments=None, first_panel_name=None, first_lab_test_name=None, first_lab_test_value=None, normal_range_minimum=None, normal_range_maximum=None, non_critical_range_minimum=None, non_critical_range_maximum=None): """ SZ: More error checking needs to be performed in this method """ if date_measured: date_measured = iso8601.parse_utc_date(date_measured) try: lab_obj = Lab.objects.create( date_measured=date_measured, lab_type=lab_type, lab_name=lab_name, lab_address=lab_address, lab_comments=lab_comments, first_panel_name=first_panel_name, first_lab_test_name=first_lab_test_name, first_lab_test_value=first_lab_test_value, normal_range_minimum=normal_range_minimum, normal_range_maximum=normal_range_maximum, non_critical_range_minimum=non_critical_range_minimum, non_critical_range_maximum=non_critical_range_maximum) return lab_obj except Exception, e: raise ValueError("problem processing lab report " + str(e))
def test_get_output(self): output_objects = [obj for obj in self.instance.get_output()] self.assertEqual(len(output_objects), 4) # Three models in the definition med_obj = scrip_obj = None fill_objs = [] for obj in output_objects: klass_name = obj.__class__.__name__ if klass_name == 'TestMedication2': med_obj = obj elif klass_name == 'TestPrescription2': scrip_obj = obj elif klass_name == 'TestFill2': fill_objs.append(obj) else: self.fail( 'SDMX Document parsing produced an instance of an invalid class %s' % klass_name) if not med_obj: self.fail( 'SDMX Document parsing did not produce an instance of TestMedication2' ) if not scrip_obj: self.fail( 'SDMX Document parsing did not produce an instance of TestPrescription2' ) if not fill_objs or len(fill_objs) != 2: self.fail( 'SDMX Document parsing did not produce two instances of TestFill2' ) # Make sure the testmedication2 object parsed as expected med_expected_fields = { 'name': 'ibuprofen', 'date_started': iso8601.parse_utc_date('2010-10-01T00:00:00Z'), 'date_stopped': iso8601.parse_utc_date('2010-10-31T00:00:00Z'), 'brand_name': 'Advil', 'route': 'Oral', } self.check_object_fields(med_obj, med_expected_fields) # The 'prescription' field should be a OneToOne field, pointing at the prescription object self.assertEqual(med_obj.prescription, scrip_obj) # The 'fills' field should be a manager for fills objects # We can't test whether they match up because we aren't saving them to the database # So currently 'med_obj.fills' will raise a DoesNotExist exception # Make sure the testprescription2 class parsed as expected scrip_expected_fields = { 'prescribed_by_name': 'Kenneth D. Mandl', 'prescribed_by_institution': 'Children\'s Hospital Boston', 'prescribed_on': iso8601.parse_utc_date('2010-09-30T00:00:00Z'), 'prescribed_stop_on': iso8601.parse_utc_date('2010-10-31T00:00:00Z'), } self.check_object_fields(scrip_obj, scrip_expected_fields) # The TestPrescription2 object should have a 'testmedication2' field pointing to the Medication class # (the reverse link of the OneToOne from the TestMedication2) # We can't test this because we aren't saving object to the database. # If we were, we should test this with: self.assertEqual(scrip_obj.testmedication2, med_obj) # Make sure the testfill2 class parsed as expected fill_expected_fields = { 'supply_days': 15, 'filled_at_name': 'CVS', } fill_dates = set([ iso8601.parse_utc_date('2010-10-01T00:00:00Z'), iso8601.parse_utc_date('2010-10-16T00:00:00Z') ]) for fill_obj in fill_objs: self.check_object_fields(fill_obj, fill_expected_fields) self.assertEqual(fill_obj.testmedication2, med_obj) self.assertEqual(set([o.date_filled for o in fill_objs]), fill_dates)
def test_get_output(self): output_objects = [obj for obj in self.instance.get_output()] self.assertEqual(len(output_objects), 4) # Three models in the definition med_obj = scrip_obj = None fill_objs = [] for obj in output_objects: klass_name = obj.__class__.__name__ if klass_name == 'TestMedication2': med_obj = obj elif klass_name == 'TestPrescription2': scrip_obj = obj elif klass_name == 'TestFill2': fill_objs.append(obj) else: self.fail('SDMX Document parsing produced an instance of an invalid class %s'%klass_name) if not med_obj: self.fail('SDMX Document parsing did not produce an instance of TestMedication2') if not scrip_obj: self.fail('SDMX Document parsing did not produce an instance of TestPrescription2') if not fill_objs or len(fill_objs) != 2: self.fail('SDMX Document parsing did not produce two instances of TestFill2') # Make sure the testmedication2 object parsed as expected med_expected_fields = { 'name': 'ibuprofen', 'date_started': iso8601.parse_utc_date('2010-10-01T00:00:00Z'), 'date_stopped': iso8601.parse_utc_date('2010-10-31T00:00:00Z'), 'brand_name': 'Advil', 'route': 'Oral', } self.check_object_fields(med_obj, med_expected_fields) # The 'prescription' field should be a OneToOne field, pointing at the prescription object self.assertEqual(med_obj.prescription, scrip_obj) # The 'fills' field should be a manager for fills objects # We can't test whether they match up because we aren't saving them to the database # So currently 'med_obj.fills' will raise a DoesNotExist exception # Make sure the testprescription2 class parsed as expected scrip_expected_fields = { 'prescribed_by_name': 'Kenneth D. Mandl', 'prescribed_by_institution': 'Children\'s Hospital Boston', 'prescribed_on': iso8601.parse_utc_date('2010-09-30T00:00:00Z'), 'prescribed_stop_on': iso8601.parse_utc_date('2010-10-31T00:00:00Z'), } self.check_object_fields(scrip_obj, scrip_expected_fields) # The TestPrescription2 object should have a 'testmedication2' field pointing to the Medication class # (the reverse link of the OneToOne from the TestMedication2) # We can't test this because we aren't saving object to the database. # If we were, we should test this with: self.assertEqual(scrip_obj.testmedication2, med_obj) # Make sure the testfill2 class parsed as expected fill_expected_fields = { 'supply_days': 15, 'filled_at_name': 'CVS', } fill_dates = set([iso8601.parse_utc_date('2010-10-01T00:00:00Z'), iso8601.parse_utc_date('2010-10-16T00:00:00Z')]) for fill_obj in fill_objs: self.check_object_fields(fill_obj, fill_expected_fields) self.assertEqual(fill_obj.testmedication2, med_obj) self.assertEqual(set([o.date_filled for o in fill_objs]), fill_dates)
def from_xml(klass, xml): attrs = {} _tag = lambda tag_name: "{%s}%s" % ( "http://indivo.org/vocab/xml/documents#", tag_name) # build etree try: root = etree.XML(xml) except Exception as e: raise ValueError( "Input document didn't parse as XML, error was: %s" % (str(e))) # validate XML try: with open( os.path.join( settings.APP_HOME, 'indivo/schemas/data/core/demographics/schema.xsd'), 'r') as schema_file: schema = etree.XMLSchema(etree.parse(schema_file)) schema.assertValid(root) except etree.DocumentInvalid as e: raise ValueError("Input document didn't validate, error was: %s" % (str(e))) # parse XML attrs['bday'] = parse_utc_date(root.findtext(_tag('dateOfBirth'))) attrs['gender'] = root.findtext(_tag('gender')) attrs['email'] = root.findtext(_tag('email')) attrs['ethnicity'] = root.findtext(_tag('ethnicity')) attrs['race'] = root.findtext(_tag('race')) attrs['preferred_language'] = root.findtext(_tag('preferredLanguage')) nameElement = root.find(_tag('Name')) attrs['name_family'] = nameElement.findtext(_tag('familyName')) attrs['name_given'] = nameElement.findtext(_tag('givenName')) attrs['name_middle'] = nameElement.findtext(_tag('middleName')) attrs['name_prefix'] = nameElement.findtext(_tag('prefix')) attrs['name_suffix'] = nameElement.findtext(_tag('suffix')) telephoneElements = root.findall(_tag('Telephone')) if len(telephoneElements) > 0: tel_1 = telephoneElements[0] attrs['tel_1_type'] = tel_1.findtext(_tag('type')) attrs['tel_1_number'] = tel_1.findtext(_tag('number')) attrs['tel_1_preferred_p'] = 'false' != tel_1.findtext( _tag('preferred')) if len(telephoneElements) > 1: tel_2 = telephoneElements[1] attrs['tel_2_type'] = tel_2.findtext(_tag('type')) attrs['tel_2_number'] = tel_2.findtext(_tag('number')) attrs['tel_2_preferred_p'] = 'false' != tel_2.findtext( _tag('preferred')) addressElement = root.find(_tag('Address')) if addressElement is not None: attrs['adr_country'] = addressElement.findtext(_tag('country')) attrs['adr_city'] = addressElement.findtext(_tag('city')) attrs['adr_postalcode'] = addressElement.findtext( _tag('postalCode')) attrs['adr_region'] = addressElement.findtext(_tag('region')) attrs['adr_street'] = addressElement.findtext(_tag('street')) return klass(**attrs)
def parse_date_range(value): field, start_date, end_date = value.split('*') start_date = None if start_date == '' else iso8601.parse_utc_date(start_date) end_date = None if end_date == '' else iso8601.parse_utc_date(end_date) return {'field':field, 'start_date':start_date, 'end_date':end_date}
def marsloader_func(request, *args, **kwargs): """MARS_loader (Modifying Arguments for the Result Set) adds arguments specifically meant to modify the result set (eg. limit, offset and order_by) 04-05-2011: Modified to Handle the New Query Interface New arguments are: group_by, aggregate_by, date_group, date_range, generic filters. Also: No longer checks that the URL ends in a '/'. We assume that if you didn't want to call this function, you wouldn't have decorated the view with it. """ check_safety() # This should be abstracted # StatusName 'active' should always be available arg_defaults = { 'limit': 100, 'offset': 0, 'order_by': '-%s'%(DEFAULT_ORDERBY) if not request.GET.has_key('aggregate_by') or not query_api_support else None, 'status': models.StatusName.objects.get(name='active'), } query_api_defaults = { 'group_by': None, 'aggregate_by': None, 'date_range': None, 'date_group': None, } # Every get paramater should be useful: otherwise we have to treat it as # an invalid filter new_args = copy.copy(kwargs) filters = {} for _arg, value in request.GET.iteritems(): arg = str(_arg) try: if arg == 'limit': new_args[arg] = int(value) elif arg == 'offset': new_args[arg] = int(value) elif arg == 'order_by': new_args[arg] = value elif arg == 'status': new_args[arg] = models.StatusName.objects.get(name=value) elif arg == 'group_by' and query_api_support: new_args[arg] = value elif arg == 'aggregate_by' and query_api_support: operator, field = value.split('*') field = None if field == '' else field new_args[arg] = {'operator':operator, 'field':field} elif arg == 'date_range' and query_api_support: field, start_date, end_date = value.split('*') start_date = None if start_date == '' else iso8601.parse_utc_date(start_date) end_date = None if end_date == '' else iso8601.parse_utc_date(end_date) new_args[arg] = {'field':field, 'start_date':start_date, 'end_date':end_date} elif arg == 'date_group' and query_api_support: field, time_incr = value.split('*') new_args[arg] = {'field':field, 'time_incr':time_incr} # We assume that all remaining parameters are field-specific query parameters # (i.e. 'lab_type=hematology') if this is a query_api call else: if query_api_support: # Don't do type-checking here: the individual report defines the types of filters filters[arg] = value except models.StatusName.DoesNotExist: raise Http404 except ValueError: return HttpResponseBadRequest('Argument %s must be formatted according to the Indivo Query API'%(arg)) if query_api_support: new_args['filters'] = filters # Add defaults for missing params for arg, default in arg_defaults.iteritems(): if not new_args.has_key(arg): new_args[arg] = default if query_api_support: for arg, default in query_api_defaults.iteritems(): if not new_args.has_key(arg): new_args[arg] = default # Check that the new arguments are all in func() if len(inspect.getargspec(func)) > 0: for new_arg in new_args.keys(): if new_arg not in inspect.getargspec(func)[0]: raise Exception("Missing arg " + new_arg + " in " + func.func_name) # call the view return func(request, **new_args)
def validateIso8601(self, datestring, accept_null = True): if not datestring and accept_null: return else: return iso8601.parse_utc_date(datestring)
def _parse_one(self, instance_etree, rel_parent_obj=None, rel_fieldname=None, rel_to_parent=False): """ Build one Django model instance. rel_parent_obj, rel_fieldname, and rel_to_parent, if provided, are instructions to set up a reference to the parent object. Rel_fieldname is the field on which to create the reference, and rel_on_parent indicates which direction the reference should go (child to parent for a manytomany relationship, parent to child for a onetoone relationship). Returns a tuple of (subdefs_to_parse, parsed_instance), where subdefs_to_parse is a list of subobjects that need parsing, and parsed_instance is an instance of the django.db.models.Model subclass we have just parsed. List elements of subdefs_to_parse are tuples of (instance_etree, rel_parent_obj, rel_fieldname, rel_to_parent), appropriate for passing back into this function. """ subobjs_found = [] subdefs_to_parse = [] fields = {} # Pull out our model's name first, so we can pass it into submodels as needed. model_name = instance_etree.get("name", None) if not model_name: raise SDMDataException("All SDM data instances must specify the model they belong to.") try: model_class = getattr(__import__("indivo.models", fromlist=[model_name]), model_name, None) except ImportError: model_class = None finally: if not model_class: raise SDMDataException("SDM model specified a non-existent data-model: %s" % model_name) for field_etree in instance_etree.findall("Field"): fieldname = field_etree.get("name", None) if not fieldname: raise SDMDataException("All SDM data fields must specify a fieldname.") if field_etree.find("Models") is not None: # OneToMany Field: we save the subobjects for later parsing. # We tell the subobject to add a reference to our instance on a field # named after the lowercase of our modelname. for subobject_etree in field_etree.find("Models").findall("Model"): subobjs_found.append((subobject_etree, model_name.lower(), True)) elif field_etree.find("Model") is not None: # OnetoOne Field: we save the subobject for later parsing. # We tell the subobject to add a reference from our instance to them subobjs_found.append((field_etree.find("Model"), fieldname, False)) else: # Simple Field: we validate the datatype, then add the data to our model # get the field definition on the class try: model_field = model_class._meta.get_field(fieldname) except FieldDoesNotExist: model_field = None if not model_field: raise SDMDataException("Non-existent data field: %s" % fieldname) raw_value = field_etree.text if not raw_value: fields[fieldname] = None else: # since everything is coming in as a string, try converting to native Django types if isinstance(model_field, models.DateField): try: value = iso8601.parse_utc_date(raw_value) except Exception as e: raise SDMDataException( "SDM data for field %s should have been an iso8601 datetime: got %s instead" % (fieldname, raw_value) ) elif isinstance(model_field, models.FloatField) and raw_value: try: value = float(raw_value) except Exception as e: raise SDMDataException( "SDM data for field %s should have been numeric: got %s instead" % (fieldname, raw_value) ) elif isinstance(model_field, models.BooleanField) or isinstance( model_field, models.NullBooleanField ): if raw_value.lower() == "true": value = True elif raw_value.lower() == "false": value = False elif raw_value == True or raw_value == False: value = raw_value else: raise SDMDataException( "SDM data for field %s should have been boolean: got %s instead" % (fieldname, raw_value) ) else: value = raw_value fields[fieldname] = value # Add a reference from us to them, if we were asked to. # We'll need to save the parent object first, so it has an ID if rel_parent_obj and rel_to_parent: if not rel_parent_obj.id: rel_parent_obj.save() fields[rel_fieldname] = rel_parent_obj # Now build the Django Model instance instance = model_class(**fields) # TODO: check for more efficient way than saving every time if not instance.id: instance.save() # Add a reference from them to us, if we were asked to. # We'll need to save ourselves first, so we have an ID. if rel_parent_obj and not rel_to_parent: setattr(rel_parent_obj, rel_fieldname, instance) # Add ourselves as the parent to all of our subinstances for subobj_etree, subobj_field, subobj_direction in subobjs_found: subdefs_to_parse.append((subobj_etree, instance, subobj_field, subobj_direction)) # And we're done! return (subdefs_to_parse, instance)
def _parse_one(self, instance_etree, rel_parent_obj=None, rel_fieldname=None, rel_to_parent=False): """ Build one Django model instance. rel_parent_obj, rel_fieldname, and rel_to_parent, if provided, are instructions to set up a reference to the parent object. Rel_fieldname is the field on which to create the reference, and rel_on_parent indicates which direction the reference should go (child to parent for a manytomany relationship, parent to child for a onetoone relationship). Returns a tuple of (subdefs_to_parse, parsed_instance), where subdefs_to_parse is a list of subobjects that need parsing, and parsed_instance is an instance of the django.db.models.Model subclass we have just parsed. List elements of subdefs_to_parse are tuples of (instance_etree, rel_parent_obj, rel_fieldname, rel_to_parent), appropriate for passing back into this function. """ subobjs_found = [] subdefs_to_parse = [] fields = {} # Pull out our model's name first, so we can pass it into submodels as needed. model_name = instance_etree.get('name', None) if not model_name: raise SDMDataException( "All SDM data instances must specify the model they belong to." ) try: model_class = getattr( __import__('indivo.models', fromlist=[model_name]), model_name, None) except ImportError: model_class = None finally: if not model_class: raise SDMDataException( "SDM model specified a non-existent data-model: %s" % model_name) for field_etree in instance_etree.findall('Field'): fieldname = field_etree.get('name', None) if not fieldname: raise SDMDataException( "All SDM data fields must specify a fieldname.") if field_etree.find('Models') is not None: # OneToMany Field: we save the subobjects for later parsing. # We tell the subobject to add a reference to our instance on a field # named after the lowercase of our modelname. for subobject_etree in field_etree.find('Models').findall( 'Model'): subobjs_found.append( (subobject_etree, model_name.lower(), True)) elif field_etree.find('Model') is not None: # OnetoOne Field: we save the subobject for later parsing. # We tell the subobject to add a reference from our instance to them subobjs_found.append( (field_etree.find('Model'), fieldname, False)) else: # Simple Field: we validate the datatype, then add the data to our model # get the field definition on the class try: model_field = model_class._meta.get_field(fieldname) except FieldDoesNotExist: model_field = None if not model_field: raise SDMDataException("Non-existent data field: %s" % fieldname) raw_value = field_etree.text if not raw_value: fields[fieldname] = None else: # since everything is coming in as a string, try converting to native Django types if isinstance(model_field, models.DateField): try: value = iso8601.parse_utc_date(raw_value) except Exception as e: raise SDMDataException( "SDM data for field %s should have been an iso8601 datetime: got %s instead" % (fieldname, raw_value)) elif isinstance(model_field, models.FloatField) and raw_value: try: value = float(raw_value) except Exception as e: raise SDMDataException( "SDM data for field %s should have been numeric: got %s instead" % (fieldname, raw_value)) elif isinstance(model_field, models.BooleanField) or isinstance( model_field, models.NullBooleanField): if raw_value.lower() == 'true': value = True elif raw_value.lower() == 'false': value = False elif raw_value == True or raw_value == False: value = raw_value else: raise SDMDataException( "SDM data for field %s should have been boolean: got %s instead" % (fieldname, raw_value)) else: value = raw_value fields[fieldname] = value # Add a reference from us to them, if we were asked to. # We'll need to save the parent object first, so it has an ID if rel_parent_obj and rel_to_parent: if not rel_parent_obj.id: rel_parent_obj.save() fields[rel_fieldname] = rel_parent_obj # Now build the Django Model instance instance = model_class(**fields) # TODO: check for more efficient way than saving every time if not instance.id: instance.save() # Add a reference from them to us, if we were asked to. # We'll need to save ourselves first, so we have an ID. if rel_parent_obj and not rel_to_parent: setattr(rel_parent_obj, rel_fieldname, instance) # Add ourselves as the parent to all of our subinstances for subobj_etree, subobj_field, subobj_direction in subobjs_found: subdefs_to_parse.append( (subobj_etree, instance, subobj_field, subobj_direction)) # And we're done! return (subdefs_to_parse, instance)
def post_data(self, date_started=None, date_stopped=None, name=None, name_type=None, name_value=None, name_abbrev=None, brand_name=None, brand_name_type=None, brand_name_value=None, brand_name_abbrev=None, dose_unit=None, dose_textvalue=None, dose_value=None, dose_unit_type=None, dose_unit_value=None, dose_unit_abbrev=None, route=None, route_type=None, route_value=None, route_abbrev=None, strength_value=None, strength_textvalue=None, strength_unit=None, strength_unit_type=None, strength_unit_value=None, strength_unit_abbrev=None, frequency=None, frequency_type=None, frequency_value=None, frequency_abbrev=None, prescribed_by_name=None, prescribed_by_institution=None, prescribed_on=None, prescribed_stop_on=None, dispense_as_written=None, prescription_duration=None, prescription_refill_info=None, prescription_instructions=None): """ SZ: More error checking needs to be performed in this method """ try: if date_started: date_started = iso8601.parse_utc_date(date_started) if date_stopped: date_stopped = iso8601.parse_utc_date(date_stopped) medication_obj = Medication.objects.create( date_started=date_started, date_stopped=date_stopped, name=name, name_type=name_type, name_value=name_value, name_abbrev=name_abbrev, brand_name=brand_name, brand_name_type=brand_name_type, brand_name_value=brand_name_value, brand_name_abbrev=brand_name_abbrev, dose_value=dose_value, dose_textvalue=dose_textvalue, dose_unit=dose_unit, dose_unit_type=dose_unit_type, dose_unit_value=dose_unit_value, dose_unit_abbrev=dose_unit_abbrev, route=route, route_type=route_type, route_value=route_value, route_abbrev=route_abbrev, strength_value=strength_value, strength_textvalue=strength_textvalue, strength_unit=strength_unit, strength_unit_type=strength_unit_type, strength_unit_value=strength_unit_value, strength_unit_abbrev=strength_unit_abbrev, frequency=frequency, frequency_type=frequency_type, frequency_value=frequency_value, frequency_abbrev=frequency_abbrev, prescribed_by_name=prescribed_by_name, prescribed_by_institution=prescribed_by_institution, prescribed_on=prescribed_on, prescribed_stop_on=prescribed_stop_on, dispense_as_written=dispense_as_written, prescription_duration=prescription_duration, prescription_refill_info=prescription_refill_info, prescription_instructions=prescription_instructions) return medication_obj except Exception, e: raise ValueError("problem processing medication report " + str(e))
def post_data(self, date_started=None, date_stopped=None, name=None, name_type=None, name_value=None, name_abbrev=None, brand_name=None, brand_name_type=None, brand_name_value=None, brand_name_abbrev=None, dose_unit=None, dose_textvalue=None, dose_value=None, dose_unit_type=None, dose_unit_value=None, dose_unit_abbrev=None, route=None, route_type=None, route_value=None, route_abbrev=None, strength_value=None, strength_textvalue=None, strength_unit=None, strength_unit_type=None, strength_unit_value=None, strength_unit_abbrev=None, frequency=None, frequency_type=None, frequency_value=None, frequency_abbrev=None, prescribed_by_name=None, prescribed_by_institution=None, prescribed_on=None, prescribed_stop_on=None, dispense_as_written=None, prescription_duration=None, prescription_refill_info=None, prescription_instructions=None): """ SZ: More error checking needs to be performed in this method """ try: if date_started: date_started = iso8601.parse_utc_date(date_started) if date_stopped: date_stopped = iso8601.parse_utc_date(date_stopped) medication_obj = Medication.objects.create( date_started= date_started, date_stopped= date_stopped, name=name, name_type=name_type, name_value=name_value, name_abbrev=name_abbrev, brand_name=brand_name, brand_name_type=brand_name_type, brand_name_value=brand_name_value, brand_name_abbrev=brand_name_abbrev, dose_value=dose_value, dose_textvalue=dose_textvalue, dose_unit=dose_unit, dose_unit_type=dose_unit_type, dose_unit_value=dose_unit_value, dose_unit_abbrev=dose_unit_abbrev, route=route, route_type=route_type, route_value=route_value, route_abbrev=route_abbrev, strength_value=strength_value, strength_textvalue=strength_textvalue, strength_unit=strength_unit, strength_unit_type=strength_unit_type, strength_unit_value=strength_unit_value, strength_unit_abbrev=strength_unit_abbrev, frequency=frequency, frequency_type=frequency_type, frequency_value=frequency_value, frequency_abbrev=frequency_abbrev, prescribed_by_name=prescribed_by_name, prescribed_by_institution=prescribed_by_institution, prescribed_on=prescribed_on, prescribed_stop_on=prescribed_stop_on, dispense_as_written=dispense_as_written, prescription_duration=prescription_duration, prescription_refill_info=prescription_refill_info, prescription_instructions=prescription_instructions) return medication_obj except Exception, e: raise ValueError("problem processing medication report " + str(e))