def make_fhir_bundle_entry( resource_type_url: str, identifier: Identifier, resource: Dict, identifier_is_list: bool = True, ) -> Dict: """ Builds a FHIR BundleEntry, as a JSON dict. This also takes care of the identifier, by ensuring (a) that the resource is labelled with the identifier, and (b) that the BundleEntryRequest has an ifNoneExist condition referring to that identifier. """ if Fc.IDENTIFIER in resource: log.warning(f"Duplication: {Fc.IDENTIFIER!r} specified in resource " f"but would be auto-added by make_fhir_bundle_entry()") if identifier_is_list: # Some, like Observation, Patient, and Questionnaire, need lists here. resource[Fc.IDENTIFIER] = [identifier.as_json()] else: # Others, like QuestionnaireResponse, don't. resource[Fc.IDENTIFIER] = identifier.as_json() bundle_request = BundleEntryRequest( jsondict={ Fc.METHOD: HttpMethod.POST, Fc.URL: resource_type_url, Fc.IF_NONE_EXIST: fhir_reference_from_identifier(identifier), # "If this resource doesn't exist, as determined by this # identifier, then create it:" # https://www.hl7.org/fhir/http.html#ccreate }) return BundleEntry(jsondict={ Fc.REQUEST: bundle_request.as_json(), Fc.RESOURCE: resource }).as_json()
def _add_identifiers_to_resource(cls, resource, model): resource.identifier = [] for identifier in model.identifiers: fhir_id = Identifier() fhir_id.system = identifier.system fhir_id.value = identifier.value resource.identifier.append(fhir_id)
def create_parameter_with_binding(name, value, direction="in"): """ Helper function to create a fhir parameter with binding value :param name: name of the parameter :param value: the value of the parameter :param direction: the direction of the parameter :return: OperationDefinitionParameter """ identifier = Identifier({'value': value}) op_param_binding = OperationDefinitionParameterBinding({ 'strength': 'required', 'valueSetReference': { 'identifier': identifier.as_json() } }) op_param = OperationDefinitionParameter({ 'name': name, 'use': direction, 'min': 1, 'max': '1', 'binding': op_param_binding.as_json() }) return op_param
def create_patient_resource(resource_id, nhs_number, title, first_name, last_name, gender, date_of_birth, address_line_1, city, postcode, place_of_birth): """ Helper function to create a basic fhir patient :return: Patient """ pat_address = Address({ 'line': [address_line_1], 'city': city, 'postalCode': postcode }) nhs_number = Identifier({'value': nhs_number}) name = HumanName({ 'prefix': [title], 'family': last_name, 'given': [first_name] }) birth_address = Address({'city': place_of_birth}) place_of_birth = Extension({ 'url': 'http://hl7.org/fhir/StructureDefinition/birthPlace', 'valueAddress': birth_address.as_json() }) patient = Patient({ 'id': resource_id, 'identifier': [nhs_number.as_json()], 'gender': gender, 'name': [name.as_json()], 'birthDate': date_of_birth, 'address': [pat_address.as_json()], 'extension': [place_of_birth.as_json()] }) return patient
def _to_handling_info(self, username, site_id): if not username and not site_id: return None info = _FhirBiobankOrderHandlingInfo() if site_id: site = SiteDao().get(site_id) info.site = Identifier() info.site.system = SITE_ID_SYSTEM info.site.value = site.googleGroup if username: info.author = Identifier() info.author.system = HEALTHPRO_USERNAME_SYSTEM info.author.value = username return info
def get_fhir_identifier( self, req: "CamcopsRequest", recipient: "ExportRecipient" ) -> Identifier: """ Returns a FHIR identifier for this patient, as a :class:`fhirclient.models.identifier.Identifier` object. This pairs a URL to our CamCOPS server indicating the ID number type (as the "system") with the actual ID number (as the "value"). For debugging situations, it falls back to a default identifier (using the PK on our CamCOPS server). """ which_idnum = recipient.primary_idnum try: # For real exports, the fact that the patient does have an ID # number of the right type will have been pre-verified. if which_idnum is None: raise AttributeError idnum_object = self.get_idnum_object(which_idnum) idnum_value = idnum_object.idnum_value # may raise AttributeError iddef = req.get_idnum_definition(which_idnum) idnum_url = iddef.effective_fhir_id_system(req) return Identifier( jsondict={Fc.SYSTEM: idnum_url, Fc.VALUE: str(idnum_value)} ) except AttributeError: # We are probably in a debugging/drafting situation. Fall back to # a default identifier. return fhir_pk_identifier( req, self.__tablename__, self.pk, Fc.CAMCOPS_VALUE_PATIENT_WITHIN_TASK, )
def fhir_pk_identifier(req: "CamcopsRequest", tablename: str, pk: int, value_within_task: str) -> Identifier: """ Creates a "fallback" identifier -- this is poor, but allows unique identification of anything (such as a patient with no proper ID numbers) based on its CamCOPS table name and server PK. """ return Identifier( jsondict={ Fc.SYSTEM: req.route_url(Routes.FHIR_TABLENAME_PK_ID, table_name=tablename, server_pk=pk), Fc.VALUE: value_within_task, })
def to_client_json(self, model): resource = _FhirBiobankOrder() resource.subject = self._participant_id_to_subject(model.participantId) resource.created = _ToFhirDate(model.created) resource.notes = _FhirBiobankOrderNotes() resource.notes.collected = model.collectedNote resource.notes.processed = model.processedNote resource.notes.finalized = model.finalizedNote resource.source_site = Identifier() resource.created_info = self._to_handling_info(model.sourceUsername, model.sourceSiteId) resource.collected_info = self._to_handling_info( model.collectedUsername, model.collectedSiteId) resource.processed_info = self._to_handling_info( model.processedUsername, model.processedSiteId) resource.finalized_info = self._to_handling_info( model.finalizedUsername, model.finalizedSiteId) resource.amendedReason = model.amendedReason restored = getattr(model, 'restoredSiteId') if model.orderStatus == BiobankOrderStatus.CANCELLED: resource.status = str(BiobankOrderStatus.CANCELLED) resource.cancelledInfo = self._to_handling_info( model.cancelledUsername, model.cancelledSiteId) elif restored: resource.status = str(BiobankOrderStatus.UNSET) resource.restoredInfo = self._to_handling_info( model.restoredUsername, model.restoredSiteId) elif model.orderStatus == BiobankOrderStatus.AMENDED: resource.status = str(BiobankOrderStatus.AMENDED) resource.amendedInfo = self._to_handling_info( model.amendedUsername, model.amendedSiteId) self._add_identifiers_to_resource(resource, model) self._add_samples_to_resource(resource, model) client_json = resource.as_json() # also validates required fields client_json['id'] = model.biobankOrderId del client_json['resourceType'] return client_json
def make_bundle(value: str, sp_unique: bool = False) -> Bundle: system = "https://some_system" jd = { "type": "transaction", "entry": [ BundleEntry( jsondict={ "request": BundleEntryRequest( jsondict={ "method": "POST", "url": "Questionnaire", "ifNoneExist": f"identifier={system}|{value}", }).as_json(), "resource": Questionnaire( jsondict={ "name": "some_questionnaire_name", "status": "active", "identifier": [ Identifier(jsondict={ "system": system, "value": value }).as_json() ], }).as_json(), }).as_json() ], } # Note: the .as_json() conversions are necessary. if sp_unique: raise NotImplementedError( "sp_unique method not implemented; see " "https://github.com/hapifhir/hapi-fhir/issues/3141") return Bundle(jsondict=jd)
def to_client_json(self, model): resource = _FhirBiobankOrder() resource.subject = self._participant_id_to_subject(model.participantId) resource.created = _ToFhirDate(model.created) resource.notes = _FhirBiobankOrderNotes() resource.notes.collected = model.collectedNote resource.notes.processed = model.processedNote resource.notes.finalized = model.finalizedNote resource.source_site = Identifier() resource.created_info = self._to_handling_info(model.sourceUsername, model.sourceSiteId) resource.collected_info = self._to_handling_info( model.collectedUsername, model.collectedSiteId) resource.processed_info = self._to_handling_info( model.processedUsername, model.processedSiteId) resource.finalized_info = self._to_handling_info( model.finalizedUsername, model.finalizedSiteId) self._add_identifiers_to_resource(resource, model) self._add_samples_to_resource(resource, model) client_json = resource.as_json() # also validates required fields client_json['id'] = model.biobankOrderId del client_json['resourceType'] return client_json