def process_search_results(self, search_result, collection): # TODO: Check if FHIR can resolve the dependencies, so less calls necessary result_list = [] next_page = True while next_page: for entry_elem in search_result.entry: ret_element = entry_elem.resource element = ret_element.as_json() result_list.append(element) if len(search_result.link) < 2 or search_result.link[1].relation != "next": next_page = False break res = server.server.request_json(search_result.link[1].url) search_result = bundle.Bundle(res) connection = psqlDbConnection.get_db_connection() pgCur = connection.cursor() pgCur.execute("CREATE TABLE IF NOT EXISTS " + collection + " (ID serial NOT NULL PRIMARY KEY, data jsonb NOT NULL);") pgCur.execute("TRUNCATE TABLE " + collection + " ;") insertSql = "INSERT INTO " + collection + "(data) VALUES %s" entry_list = [] for entry in result_list: entry_list.append((json.dumps(entry),)) execute_values(pgCur, insertSql, entry_list, "(%s::jsonb)") connection.commit() return True
def mkbundle(type, resources): """ takes a list of resources and a bundle type and returns a bundle """ import fhirclient.models.bundle as b bundle = b.Bundle({'type': type}) bundle.entry = [] for resource in resources: print(resource.uuid) entry = b.BundleEntry() entry.fullUrl = resource.uuid entry.resource = resource # print(json.dumps(resource.as_json(), indent=4)) # print(resource.resource_type) # print(json.dumps(resource.referenceSeq.as_json(), indent=4)) # print(dir(resource)) if type == "transaction": request = b.BundleEntryRequest({ 'method': 'POST', 'url': resource.resource_type }) # print(request.as_json()) entry.request = request bundle.entry.append(entry) # print(dir(entry)) print(json.dumps(bundle.as_json(), indent=4))
def unbundle(res_json): try: # unbundle res from search results and add to the res list bundle = Bundle.Bundle(res_json) res = [be.resource for be in bundle.entry] # logging.info('slots[0] is: {}'.format(slots[0].as_json())) return (res) except: logging.info('return None if bundle is None or no bundle entries') return (None)
def crawlResourceForSubject(resourceName, pat_ids, collection, key, value, name, resource_val_path): # Dynamically load module for resource try: resource = getattr(importlib.import_module("fhirclient.models." + resourceName.lower()), resourceName) except Exception: logger.error("Resource " + resourceName + " does not exist", exc_info=1) raise # Perform search try: if resourceName == 'Patient': serverSearchParams = {"_id": pat_ids} else: serverSearchParams = {"patient": pat_ids, key: value} search = resource.where(serverSearchParams) ret = search.perform(server.server) except Exception: logger.error("Search failed", exc_info=1) raise if(len(ret.entry) == 0): logger.info("No values found for search for patients " + pat_ids + " on resource " + resourceName) return insert_list = [] next_page = True while next_page: for entry_elem in ret.entry: ret_element = entry_elem.resource element = resource.as_json(ret_element) element["_id"] = str(ObjectId()) element["feature"] = value element["name"] = name if name is not None else value if resourceName == "Patient": element["patient_id"] = pat_ids elif resourceName == "Condition": element["patient_id"] = ret_element.patient.reference.replace("Patient/", "") else: element["patient_id"] = ret_element.subject.reference.replace("Patient/", "") if resource_val_path is not None: element["resource_val_path"] = resource_val_path insert_list.append(element) if len(ret.link) < 2 or ret.link[1].relation != "next": next_page = False break res = server.server.request_json(ret.link[1].url) ret = bundle.Bundle(res) mongodbConnection.get_db()[collection].insert(list(insert_list))
def __init__(self, entry_name, doc_src='i2b2'): self.entry_name = entry_name self.i2b2_txt_root = data_root / 'mimic/notes/total' self.i2b2_bundle_root = data_root / 'mimic/ObesityResourceBundle' with open(self.i2b2_bundle_root / entry_name) as h: self.doc_js = json.load(h) self.bundle = bd.Bundle(self.doc_js, strict=False) with open(self.i2b2_txt_root / entry_name[:-5]) as f_txt: self.text = f_txt.read()
def parse_bundle_for_file(fhir_bundle_path): with open(fhir_bundle_path, 'r', encoding="utf8") as f: fhir_object = json.load(f) #loading bundle object try: bundle = b.Bundle(fhir_object) #initiating bundle object return bundle except: print( "There are no fhir format files in the provided directory. Please try again." ) return
def get_patients(bundle_path): filelist = os.listdir(bundle_path) Patient_objects = [] for everyfile in filelist: with open(bundle_path + everyfile, 'r') as h: js = json.load(h) Bundle = b.Bundle(js) for e in Bundle.entry: if e.request.url == 'Patient': Patient_objects.append(e.resource) # print(Patient_objects) return Patient_objects
def NextBundle(client, bundle): from fhirclient.models import bundle as BS res = None for link in bundle.link: if link.relation == "next": res = client.server.request_json(link.url) break if res: NewBundle = BS.Bundle(res, strict=False) NewBundle._server = client return NewBundle else: return None
def perform_in(srch_str, server, apiBase): """ Execute the search URL against the given server. :param server: The server against which to perform the search :returns: A Bundle resource """ from fhirclient.models import bundle if server is None: raise Exception("Need a server url to perform search") resources = [] bundleBase = server.request_json(srch_str) bundleCur = bundleBase from fhirclient.models import bundle bundle = bundle.Bundle(bundleBase) bundle.origin_server = server if bundle is not None and bundle.entry is not None: for entry in bundle.entry: resources.append(entry.resource) while True: if len(bundleCur['link'] ) > 1 and bundleCur['link'][1]['relation'] != 'previous': from fhirclient.models import bundle url = bundleCur['link'][1]['url'] urlString = url.replace(apiBase, '') bundleNext = server.request_json(urlString) bundleN = bundle.Bundle(bundleNext) bundleN.origin_server = server if bundleN is not None and bundleN.entry is not None: for entry in bundleN.entry: resources.append(entry.resource) bundleCur = bundleNext else: break return resources
def getAllRecentBabies(server=smart.server, targetnumber=1000, bornInDays=500): bundle = b.Bundle.read_from('Patient', server) targetGap = datetime.timedelta(days=bornInDays) res = [] while len(res) < targetnumber: if bundle is None or bundle.entry is None: return res for entry in bundle.entry: pt = entry.resource if pt.name is None: name = "Name None" else: name = pt.name[0].as_json() if pt.birthDate is None: dob = "DOB None" else: dob = pt.birthDate.date print(len(res), pt.id, name, dob) if dob == 'DOB None': continue if type(dob) == datetime.date: gap = datetime.date.today() - dob #stop = > targetGap if type(dob) == datetime.datetime: gap = datetime.datetime.now( tz=pytz.utc ) - dob # Make now as a datetime timezone-aware, #stop = > targetGap #print("stop is ", stop) if gap > targetGap: continue print("Add patient: ", name, dob) res.append(pt) nexturl = getNextURL(bundle.link) if nexturl is None: return res data = requests.get(nexturl) # request from a URL, not by fhirclient if data is None or data.text is None: return res bundle = b.Bundle(jsondict=json.loads(data.text))
def _load_bundle(path, strict): error = None try: with open(path) as file: json_data = json.load(file) bundle = b.Bundle(json_data) except FHIRValidationError as validation_error: bundle = None error = validation_error if (strict): raise validation_error except: print(f'Unexpected error: {sys.exc_info()[0]}') raise return (bundle, error)
def process_search_results(ret, resource_name, values, code_inf_map, resource_configs, key_path, collection): insert_list = [] next_page = True while next_page: for entry_elem in ret.entry: if resource_name == 'Patient': process_patient_resource(insert_list, entry_elem, values, code_inf_map, resource_configs) else: process_resource(insert_list, entry_elem, resource_name, key_path, values, code_inf_map, resource_configs) if len(ret.link) < 2 or ret.link[1].relation != "next": next_page = False break res = server.server.request_json(ret.link[1].url) ret = bundle.Bundle(res) mongodbConnection.get_db()[collection].insert(list(insert_list))
def parse_bundle_for_file(fhir_bundle_path): """Reads a fhir bundle file and returns a fhir bundle class object Arguments: fhir_bundle_path {String} -- path to a fhir bundle Returns: fhirclient.models.bundle.Bundle -- fhir bundle class object for the fhir bundle file passed into the function """ with open(fhir_bundle_path, 'r') as f: fhir_object = json.load(f) #loading bundle object try: bundle = b.Bundle(fhir_object) #initiating bundle object return bundle except: print( "There are no fhir format files in the provided directory. Please try again." ) return
def perform_in(srch_str, server, apiBase): """ Execute the search URL against the given server. :param server: The server against which to perform the search :returns: A Bundle resource """ from fhirclient.models import bundle if server is None: raise Exception("Need a server url to perform search") resources = [] bundleBase = server.request_json(srch_str) bundleCur = bundleBase from fhirclient.models import bundle bundle = bundle.Bundle(bundleBase) bundle.origin_server = server if bundle is not None and bundle.entry is not None: for entry in bundle.entry: resources.append(entry.resource) return resources
def testBundleReferences(self): with open(os.path.join(cwd, 'test_bundle.json')) as h: data = json.load(h) b = bundle.Bundle(data) self.assertIsNotNone(b, "Must instantiate Bundle") self.assertEqual('Bundle', b.resource_type) #b._server = MockServer() # get resources pat23 = b.entry[0].resource self.assertEqual('Patient', pat23.resource_type) self.assertEqual('Darth', pat23.name[0].given[0]) patURN = b.entry[1].resource self.assertEqual('Patient', patURN.resource_type) self.assertEqual('Ben', patURN.name[0].given[0]) obs123 = b.entry[2].resource self.assertEqual('Observation', obs123.resource_type) obs56 = b.entry[3].resource self.assertEqual('Observation', obs56.resource_type) obs34 = b.entry[4].resource self.assertEqual('Observation', obs34.resource_type) # test resolving w/o server (won't work) res = obs123.subject.resolved(patient.Patient) self.assertIsNone(res) # test resolving with server b._server = MockServer() res = obs123.subject.resolved(patient.Patient) self.assertEqual(res, pat23) res = obs123.subject.resolved(medication.Medication) self.assertIsNone(res, "Must not resolve on type mismatch") res = obs56.subject.resolved(patient.Patient) self.assertEqual(res, patURN) res = obs34.subject.resolved(patient.Patient) self.assertIsNone( res, "Must not resolve Patient on same server but different endpoint")
def bundler( resources, type='aa' ): # make the operation output type = 'aa' or transactions bundle type = 'tr' logging.info("starting bundler...") new_bundle = Bundle.Bundle() new_bundle.id = 'argo-{}b-{}'.format(type, timestamp()) new_bundle.type = f.bundle_type[type] new_bundle.entry = [] for res in resources: # list of resources logging.info('res ={}'.format(res)) entry = Bundle.BundleEntry() entry.fullUrl = '{}/{}/{}'.format(ref_server, res.resource_type, res.id) entry.resource = res if type == 'aa': entry.search = Bundle.BundleEntrySearch({'mode': 'match'}) if type == 'tr': trans = Bundle.BundleEntryRequest() trans.method = 'PUT' trans.url = '{}/{}'.format(res.resource_type, res.id) entry.request = trans new_bundle.entry.append(entry) if type == 'aa': new_bundle.total = len( resources) # need to keep count same a op parameter # OO stubbed in here: entry = Bundle.BundleEntry() entry.fullUrl = '{}/{}/{}'.format(ref_server, 'OperationOutcome', new_bundle.id) entry.resource = OO.OperationOutcome(json.loads( f.oo_template)) # make a fixed template for now entry.search = Bundle.BundleEntrySearch({'mode': 'outcome'}) new_bundle.entry.append(entry) logging.info('new_bundle={}'.format(new_bundle.as_json())) return (new_bundle)
def crawlResourceForSubject(resourceName, subject, key, value): # Dynamically load module for resource try: resource = getattr( importlib.import_module("fhirclient.models." + resourceName.lower()), resourceName) except Exception: logger.error("Resource " + resourceName + " does not exist", exc_info=1) raise # Perform search try: serverSearchParams = {"patient": subject, "_count": "100"} '''if resourceName == 'Patient': serverSearchParams = {"_id": subject} else: serverSearchParams = {"patient": subject, key: value} ''' search = resource.where(serverSearchParams) ret = search.perform(server.server) except Exception: print("Search failed") raise insert_list = [] next_page = True while next_page: for entry_elem in ret.entry: ret_element = entry_elem.resource.as_json() cur_elem_key = getElemByPath("code.coding.code", ret_element) print(cur_elem_key, file=sys.stderr) name = code_inf_map[cur_elem_key]['name'] resource_val_path = code_inf_map[cur_elem_key]['resource_val_path'] element = resource.as_json(ret_element) element["_id"] = str(ObjectId()) element["feature"] = cur_elem_key element["name"] = name if name is not None else cur_elem_key if resource_name == "Patient": element["patient_id"] = pat_ids elif resource_name == "Condition": element["patient_id"] = ret_element.patient.reference.replace( "Patient/", "") else: element["patient_id"] = ret_element.subject.reference.replace( "Patient/", "") element["resource_val_path"] = resource_val_path insert_list.append(element) if len(ret.link) < 2 or ret.link[1].relation != "next": next_page = False break res = server.server.request_json(ret.link[1].url) ret = bundle.Bundle(res) '''while ret.link[1].relation == "next": from fhirclient.models import bundle res = server.server.request_json(ret.link[1].url) ret = bundle.Bundle(res) print(ret.link[1].url) print(ret.link) print(len(ret.entry)) print(ret.link[1].relation) print(ret.link[1].url) ret2 = server.server.request_json(ret.link[1].url)''' return for element in ret: #print(element.patient.reference.replace("Patient/", "")) #print('{"resource": "Condition","key": "code.coding.code","value":"', element.code.coding[0].code, '","name": "', element.code.coding[0].display, '"},', sep="") element = resource.as_json(element) return ret
elif status in ("Terminated", "Withdrawn"): return 'stopped' else: return 'draft' if __name__ == "__main__": ct = ClinicalStudy.from_file("examples/NCT02348489.xml", local_schema=True) locations = [build_location(x) for x in ct.locations] foci = build_focus(ct.mesh_terms) print([x.as_json() for x in foci]) keywords = build_keyword(ct.keywords) print([x.as_json() for x in keywords]) identifiers = build_identifiers(ct.nct_id, ct.study_id, ct.secondary_id) print([x.as_json() for x in identifiers]) package = bundle.Bundle() package.type = "document" package.identifier = identifier.Identifier( dict(use='official', system="https://clinicaltrials.gov/ct2/show/", value=ct.nct_id)) entries = [] for location in locations: be = bundle.BundleEntry() be.resource_type = "Location" be.resource = location entries.append(be) study = researchstudy.ResearchStudy() study.identifier = identifiers print("Study Identifier: ", type(study.identifier[0])) study.period = period.Period(