def next_search(request, *args, **kwargs): """ Handle search requests :param request: :return: """ server = FhirServerUrl() in_fmt = "json" get_fmt = get_format(request.GET) if settings.DEBUG: print("Server:", server) print("Kwargs:", kwargs) context = { 'display': "Search", 'name': "Search", 'server': server, 'in_fmt': in_fmt, 'get_fmt': get_fmt, 'template': 'v1api/search.html', } request_string = "?" for item in request.GET: request_string += item + "=" + request.GET[item] + "&" if request_string[:0] == "&": request_string = request_string[:-1] if not "patient=Patient/" in request_string: try: xwalk = Crosswalk.objects.get(user=request.user) patient_id = xwalk.fhir_url_id request_string += "&patient=Patient/" + patient_id except Crosswalk.DoesNotExist: return kickout_404("ID for this user not found:%s" % request.user) if settings.DEBUG: print("Gets:", request_string) try: r = requests.get(server + request_string) context = process_page(request, r, context) return publish_page(request, context) except requests.ConnectionError: print("Whoops - Problem connecting to FHIR Server") messages.error( request, "FHIR Server is unreachable. " "Are you on the CMS Network?") return render_to_response(context['template'], RequestContext( request, context, ))
def write_fhir(mode, resource, body, target ): """ write a record to FHIR :return: """ if True: print("Mode:", mode) print("Resource:", resource) print("Body:", body) print("Target:[%s]" % target) result = "" headers = {'content-type': 'application/json+fhir;charset=UTF-8'} if target == None: server = FhirServerUrl() + "/" + resource elif mode == "PUT" and target != "": server = FhirServerUrl() + "/" + target else: server = FhirServerUrl() + "/" + resource server = server + "?_format=json" if settings.DEBUG: print("in write_fhir:", server, mode, resource, body) if mode == "POST": r = requests.post(server, data=body, headers=headers) else: # mode == "PUT" r = requests.put(server, data=body, headers=headers) if r.status_code == 200 or r.status_code == 201: # We need to strip the url down to "{Resource}/{number} result = get_resource_number(r.headers['Location'], resource) else: result = target if settings.DEBUG: print("Result:", r.status_code, r.text, result) print("URL:", r.url) print("Headers:", r.headers) print(r.json) return result
def get_next_page(j): # Get the next page next_page = "" # print("Get Next Page from link:", json.dumps(j, indent=4)) for l in j['link']: if l['relation'] == "next": next_page = FhirServerUrl() + "?" + l['url'].split("?")[1] return next_page
def geteob(request): """ Process each crosswalk record. Get the fhir_url_id Construct an ExplanationOfBenefit call using patient=Patient/{xwalk.fhir_url_id} Get the count Write to xwalk.eob_cont """ server_call = FhirServerUrl( ) + "/ExplanationOfBenefit/?_format=json&patient=Patient/" ctr = 0 od = OrderedDict() od['server'] = FhirServerUrl() od['api_call'] = "/setup/geteob" then = datetime.datetime.now() od['start'] = str(then) for x in Crosswalk.objects.all(): patient_id = x.fhir_url_id u = server_call + patient_id j = get_page_content(u) if 'total' in j: x.eob_count = notNone(j["total"], 0) x.save() ctr += 1 if ctr % 100 == 0: print("processed ", ctr) print("elapsed ", str(datetime.datetime.now() - then)) od['processed'] = ctr now = datetime.datetime.now() od['elapsed'] = str(now - then) od['end'] = str(now) return HttpResponse(json.dumps(od, indent=4), content_type="application/json")
def get_api_count(api_parm): """ Generic API Call to a search to get count """ server = FhirServerUrl() + api_parm j = get_page_content(server) if 'total' in j: return j['total'] else: return None
def get_eob_count(e): """ Do EOB Search for patient=Patient/{e['id']} Get count """ pass_to = FhirServerUrl() + "/" + "ExplanationOfBenefit" pass_to += "?_format=json&patient=Patient/" pass_to += e['id'] eob = get_page_content(pass_to) # eob search bundle returnedin json format eob_count = notNone(eob['total'], 0) return eob_count
def PatientExplanationOfBenefit(request, patient_id=None, *args, **kwargs): """ Function-based interface to ExplanationOfBenefit :param request: :return: """ if patient_id == None: try: xwalk = Crosswalk.objects.get(user=request.user.id) patient_id = xwalk.fhir_url_id except Crosswalk.DoesNotExist: reason = "Unable to find Patient ID for user:%s[%s]" % (request.user, request.user.id) messages.error(request, reason) return kickout_404(reason) # return HttpResponseRedirect(reverse('api:v1:home')) if xwalk.fhir_url_id == "": err_msg = ['Crosswalk lookup failed: Sorry, We were unable to find', 'your record', ] exit_message = concat_string("", msg=err_msg, delimiter=" ", last=".") messages.error(request, exit_message) return kickout_404(exit_message) if patient_id == "": err_msg = ['Sorry, No Patient Id provided', ] exit_message = concat_string("", msg=err_msg, delimiter=" ", last=".") messages.error(request, exit_message) return HttpResponseRedirect(reverse('api:v1:home')) if settings.DEBUG: print("In apps.v1api.views.eob.PatientExplanationOfBenefit Function") print("request:", request.GET) process_mode = request.META['REQUEST_METHOD'] in_fmt = "json" get_fmt = get_format(request.GET) Txn = {'name': "ExplanationOfBenefit", 'display': 'EOB', 'mask': True, 'template': 'v1api/eob.html', 'in_fmt': in_fmt, } if settings.DEBUG: print("Request.GET :", request.GET) print("KWargs :", kwargs) print("Patient :", patient_id) # We should have the xwalk.FHIR_url_id # So we will construct the EOB Identifier to include # We will deal internally in JSON Format if caller does not choose # a format in_fmt = "json" get_fmt = get_format(request.GET) pass_to = FhirServerUrl() pass_to += "/ExplanationOfBenefit/" key = patient_id patient_filter= "?patient=Patient/" + key pass_to += patient_filter skip_parm = ['_id', '_format'] pass_to = pass_to + "&" + build_params(request.GET, skip_parm)[1:] # Set Context context = {'display':"EOB", 'name': "ExplanationOfBenefit", 'mask': True, 'key': key, 'get_fmt': get_fmt, 'in_fmt': in_fmt, 'pass_to': pass_to, } if settings.DEBUG: print("Calling requests with pass_to:", pass_to) try: r = requests.get(pass_to) if get_fmt == "xml": xml_text = minidom.parseString(r.text) print("XML_TEXT:", xml_text.toxml()) root = ET.fromstring(r.text) # root_out = etree_to_dict(r.text) json_string = "" # json_out = xml_str_to_json_str(r.text, json_string) if settings.DEBUG: print("Root ET XML:", root) # print("XML:", root_out) # print("JSON_OUT:", json_out,":", json_string) drill_down = ['Bundle', 'entry', 'Patient', ] level = 0 tag0 = xml_text.getElementsByTagName("text") # tag1 = tag0.getElementsByTagName("entry") print("Patient?:", tag0) print("DrillDown:", drill_down[level]) print("root find:", root.find(drill_down[level])) pretty_xml = xml_text.toprettyxml() #if settings.DEBUG: # print("TEXT:", text) # # print("Pretty XML:", pretty_xml) context['result'] = pretty_xml # convert context['text'] = pretty_xml else: convert = OrderedDict(r.json()) # result = mark_safe(convert) if settings.DEBUG: print("Convert:", convert) # print("Next Level - entry:", convert['entry']) # print("\n ANOTHER Level- text:", convert['entry'][0]) content = OrderedDict(convert) text = "" if settings.DEBUG: print("Content:", content) print("resourceType:", content['resourceType']) if 'text' in content: if 'div' in content['text']: print("text:", content['text']['div']) # context['result'] = r.json() # convert import_text = json.loads(r.text, object_pairs_hook=OrderedDict) context['result'] = json.dumps(import_text, indent=4, sort_keys=False) if 'text' in content: if 'div' in content['text']: context['text'] = content['text']['div'] else: context['text'] = "" else: context['text'] = "No user readable content to display" if 'error' in content: context['error'] = context['issue'] # Setup the page if settings.DEBUG: print("Context-result:", context['result']) # print("Context-converted:", json.dumps(context['result'], sort_keys=False)) # print("Context:",context) if get_fmt == 'xml' or get_fmt == 'json': if settings.DEBUG: print("Mode = ", get_fmt) print("Context['result']: ", context['result']) if get_fmt == "xml": return HttpResponse(context['result'], content_type='application/' + get_fmt) if get_fmt == "json": #return HttpResponse(context['result'], mimetype="application/json") return JsonResponse(import_text, safe=False ) else: return render_to_response(Txn['template'], RequestContext(request, context, )) except requests.ConnectionError: print("Whoops - Problem connecting to FHIR Server") messages.error(request, "FHIR Server is unreachable. Are you on the CMS Network?") return HttpResponseRedirect(reverse('api:v1:home'))
def get_patient(request, Access_Mode=None, *args, **kwargs): """ Display Patient Profile :param request: :param Access_Mode = [None], Open :param args: :param kwargs: :return: """ # Access_Mode = None = Do Crosswalk using Request.user # Access_Mode = OPEN = use kwargs['patient_id'] if settings.DEBUG: print("Request.GET :", request.GET) print("Access_Mode :", Access_Mode) print("KWargs :", kwargs) print("Args :", args) if Access_Mode == "OPEN" and kwargs['patient_id'] != "": # Lookup using patient_id for fhir_url_id key = kwargs['patient_id'].strip() else: # DONE: Setup Patient API so that ID is not required # DONE: Do CrossWalk Lookup to get Patient ID if settings.DEBUG: print("Request User Beneficiary(Patient):", request.user) try: xwalk = Crosswalk.objects.get(user=request.user.id) except Crosswalk.DoesNotExist: reason = "Unable to find Patient ID for user:%s[%s]" % ( request.user, request.user.id) messages.error(request, reason) return kickout_404(reason) # return HttpResponseRedirect(reverse('api:v1:home')) if xwalk.fhir_url_id == "": err_msg = [ 'Crosswalk lookup failed: Sorry, We were unable to find', 'your record', ] exit_message = concat_string("", msg=err_msg, delimiter=" ", last=".") messages.error(request, exit_message) return kickout_404(exit_message) # return HttpResponseRedirect(reverse('api:v1:home')) key = xwalk.fhir_url_id.strip() if settings.DEBUG: print("Crosswalk :", xwalk) print("GUID :", xwalk.guid) print("FHIR :", xwalk.fhir) print("FHIR URL ID :", key) # We will deal internally in JSON Format if caller does not choose # a format in_fmt = "json" # fhir_server_configuration = {"SERVER":"http://fhir-test.bbonfhir.com:8081", # "PATH":"", # "RELEASE":"/baseDstu2"} # FHIR_SERVER_CONF = fhir_server_configuration # FHIR_SERVER = FHIR_SERVER_CONF['SERVER'] + FHIR_SERVER_CONF['PATH'] # Since this is BlueButton and we are dealing with Patient Records # We need to limit the id search to the specific beneficiary. # A BlueButton user should not be able to request a patient profile # that is not their own. # We do this via the CrossWalk. The xwalk.fhir_url_id is the patient # id as used in the url. eg. /Patient/23/ # FHIR also allows an enquiry with ?_id=23. We need to detect that # and remove it from the parameters that are passed. # All other query parameters should be passed through to the # FHIR server. # Add URL Parameters to skip_parm to ignore or perform custom # processing with them. Use lower case values for matching. # DO NOT USE Uppercase skip_parm = ['_id', '_format'] mask = True pass_to = FhirServerUrl() pass_to += "/Patient" pass_to += "/" pass_to = pass_to + key + "/" # We need to detect if a format was requested in the URL Parameters # ie. _format=json|xml # modify get_format to default to return nothing. ie. make no change # internal data handling will be JSON # _format will drive external display # if no _format setting we will display in html (Current mode) # if valid _format string we will pass content through to display in # raw format get_fmt = get_format(request.GET) if settings.DEBUG: print("pass_to:", pass_to) pass_to = pass_to + build_params(request.GET, skip_parm) if settings.DEBUG: print("pass_to added to:", pass_to) mask_to = settings.DOMAIN # Set Context context = { 'display': "Patient", 'name': "Patient", 'mask': mask, 'key': key, 'get_fmt': get_fmt, 'in_fmt': in_fmt, # 'output' : "test output ", # 'args' : args, # 'kwargs' : kwargs, # 'get' : request.GET, 'pass_to': pass_to, 'template': 'v1api/patient.html', } if settings.DEBUG: print("Calling Requests with:", pass_to) try: r = requests.get(pass_to) context = process_page(request, r, context) return publish_page(request, context) # # Setup the page # # if settings.DEBUG: # print("Context-result:", context['result']) # # print("Context-converted:", json.dumps(context['result'], sort_keys=False)) # # print("Context:",context) # # if get_fmt == 'xml' or get_fmt == 'json': # if settings.DEBUG: # print("Mode = ", get_fmt) # print("Context['result']: ", context['result']) # if get_fmt == "xml": # return HttpResponse(context['result'], # content_type='application/' + get_fmt) # if get_fmt == "json": # #return HttpResponse(context['result'], mimetype="application/json") # return JsonResponse(context['import_text'], safe=False) # # else: # # if context['text'] == "No user readable content to display" or context['text']=="": # # result = json.loads(context['result'], object_pairs_hook=OrderedDict) # print("Result::", result) # context['text'] += "<br/> extracting information from returned record:<br/>" # context['text'] += "<table>\n" # if 'name' in result: # patient_name = result['name'][0]['given'][0] # patient_name += " " # patient_name += result['name'][0]['family'][0] # context['text'] += tr_build_item("Patient Name ", # patient_name) # if 'address' in result: # context['text'] += tr_build_item("Patient Address", # result['address'][0]['line'][0]) # if 'birthDate' in result: # context['text'] += tr_build_item("Birth Date", result['birthDate']) # # if 'identifier' in result: # context['text'] += tr_build_item("Patient ID", # result['identifier'][0]['value']) # context['text'] += "</table>" # # return render_to_response('v1api/patient.html', # RequestContext(request, # context, )) except requests.ConnectionError: pass return cms_not_connected(request, 'api:v1:home')
def get_eob_view(request, eob_id, *args, **kwargs): """ Display one or more EOBs but Always limit scope to Patient_Id :param request: :param eob_id: Request a specific EOB :param args: :param kwargs: :return: """ if settings.DEBUG: print("Request User Beneficiary(Patient):", request.user, "\nFor Single EOB") try: xwalk = Crosswalk.objects.get(user=request.user) except Crosswalk.DoesNotExist: messages.error(request, "Unable to find Patient ID") return HttpResponseRedirect(reverse('api:v1:home')) if xwalk.fhir_url_id == "": err_msg = [ 'Sorry, We were unable to find', 'your record', ] exit_message = concat_string("", msg=err_msg, delimiter=" ", last=".") messages.error(request, exit_message) return HttpResponseRedirect(reverse('api:v1:home')) if settings.DEBUG: print("Request.GET :", request.GET) print("KWargs :", kwargs) print("Crosswalk :", xwalk) print("GUID :", xwalk.guid) print("FHIR :", xwalk.fhir) print("FHIR URL ID :", xwalk.fhir_url_id) # We should have the xwalk.FHIR_url_id # So we will construct the EOB Identifier to include # We will deal internally in JSON Format if caller does not choose # a format in_fmt = "json" get_fmt = get_format(request.GET) # DONE: Define Transaction Dictionary to enable generic presentation of API Call skip_parm = ['_id', '_format'] key = xwalk.fhir_url_id.strip() mask = True pass_to = FhirServerUrl() pass_to += "/ExplanationOfBenefit/" # We can allow an EOB but we MUST add a search Parameter # to limit the items found to those relevant to the Patient Id if eob_id: pass_to = pass_to + eob_id + "/" # Now apply the search restriction to limit to patient _id #pass_to = pass_to + key + "/" pass_to = pass_to + "?patient=" pass_to = pass_to + "Patient/" pass_to = pass_to + xwalk.fhir_url_id.strip() pass_to = pass_to + "&" + build_params(request.GET, skip_parm) if settings.DEBUG: print("Pass_to from build_params:", pass_to) if settings.DEBUG: print("Calling requests with pass_to:", pass_to) # Set Context context = { 'name': "ExplanationOfBenefit", 'display': 'EOB', 'mask': mask, 'key': key, 'get_fmt': get_fmt, 'in_fmt': in_fmt, # 'output' : "test output ", # 'args' : args, # 'kwargs' : kwargs, # 'get' : request.GET, 'pass_to': pass_to, 'template': 'v1api/eob.html', } try: r = requests.get(pass_to) context = process_page(request, r, context) return publish_page(request, context) except requests.ConnectionError: pass return cms_not_connected(request, 'api:v1:home')
def get_eob(request, eob_id=None, Access_Mode=None, *args, **kwargs): """ Display one or more EOBs but Always limit scope to Patient_Id :param request: :param eob_id: Request a specific EOB :param args: :param kwargs: :return: """ if settings.DEBUG: print("Request User Beneficiary(Patient):", request.user, "\nFor EOB Enquiry ") print("Request.GET :", request.GET) print("Access_Mode :", Access_Mode) print("KWargs :", kwargs) print("Args :", args) if Access_Mode == "OPEN": # Lookup using eob_id without patient filter key = "" else: try: xwalk = Crosswalk.objects.get(user=request.user) except Crosswalk.DoesNotExist: messages.error(request, "Unable to find Patient ID") return HttpResponseRedirect(reverse('api:v1:home')) if xwalk.fhir_url_id == "": err_msg = [ 'Sorry, We were unable to find', 'your record', ] exit_message = concat_string("", msg=err_msg, delimiter=" ", last=".") messages.error(request, exit_message) return HttpResponseRedirect(reverse('api:v1:home')) key = xwalk.fhir_url_id.strip() if settings.DEBUG: print("FHIR URL ID :", key) # We should have the xwalk.FHIR_url_id # So we will construct the EOB Identifier to include # This is a hack to limit EOBs returned to this user only. # id_source['system'] = "https://mymedicare.gov/claims/beneficiary" # id_source['use'] = "official" # id_source['value'] = "Patient/"+str(patient_id) # id_list.append(unique_id(id_source)) # this search works: # http://fhir.bbonfhir.com:8080/fhir-p/ # search?serverId=bbonfhir_dev # &resource=ExplanationOfBenefit # ¶m.0.0=https%3A%2F%2Fmymedicare.gov%2Fclaims%2Fbeneficiary # ¶m.0.1=Patient%2F4995401 # ¶m.0.name=identifier # ¶m.0.type=token # &sort_by= # &sort_direction= # &resource-search-limit= # http://ec2-52-4-198-86.compute-1.amazonaws.com:8081/baseDstu2/ # ExplanationOfBenefit/?patient=Patient/131052&_format=json # We will deal internally in JSON Format if caller does not choose # a format in_fmt = "json" get_fmt = get_format(request.GET) skip_parm = ['_id', '_format', 'patient'] mask = True pass_to = FhirServerUrl() pass_to += "/ExplanationOfBenefit" pass_to += "/" if eob_id == None: pass else: pass_to += eob_id # We can allow an EOB but we MUST add a search Parameter # to limit the items found to those relevant to the Patient Id #if eob_id: # pass_to = eob_id + "/" # Now apply the search restriction to limit to patient _id #pass_to = pass_to + key + "/" if not key == "": pass_to += "?patient=" pass_to += "Patient/" pass_to += key pass_to = pass_to + "&" + build_params(request.GET, skip_parm)[1:] if settings.DEBUG: print("Pass_to from build_params:", pass_to) if settings.DEBUG: print("Calling requests with pass_to:", pass_to) # Set Context context = { 'display': 'EOB', 'name': 'ExplanationOfBenefit', 'mask': mask, 'key': key, 'eob_id': eob_id, 'get_fmt': get_fmt, 'in_fmt': in_fmt, 'pass_to': pass_to, 'template': 'v1api/eob.html', } try: r = requests.get(pass_to) context = process_page(request, r, context) return publish_page(request, context) except requests.ConnectionError: pass return cms_not_connected(request, 'api:v1:home')
def generic_read(request, interaction_type, resource_type, id, vid=None, *args, **kwargs): """ Read from remote FHIR Server :param resourcetype: :param id: :return: # Example client use in curl: # curl -X GET http://127.0.0.1:8000/fhir/Practitioner/1234 """ # interaction_type = 'read' or '_history' or 'vread' if settings.DEBUG: print("interaction_type:", interaction_type) #Check if this interaction type and resource type combo is allowed. deny = check_access_interaction_and_resource_type(resource_type, interaction_type) if deny: #If not allowed, return a 4xx error. return deny srtc = check_rt_controls(resource_type) # We get back an Supported ResourceType Control record or None if settings.DEBUG: if srtc: print("Parameter Restrictions:", srtc.parameter_restriction()) else: print("No Resource Controls found") print("Working with id:", id) key = id if srtc: if srtc.force_url_id_override: key = crosswalk_id(request, id) if key == None: if not id == None: key = id # Crosswalk returns the new id or returns None if settings.DEBUG: print("crosswalk:", key, ":", request.user) else: # No Id_Overide so use the original id key = id else: key = id # Do we have a key? # if key == None: # return kickout_404("FHIR_IO_HAPI:Search needs a valid Resource Id that is linked " # "to the authenticated user " # "(%s) which was not available" % request.user) # Now we get to process the API Call. if settings.DEBUG: print( "Now we need to evaluate the parameters and arguments" " to work with ", key, "and ", request.user) print("GET Parameters:", request.GET, ":") mask = False if srtc: if srtc.force_url_id_override: mask = True in_fmt = "json" Txn = { 'name': resource_type, 'display': resource_type, 'mask': mask, 'in_fmt': in_fmt, } skip_parm = [] if srtc: skip_parm = srtc.parameter_restriction() #skip_parm = ['_id', # 'access_token', 'client_id', 'response_type', 'state'] if settings.DEBUG: print('Masking the following parameters', skip_parm) # access_token can be passed in as a part of OAuth protected request. # as can: state=random_state_string&response_type=code&client_id=ABCDEF # Remove it before passing url through to FHIR Server pass_params = build_params(request.GET, skip_parm) if settings.DEBUG: print("Parameters:", pass_params) if interaction_type == "vread": pass_to = FhirServerUrl( ) + "/" + resource_type + "/" + key + "/" + "_history" + "/" + vid elif interaction_type == "_history": pass_to = FhirServerUrl( ) + "/" + resource_type + "/" + key + "/" + "_history" else: # interaction_type == "read": pass_to = FhirServerUrl() + "/" + resource_type + "/" + key + "/" print("Here is the URL to send, %s now get parameters %s" % (pass_to, pass_params)) if pass_params != "": pass_to += pass_params # Now make the call to the backend API try: r = requests.get(pass_to) except requests.ConnectionError: if settings.DEBUG: print("Problem connecting to FHIR Server") messages.error(request, "FHIR Server is unreachable.") return HttpResponseRedirect(reverse_lazy('api:v1:home')) if r.status_code in [301, 302, 400, 403, 404, 500]: return error_status(r, r.status_code) text_out = "" if settings.DEBUG: print("r:", r.text) if '_format=xml' in pass_params: text_out = minidom.parseString(r.text).toprettyxml() else: text_out = r.json() od = OrderedDict() if DF_EXTRA_INFO: od['request_method'] = request.method od['interaction_type'] = interaction_type od['resource_type'] = resource_type od['id'] = key if vid != None: od['vid'] = vid if settings.DEBUG: print("Query List:", request.META['QUERY_STRING']) if DF_EXTRA_INFO: od['parameters'] = request.GET.urlencode() if settings.DEBUG: print("or:", od['parameters']) if '_format=xml' in pass_params.lower(): fmt = "xml" elif '_format=json' in pass_params.lower(): fmt = "json" else: fmt = '' if DF_EXTRA_INFO: od['format'] = fmt od['bundle'] = text_out if DF_EXTRA_INFO: od['note'] = 'This is the %s Pass Thru (%s) ' % (resource_type, key) if settings.DEBUG: od['note'] += 'using: %s ' % (pass_to) print(od) if fmt == "xml": if settings.DEBUG: print("We got xml back in od") return HttpResponse(tostring(dict_to_xml('content', od)), content_type="application/%s" % fmt) elif fmt == "json": if settings.DEBUG: print("We got json back in od") return HttpResponse(json.dumps(od, indent=4), content_type="application/%s" % fmt) if settings.DEBUG: print("We got a different format:%s" % fmt) return render( request, 'fhir_io_hapi/default.html', { 'content': json.dumps(od, indent=4), 'output': od }, )
def getpatient(request): if settings.DEBUG: print("in getpatient") od = OrderedDict() # Compile call to Patient search on FHIR Server od['fhir_server'] = FhirServerUrl() + "/" + "Patient" od['count'] = 10 od['parameters'] = "?_format=json&_count=" + str(od['count']) # set count to 10 to return 10 items per page j = get_page_content(od['fhir_server'] + od['parameters']) if 'total' in j: od['total'] = j['total'] else: od['total'] = 0 then = datetime.datetime.now() od['start'] = str(then) if 'entry' in j: od['entries'] = len(j['entry']) else: od['entries'] = 0 od['entry'] = [] if settings.DEBUG: print("od:", od) # print("j:", j) if settings.DEBUG: print("Entries:", od['entries']) # Now we have the number of entries # and the contents of the entries # pass the content, current count and total to function to get patient info bundle_count = od['entries'] rt = 0 while rt < od['total']: x = 0 while x < notNone(bundle_count, 0): if settings.DEBUG: # Print every 100 lines if x % 100 == 0: print("running for:", datetime.datetime.now() - then) print("x:", rt + x) print("OD:", od) # print("entries:", len(j['entry'])) if 'entry' in j: result = extract_info(j['entry'][x]) od['entry'].append(result['id']) x += 1 if x >= notNone(bundle_count, 0): # We need to request the next page next_page = get_next_page(j) if next_page != "": j = get_page_content(next_page) if 'entry' in j: bundle_count = len(j['entry']) rt += x # if settings.DEBUG: # print("rt:", rt) od['result'] = str(j) now = datetime.datetime.now() od['end'] = str(then) od['elapsed'] = str(now - then) od['processed'] = rt # Check total # while x <= 10 and y <= total # get Patient from entity # get fhir url id # get name # get identifier # update crosswalk # update user account # Increment count while count less than total if settings.DEBUG: print("OD -result:", od['result']) return HttpResponse(json.dumps(od, indent=4), content_type="application/json")
def ExplanationOfBenefit(request, eob_id=None, Access_Mode=None, *args, **kwargs): """ Function-based interface to ExplanationOfBenefit :param request: :return: Use Cases: 1. No eob_id: Do Search and apply patient=Patient/User.Crosswalk.fhir_url_id 2. eob_id: Do Search and get eob with patient filter http://bluebuttonhapi-test.hhsdevcloud.us/baseDstu2/ExplanationOfBenefit ?_id=1286291&patient=Patient/1286160 3. eob_id and Access_mode = OPEN """ if settings.DEBUG: print("In apps.v1api.views.eob.ExplanationOfBenefit Function") print("request:", request.GET) process_mode = request.META['REQUEST_METHOD'] patient_id = lookup_xwalk(request) # try: # xwalk = Crosswalk.objects.get(user=request.user) # except Crosswalk.DoesNotExist: # messages.error(request, "Unable to find Patient ID") # return HttpResponseRedirect(reverse('api:v1:home')) # if patient_id == None: return HttpResponseRedirect(reverse('api:v1:home')) in_fmt = "json" get_fmt = get_format(request.GET) if settings.DEBUG: print("Request.GET :", request.GET) print("KWargs :", kwargs) print("FHIR URL ID :", patient_id) # We should have the xwalk.FHIR_url_id # So we will construct the EOB Identifier to include # We will deal internally in JSON Format if caller does not choose # a format in_fmt = "json" get_fmt = get_format(request.GET) pass_to = FhirServerUrl() pass_to += "/ExplanationOfBenefit/" key = patient_id.strip() patient_filter = "patient=Patient/" + key # pass_to += patient_filter skip_parm = ['_id', '_format'] got_parms = build_params(request.GET, skip_parm)[1:] if got_parms: print("Got parms:", got_parms) pass_to += "?" + got_parms if Access_Mode == "OPEN": pass else: if "?" in pass_to: pass_to += "&" + patient_filter else: pass_to += "?" + patient_filter if eob_id: if "?" in pass_to: pass_to += "&" else: pass_to += "?" pass_to += "_id=" + eob_id print("Calling:", pass_to) # Set Context context = { 'display': "EOB", 'name': "ExplanationOfBenefit", 'mask': True, 'key': key, 'eob': eob_id, 'get_fmt': get_fmt, 'in_fmt': in_fmt, 'pass_to': pass_to, 'template': 'v1api/eob.html', } if settings.DEBUG: print("Calling requests with pass_to:", pass_to) # We need to replace FHIR Server with External Server reference rewrite_from = settings.FHIR_SERVER_CONF['REWRITE_FROM'] rewrite_to = settings.FHIR_SERVER_CONF['REWRITE_TO'] try: r = requests.get(pass_to) context = process_page(request, r, context) return publish_page(request, context) except requests.ConnectionError: pass return cms_not_connected(request, 'api:v1:home')
def PatientExplanationOfBenefit(request, patient_id=None, *args, **kwargs): """ Function-based interface to ExplanationOfBenefit :param request: :return: """ if patient_id == None: patient_id = lookup_xwalk(request) if patient_id == None: err_msg = [ 'Crosswalk lookup failed: Sorry, We were unable to find', 'your record', ] exit_message = concat_string("", msg=err_msg, delimiter=" ", last=".") messages.error(request, exit_message) return kickout_404(exit_message) if patient_id == "": err_msg = [ 'Sorry, No Patient Id provided', ] exit_message = concat_string("", msg=err_msg, delimiter=" ", last=".") messages.error(request, exit_message) return HttpResponseRedirect(reverse('api:v1:home')) if settings.DEBUG: print("In apps.v1api.views.eob.PatientExplanationOfBenefit Function") print("request:", request.GET) process_mode = request.META['REQUEST_METHOD'] in_fmt = "json" get_fmt = get_format(request.GET) if settings.DEBUG: print("Request.GET :", request.GET) print("KWargs :", kwargs) print("Patient :", patient_id) # We should have the patient_id from xwalk.FHIR_url_id # So we will construct the EOB Identifier to include # We will deal internally in JSON Format if caller does not choose # a format in_fmt = "json" get_fmt = get_format(request.GET) pass_to = FhirServerUrl() pass_to += "/ExplanationOfBenefit/" key = patient_id patient_filter = "?patient=Patient/" + key pass_to += patient_filter skip_parm = ['_id', '_format'] pass_to = pass_to + "&" + build_params(request.GET, skip_parm)[1:] # Set Context context = { 'display': "EOB", 'name': "ExplanationOfBenefit", 'mask': True, 'key': key, 'get_fmt': get_fmt, 'in_fmt': in_fmt, 'pass_to': pass_to, 'template': 'v1api/eob.html', } if settings.DEBUG: print("Calling requests with pass_to:", pass_to) try: r = requests.get(pass_to) context = process_page(request, r, context) return publish_page(request, context) except requests.ConnectionError: pass return cms_not_connected(request, 'api:v1:home')
def get_eob_view(request, eob_id, *args, **kwargs): """ Display one or more EOBs but Always limit scope to Patient_Id :param request: :param eob_id: Request a specific EOB :param args: :param kwargs: :return: """ if settings.DEBUG: print("Request User Beneficiary(Patient):", request.user, "\nFor Single EOB") try: xwalk = Crosswalk.objects.get(user=request.user) except Crosswalk.DoesNotExist: messages.error(request, "Unable to find Patient ID") return HttpResponseRedirect(reverse('api:v1:home')) if xwalk.fhir_url_id == "": err_msg = [ 'Sorry, We were unable to find', 'your record', ] exit_message = concat_string("", msg=err_msg, delimiter=" ", last=".") messages.error(request, exit_message) return HttpResponseRedirect(reverse('api:v1:home')) if settings.DEBUG: print("Request.GET :", request.GET) print("KWargs :", kwargs) print("Crosswalk :", xwalk) print("GUID :", xwalk.guid) print("FHIR :", xwalk.fhir) print("FHIR URL ID :", xwalk.fhir_url_id) # We should have the xwalk.FHIR_url_id # So we will construct the EOB Identifier to include # We will deal internally in JSON Format if caller does not choose # a format in_fmt = "json" get_fmt = get_format(request.GET) # DONE: Define Transaction Dictionary to enable generic presentation of API Call Txn = { 'name': "ExplanationOfBenefit", 'display': 'EOB', 'mask': True, # 'server': settings.FHIR_SERVER, # 'locn': "/baseDstu2/ExplanationOfBenefit/", 'template': 'v1api/eob.html', 'in_fmt': in_fmt, } skip_parm = ['_id', '_format'] key = xwalk.fhir_url_id.strip() mask = False if 'mask' in Txn: mask = Txn['mask'] pass_to = FhirServerUrl() pass_to += "/ExplanationOfBenefit/" # We can allow an EOB but we MUST add a search Parameter # to limit the items found to those relevant to the Patient Id if eob_id: pass_to = pass_to + eob_id + "/" # Now apply the search restriction to limit to patient _id #pass_to = pass_to + key + "/" pass_to = pass_to + "?patient=" pass_to = pass_to + "Patient/" pass_to = pass_to + xwalk.fhir_url_id.strip() pass_to = pass_to + "&" + build_params(request.GET, skip_parm) if settings.DEBUG: print("Pass_to from build_params:", pass_to) if settings.DEBUG: print("Calling requests with pass_to:", pass_to) # Set Context context = { 'display': Txn['display'], 'name': Txn['name'], 'mask': mask, 'key': key, 'get_fmt': get_fmt, 'in_fmt': Txn['in_fmt'], # 'output' : "test output ", # 'args' : args, # 'kwargs' : kwargs, # 'get' : request.GET, 'pass_to': pass_to, } try: r = requests.get(pass_to) if get_fmt == "xml": xml_text = minidom.parseString(r.text) pretty_xml = xml_text.toprettyxml() context['result'] = pretty_xml # convert context['text'] = pretty_xml return HttpResponse(context['result'], content_type='application/' + get_fmt) else: # get_fmt == "json" or None: convert = OrderedDict(r.json()) # result = mark_safe(convert) if settings.DEBUG: print("Convert:", convert) content = OrderedDict(convert) text = "" context['result'] = r.json() # convert if 'text' in content: context['text'] = content['text']['div'] if 'issue' in content: context['error'] = content['issue'] else: if settings.DEBUG: print("Resource:", convert['entry']) context['text'] = convert['entry'] if get_fmt == "json": return JsonResponse(context['result'], ) return render_to_response(Txn['template'], RequestContext( request, context, )) except requests.ConnectionError: print("Whoops - Problem connecting to FHIR Server") messages.error( request, "FHIR Server is unreachable. " "Are you on the CMS Network?") return HttpResponseRedirect(reverse('api:v1:home'))
def get_eob(request, Access_Mode=None, *args, **kwargs): """ Display one or more EOBs but Always limit scope to Patient_Id :param request: :param eob_id: Request a specific EOB :param args: :param kwargs: :return: """ if settings.DEBUG: print("Request User Beneficiary(Patient):", request.user, "\nFor EOB Enquiry ") print("Request.GET :", request.GET) print("Access_Mode :", Access_Mode) print("KWargs :", kwargs) print("Args :", args) if Access_Mode == "OPEN" and kwargs['patient_id'] != "": # Lookup using patient_id for fhir_url_id key = kwargs['patient_id'].strip() else: try: xwalk = Crosswalk.objects.get(user=request.user) except Crosswalk.DoesNotExist: messages.error(request, "Unable to find Patient ID") return HttpResponseRedirect(reverse('api:v1:home')) if xwalk.fhir_url_id == "": err_msg = [ 'Sorry, We were unable to find', 'your record', ] exit_message = concat_string("", msg=err_msg, delimiter=" ", last=".") messages.error(request, exit_message) return HttpResponseRedirect(reverse('api:v1:home')) key = xwalk.fhir_url_id.strip() if settings.DEBUG: print("FHIR URL ID :", key) # We should have the xwalk.FHIR_url_id # So we will construct the EOB Identifier to include # This is a hack to limit EOBs returned to this user only. # id_source['system'] = "https://mymedicare.gov/claims/beneficiary" # id_source['use'] = "official" # id_source['value'] = "Patient/"+str(patient_id) # id_list.append(unique_id(id_source)) # this search works: # http://fhir.bbonfhir.com:8080/fhir-p/ # search?serverId=bbonfhir_dev # &resource=ExplanationOfBenefit # ¶m.0.0=https%3A%2F%2Fmymedicare.gov%2Fclaims%2Fbeneficiary # ¶m.0.1=Patient%2F4995401 # ¶m.0.name=identifier # ¶m.0.type=token # &sort_by= # &sort_direction= # &resource-search-limit= # http://ec2-52-4-198-86.compute-1.amazonaws.com:8081/baseDstu2/ # ExplanationOfBenefit/?patient=Patient/131052&_format=json # # We will deal internally in JSON Format if caller does not choose # a format in_fmt = "json" get_fmt = get_format(request.GET) # DONE: Define Transaction Dictionary to enable generic presentation of API Call Txn = { 'name': "ExplanationOfBenefit", 'display': 'EOB', 'mask': True, 'template': 'v1api/eob.html', 'in_fmt': in_fmt, } skip_parm = ['_id', '_format', 'patient'] mask = True pass_to = FhirServerUrl() pass_to += "/ExplanationOfBenefit" pass_to += "/" # We can allow an EOB but we MUST add a search Parameter # to limit the items found to those relevant to the Patient Id #if eob_id: # pass_to = eob_id + "/" # Now apply the search restriction to limit to patient _id #pass_to = pass_to + key + "/" pass_to += "?patient=" pass_to += "Patient/" pass_to += key pass_to = pass_to + "&" + build_params(request.GET, skip_parm)[1:] if settings.DEBUG: print("Pass_to from build_params:", pass_to) if settings.DEBUG: print("Calling requests with pass_to:", pass_to) # Set Context context = { 'display': 'EOB', 'name': 'ExplanationOfBenefit', 'mask': mask, 'key': key, 'get_fmt': get_fmt, 'in_fmt': in_fmt, 'pass_to': pass_to, } try: r = requests.get(pass_to) context = process_page(request, r, context) # Setup the page if settings.DEBUG: print("Context-result:", context['result']) # print("Context-converted:", json.dumps(context['result'], sort_keys=False)) # print("Context:",context) if get_fmt == 'xml' or get_fmt == 'json': if settings.DEBUG: print("Mode = ", get_fmt) print("Context['result']: ", context['result']) if get_fmt == "xml": return HttpResponse(context['result'], content_type='application/' + get_fmt) if get_fmt == "json": #return HttpResponse(context['result'], mimetype="application/json") return JsonResponse(context['import_text'], safe=False) else: if context[ 'text'] == "No user readable content to display" or context[ 'text'] == "": result = json.loads(context['result'], object_pairs_hook=OrderedDict) print("Result::", result) context[ 'text'] += "<br/> extracting information from returned record:<br/>" context['text'] += "<table>\n" if 'name' in result: patient_name = result['name'][0]['given'][0] patient_name += " " patient_name += result['name'][0]['family'][0] context['text'] += tr_build_item( "Patient Name ", patient_name) if 'address' in result: context['text'] += tr_build_item( "Patient Address", result['address'][0]['line'][0]) if 'birthDate' in result: context['text'] += tr_build_item("Birth Date", result['birthDate']) if 'identifier' in result: context['text'] += tr_build_item( "Patient ID", result['identifier'][0]['value']) context['text'] += "</table>" return render_to_response('v1api/eob.html', RequestContext( request, context, )) except requests.ConnectionError: print("Whoops - Problem connecting to FHIR Server") messages.error( request, "FHIR Server is unreachable. " "Are you on the CMS Network?") return HttpResponseRedirect(reverse('api:v1:home'))