def _parse_value(self, prop, property_type, value): if value is None: return None try: if property_type == PropertyType.DATE: return api_util.parse_date(value).date() elif property_type == PropertyType.DATETIME: return api_util.parse_date(value) elif property_type == PropertyType.ENUM: return prop.property.columns[0].type.enum_type(value) elif property_type == PropertyType.INTEGER: return int(value) else: return value except ValueError: raise BadRequest('Invalid value for property of type %s: %r.' % (property_type, value))
def _parse_date(params, key): try: return parse_date(params[key]) except ValueError: raise BadRequest('Invalid {key} date: {value}'.format( key=key, value=params[key])) except KeyError: raise BadRequest('Missing {key}'.format(key=key))
def insert_with_session(self, session, obj): is_amendment = False obj.logPosition = LogPosition() obj.final = True obj.created = clock.CLOCK.now() resource_json = json.loads(obj.resource) finalized_date = resource_json['entry'][0]['resource'].get('date') if finalized_date: obj.finalized = parse_date(finalized_date) for extension in resource_json['entry'][0]['resource'].get( 'extension', []): url = extension.get('url') if url not in _ALL_EXTENSIONS: logging.info( 'Ignoring unsupported extension for PhysicalMeasurements: %r. Expected one of: %s', url, _ALL_EXTENSIONS) continue if url == _AMENDMENT_URL: self._update_amended(obj, extension, url, session) is_amendment = True break participant_summary = self._update_participant_summary( session, obj, is_amendment) existing_measurements = (session.query(PhysicalMeasurements).filter( PhysicalMeasurements.participantId == obj.participantId).all()) if existing_measurements: new_dict = self._measurements_as_dict(obj) for measurements in existing_measurements: if self._measurements_as_dict(measurements) == new_dict: # If there are already measurements that look exactly like this, return them # without inserting new measurements. return measurements PhysicalMeasurementsDao.set_measurement_ids(obj) inserted_obj = super(PhysicalMeasurementsDao, self).insert_with_session(session, obj) if not is_amendment: # Amendments aren't expected to have site ID extensions. if participant_summary.biospecimenCollectedSiteId is None: ParticipantDao().add_missing_hpo_from_site( session, inserted_obj.participantId, inserted_obj.finalizedSiteId) # Flush to assign an ID to the measurements, as the client doesn't provide one. session.flush() # Update the resource to contain the ID. resource_json['id'] = str(obj.physicalMeasurementsId) obj.resource = json.dumps(resource_json) return obj
def test_from_json(self): ParticipantSummaryDao().insert(self.participant_summary(self.participant)) order_json = load_biobank_order_json(self.participant.participantId) order = BiobankOrderDao().from_client_json(order_json, participant_id=self.participant.participantId) self.assertEquals(1, order.sourceSiteId) self.assertEquals('*****@*****.**', order.sourceUsername) self.assertEquals(1, order.collectedSiteId) self.assertEquals('*****@*****.**', order.collectedUsername) self.assertEquals(1, order.processedSiteId) self.assertEquals('*****@*****.**', order.processedUsername) self.assertEquals(2, order.finalizedSiteId) self.assertEquals('*****@*****.**', order.finalizedUsername) # testing finalized_time samples_finalized_time = None for sample in order_json['samples']: samples_finalized_time = parse_date(sample['finalized']) break self.assertEquals(samples_finalized_time, order.finalizedTime)
def put(self, key=config.CONFIG_SINGLETON_KEY): model_key = ndb.Key(config.Configuration, key) old_model = model_key.get() if not old_model: raise NotFound('{} with key {} does not exist'.format('Configuration', key)) # the history mechanism doesn't work unless we make a copy. So a put is always a clone, never # an actual update. model = config.Configuration(**old_model.to_dict()) model.key = model_key model.configuration = request.get_json(force=True) self.validate(model) date = None if config.getSettingJson(config.ALLOW_NONPROD_REQUESTS, False): date = request.headers.get('x-pretend-date', None) if date is not None: date = parse_date(date) client_id = app_util.get_oauth_id() config.store(model, date=date, client_id=client_id) return model.configuration
def make_query_filter(self, field_name, value): """Attempts to make a query filter for the model property with the specified name, matching the specified value. If no such property exists, None is returned. """ prop = getattr(self.model_type, field_name, None) if prop: property_type = PROPERTY_TYPE_MAP.get(prop.__class__.__name__) filter_value = None try: if property_type == PropertyType.DATE: filter_value = api_util.parse_date(value) elif property_type == PropertyType.ENUM: filter_value = prop._enum_type(value) elif property_type == PropertyType.INTEGER: filter_value = int(value) else: filter_value = value except ValueError: raise BadRequest("Invalid value for %s of type %s: %s" % (field_name, property_type, value)) return FieldFilter(field_name, Operator.EQUALS, filter_value) else: return None
def build_expected_resource_type_data(self, resource_type): """Helper function to build the data we are expecting from the test-data file.""" fhir_resource = SimpleFhirR4Reader(resource_type) test_fields = {} fhir_address = {} # fields to test with the same structure in both payloads fhir_device = fhir_resource.contained.get(resourceType="Device") test_fields.update({ 'itemName': fhir_device.deviceName.get(type="manufacturer-name").name, 'orderType': fhir_resource.extension.get(url=DV_ORDER_URL).valueString }) # add the fields to test for each resource type (SupplyRequest, SupplyDelivery) if resource_type == self.post_request: test_fields.update({ 'order_id': int( fhir_resource.identifier.get(system=DV_FHIR_URL + "orderId").value), 'supplier': fhir_resource.contained.get(resourceType="Organization").id, 'supplierStatus': fhir_resource.extension.get( url=DV_FULFILLMENT_URL).valueString, 'itemQuantity': fhir_resource.quantity.value, 'itemSKUCode': fhir_device.identifier.get(system=DV_FHIR_URL + "SKU").value, }) # Address Handling fhir_address = fhir_resource.contained.get( resourceType="Patient").address[0] if resource_type == self.post_delivery: test_fields.update({ 'order_id': int(fhir_resource.basedOn[0].identifier.value), 'shipmentEstArrival': parse_date( fhir_resource.extension.get( url=DV_FHIR_URL + "expected-delivery-date").valueDateTime), 'shipmentCarrier': fhir_resource.extension.get(url=DV_FHIR_URL + "carrier").valueString, 'trackingId': fhir_resource.identifier.get(system=DV_FHIR_URL + "trackingId").value, 'shipmentLastUpdate': parse_date(fhir_resource.occurrenceDateTime), }) # Address Handling fhir_address = fhir_resource.contained.get( resourceType="Location").get("address") address_fields = { "streetAddress1": fhir_address.line[0], "streetAddress2": '', "city": fhir_address.city, "stateId": get_code_id(fhir_address, self.code_dao, "state", "State_"), "zipCode": fhir_address.postalCode, } # street address 2 if len(list(fhir_address.line)) > 1: address_fields['streetAddress2'] = fhir_address.line[1] test_fields.update(address_fields) Supply = namedtuple('Supply', test_fields.keys()) expected_data = Supply(**test_fields) return expected_data
def get_config_by_date(self, key, date): result = config.get_config_that_was_active_at( key, api_util.parse_date(date)) return self.make_response_for_resource(self.dao.to_json(result))
def get(self, key=config.CONFIG_SINGLETON_KEY): date = request.args.get('date') if date is not None: date = parse_date(date) model = config.load(key, date=date) return model.configuration
def from_client_json(self, resource_json, id_=None, expected_version=None, participant_id=None, client_id=None): #pylint: disable=unused-argument """Initial loading of the DV order table does not include all attributes.""" fhir_resource = SimpleFhirR4Reader(resource_json) order = BiobankDVOrder(participantId=participant_id) order.participantId = participant_id if resource_json['resourceType'].lower() == 'supplydelivery': order.order_id = int(fhir_resource.basedOn[0].identifier.value) existing_obj = self.get(self.get_id(order)) if not existing_obj: raise NotFound('existing order record not found') # handling of biobankStatus from Mayolink API try: existing_obj.biobankStatus = resource_json['biobankStatus'] except KeyError: # resource will only have biobankStatus on a PUT pass existing_obj.shipmentStatus = self._enumerate_order_tracking_status( fhir_resource.extension.get(url=DV_FHIR_URL + 'tracking-status').valueString) existing_obj.shipmentCarrier = fhir_resource.extension.get( url=DV_FHIR_URL + 'carrier').valueString # shipmentEstArrival # The fhir_resource.get() method # will raise an exception on "expected-delivery-date" # if the resource doesn't have that path delivery_date_url = [ extension.url for extension in fhir_resource["extension"] if extension.url == DV_FHIR_URL + "expected-delivery-date" ] if delivery_date_url: existing_obj.shipmentEstArrival = parse_date( fhir_resource.extension.get( url=DV_FHIR_URL + "expected-delivery-date").valueDateTime) existing_obj.trackingId = fhir_resource.identifier.get( system=DV_FHIR_URL + 'trackingId').value # USPS status existing_obj.orderStatus = self._enumerate_order_shipping_status( fhir_resource.status) # USPS status time existing_obj.shipmentLastUpdate = parse_date( fhir_resource.occurrenceDateTime) order_address = fhir_resource.contained.get( resourceType='Location').get('address') address_use = fhir_resource.contained.get( resourceType='Location').get('address').get('use') order_address.stateId = get_code_id(order_address, self.code_dao, 'state', 'State_') existing_obj.address = { 'city': existing_obj.city, 'state': existing_obj.stateId, 'postalCode': existing_obj.zipCode, 'line': [existing_obj.streetAddress1] } if existing_obj.streetAddress2 is not None and existing_obj.streetAddress2 != '': existing_obj.address['line'].append( existing_obj.streetAddress2) if address_use.lower() == 'home': existing_obj.city = order_address.city existing_obj.stateId = order_address.stateId existing_obj.streetAddress1 = order_address.line[0] existing_obj.zipCode = order_address.postalCode if len(order_address._obj['line'][0]) > 1: try: existing_obj.streetAddress2 = order_address._obj[ 'line'][1] except IndexError: pass elif address_use.lower() == 'work': existing_obj.biobankCity = order_address.city existing_obj.biobankStateId = order_address.stateId existing_obj.biobankStreetAddress1 = order_address.line[0] existing_obj.biobankZipCode = order_address.postalCode if hasattr(fhir_resource, 'biobankTrackingId'): existing_obj.biobankTrackingId = fhir_resource.biobankTrackingId existing_obj.biobankReceived = parse_date( fhir_resource.received) return existing_obj if resource_json['resourceType'].lower() == 'supplyrequest': order.order_id = int( fhir_resource.identifier.get(system=DV_FHIR_URL + 'orderId').value) if id_ and int(id_) != order.order_id: raise Conflict( 'url order id param does not match document order id') if hasattr(fhir_resource, 'authoredOn'): order.order_date = parse_date(fhir_resource.authoredOn) order.supplier = fhir_resource.contained.get( resourceType='Organization').id order.created = clock.CLOCK.now() order.supplierStatus = fhir_resource.extension.get( url=DV_FULFILLMENT_URL).valueString fhir_device = fhir_resource.contained.get(resourceType='Device') order.itemName = fhir_device.deviceName.get( type='manufacturer-name').name order.itemSKUCode = fhir_device.identifier.get(system=DV_FHIR_URL + 'SKU').value order.itemQuantity = fhir_resource.quantity.value fhir_patient = fhir_resource.contained.get(resourceType='Patient') fhir_address = fhir_patient.address[0] order.streetAddress1 = fhir_address.line[0] order.streetAddress2 = '\n'.join(fhir_address.line[1:]) order.city = fhir_address.city order.stateId = get_code_id(fhir_address, self.code_dao, 'state', 'State_') order.zipCode = fhir_address.postalCode order.orderType = fhir_resource.extension.get( url=DV_ORDER_URL).valueString if id_ is None: order.version = 1 else: # A put request may add new attributes existing_obj = self.get(self.get_id(order)) if not existing_obj: raise NotFound('existing order record not found') order.id = existing_obj.id order.version = expected_version order.biobankStatus = fhir_resource.biobankStatus if hasattr( fhir_resource, 'biobankStatus') else None try: order.barcode = fhir_resource.extension.get( url=DV_BARCODE_URL).valueString except ValueError: order.barcode = None return order
def _consider_fake_date(): if config.getSettingJson(config.ALLOW_NONPROD_REQUESTS, False): date = request.headers.get('x-pretend-date', None) if date: return api_util.parse_date(date) return None