def test_pretty_json(self): """ Test text dict or list is converted to pretty json(indent=4) """ od = '{"format": ["application/xml+fhir","application/json+fhir"]}' response = pretty_json(od, indent=5) expected = '"{\\"format\\": [\\"application/xml+fhir\\",' '\\"application/json+fhir\\"]}"' self.assertEqual(response, expected)
def test_pretty_json(self): """ Test text dict or list is converted to pretty json(indent=4) """ od = '{"format": ["application/xml+fhir","application/json+fhir"]}' response = pretty_json(od, indent=5) expected = '"{\\"format\\": [\\"application/xml+fhir\\",' \ '\\"application/json+fhir\\"]}"' self.assertEqual(response, expected)
def test_fetch(self, mock_requests): request = self.factory.get('http://someurl.com/test.text') mock_requests.get.return_value.status_code = 200 mock_requests.get.return_value.text = CONFORMANCE mock_requests.get.return_value.json = pretty_json({"field": "My text " "is here" "!!!!"}) resp = request_call(request, "http://someurl.com/test.text") # print("\nResp.text:\n%s" % resp.text) # print("\nResp.json:\n%s" % resp.json) self.assertEqual(resp.text[:100], CONFORMANCE[:100])
def test_fetch(self, mock_requests): request = self.factory.get('http://someurl.com/test.text') mock_requests.get.return_value.status_code = 200 mock_requests.get.return_value.text = CONFORMANCE mock_requests.get.return_value.json = pretty_json({"field": "My text " "is here" "!!!!"}) resp = request_call(request, "http://someurl.com/test.text", cx=None) # print("\nResp.text:\n%s" % resp.text) # print("\nResp.json:\n%s" % resp.json) self.assertEqual(resp.text[:100], CONFORMANCE[:100])
def test_fetch(self, mock_requests): # rr_id = self.resrtr.id # print("\nResRtr-testfetch:%s=%s\n" % (rr_id, self.resrtr)) # rr = get_resourcerouter() # print("\nRR-testfetch:%s\n" % rr) request = self.factory.get('http://someurl.com/test.text') mock_requests.get.return_value.status_code = 200 mock_requests.get.return_value.text = CONFORMANCE mock_requests.get.return_value.json = pretty_json( {"field": "My text " "is here" "!!!!"}) resp = request_call(request, "http://someurl.com/test.text", cx=None) # print("\nResp.text:\n%s" % resp.text) # print("\nResp.json:\n%s" % resp.json) self.assertEqual(resp.text[:100], CONFORMANCE[:100])
def convert_bb(request): """ Read bb_text from CrossWalk Convert to JSON (bb_to_json) Analyze JSON Get Claims Search for Claims Check for Unique Patient Get Unique Patient Store ID in Crosswalk """ try: xwalk = Crosswalk.objects.get(user=request.user) except Crosswalk.DoesNotExist: xwalk = Crosswalk() xwalk.user = request.user # We may want to add the default FHIR Server to the crosswalk entry # before we save. # xwalk.fhir_source = xwalk.save() # Do we have Blue Button text to work with? bb_text = check_for_bb_text(xwalk.user) if not bb_text: return HttpResponseRedirect(reverse('home')) # Convert from text to JSON bb_result = bb_to_json(request, bb_text.bb_content) bb_json = bb_result['mmg_bbjson'] # print("JSON:", bb_result['mmg_bbjson']) # Extract Claims from bb_json bb_claims = getbbclm(request, bb_result['mmg_bbjson']) # print("\nClaims:", bb_claims) fhir_claims = eval_claims(request, bb_claims) # Take bb_claims and get a unique list of patients # Hopefully we only have ONE bb_patient_ids = unique_keys(fhir_claims, key="patient") # print("Patient IDs:", bb_patient_ids) if len(bb_patient_ids) is 0: # We have a problem... # Too many or Too Few Patient IDs returned from Claims messages.error(request, "Unable to find a Patient Match") elif len(bb_patient_ids) > 1: messages.error(request, "Unable to match to a unique Patient ID") else: messages.info(request, "We found a match %s" % bb_patient_ids[0]) if not xwalk.fhir_id: # We need the Id from Patient ID # It should be in format Patient/{ID} fhir_id = bb_patient_ids[0].split('/') if len(fhir_id) > 1: fhir_id_num = fhir_id[-1] xwalk.fhir_id = fhir_id_num mc_prof = {} if bb_json['result'] == "OK": mc_prof['bb_json'] = bb_json['mmg_bbjson'] mc_prof['email'] = get_bbemail(request, bb_json) mc_prof['profile'] = get_bbprof(request, bb_json) # Extract claims from Blue Button JSON mc_prof['claims'] = getbbclm(request, bb_json) return render(request, 'eimm/bluebutton_analytics.html', {'content': bb_json, 'profile': mc_prof, 'profilep': pretty_json(mc_prof['profile']), 'claimsp': pretty_json(mc_prof['claims']) }) return HttpResponseRedirect(reverse('home'))
def connect_first(request): """ Prompt for MyMedicare.gov user and password Ask for confirmation to connect to MyMedicare.gov call connect with userid and password :param request: :return: """ try: xwalk = Crosswalk.objects.get(user=request.user) except Crosswalk.DoesNotExist: xwalk = Crosswalk() xwalk.user = request.user # We may want to add the default FHIR Server to the crosswalk entry # before we save. # xwalk.fhir_source = xwalk.save() xwalk = Crosswalk.objects.get(user=request.user) form = Medicare_Connect() # logger.debug("In eimm.mym_login.connect_first:" # "User:%s \nCrosswalk:%s" % (xwalk.user, xwalk)) if request.POST: form = Medicare_Connect(request.POST) if form.is_valid(): if form.cleaned_data['mmg_user'] and form.cleaned_data['mmg_pwd']: context = {} # make the call # logger.debug("MAKING THE CALL with:", # form.cleaned_data['mmg_user'], # "and ", form.cleaned_data['mmg_pwd']) mmg = {} mmg['mmg_user'] = form.cleaned_data['mmg_user'] mmg['mmg_pwd'] = form.cleaned_data['mmg_pwd'] # see if the call works mmg = connect(request, mmg) if mmg['status'] == 'FAIL': # we had a problem with login messages.info(request, mark_safe("Do you need to connect to " "<a href='https://mymedicare.gov'" " target='_blank'>" "MyMedicare.gov</a> to check your" " account?")) return render(request, 'eimm/medicare_connect.html', {'form': form}) # Now we go and get the BlueButton Text file mmg_bb = get_bluebutton(request, mmg) # mmg_mail = {} # logger.debug("Blue Button returned:", mmg_bb) mc_prof = {} if mmg_bb['status'] == "OK": pretty_name = pretty_json(split_name(mmg['mmg_name'])) mc_prof['user'] = mmg['mmg_user'] mc_prof['password'] = mmg['mmg_pwd'] mc_prof['name'] = mmg['mmg_name'] mc_prof['HumanName'] = pretty_name mc_prof['account'] = mmg['mmg_account'] # need to check what is returned in mmg_account. messages.success(request, "Connection succeeded for " + mc_prof['name'] + "[" + mc_prof['user'] + "].") # Update the Medicare user name to the Crosswalk if xwalk.mb_user == '': xwalk.mb_user = mc_prof['user'] if mmg_bb['status'] == "OK": # We need to save the Blue Button Text # print("We are okay to update mmg_bbdata", # "\n with ", mmg_bb['mmg_bbdata'][:250]) mc_prof['bb_data'] = mmg_bb['mmg_bbdata'] # Save the Blue Button text to the Crosswalk # TODO: Save to BlueButtonText write_bb_text = bb_update_or_create(xwalk.user, mmg_bb['mmg_bbdata']) # xwalk.bb_text = mmg_bb['mmg_bbdata'] if write_bb_text: bb_text = mmg_bb['mmg_bbdata'] else: bb_text = '{}' # Convert the text to JSON result = bb_to_json(request, bb_text) # logger.debug("BB Conversion:", result) if result['result'] == "OK": mc_prof['bb_json'] = result['mmg_bbjson'] mc_prof['email'] = get_bbemail(request, mc_prof['bb_json']) mc_prof['profile'] = get_bbprof(request, mc_prof['bb_json']) # Extract claims from Blue Button JSON mc_prof['claims'] = getbbclm(request, mc_prof['bb_json']) # logger.debug("returned json from xwalk:", result) # for key, value in xwalk.mmg_bbjson.items(): # # print("Key:", key) # if key == "patient": # for k, v in value.items(): # # print("K:", k, "| v:", v) # if k == "email": # xwalk.mmg_email = v # if not xwalk.mmg_bbfhir: # if result['result'] == "OK": # outcome = json_to_eob(request) # if outcome['result'] == "OK": # xwalk.mmg_bbfhir = True # if mmg_mail['status'] == "OK": # xwalk.mmg_email = mmg_mail['mmg_email'] # Save the Crosswalk changes xwalk.save() context['mmg'] = mmg return render(request, 'eimm/bluebutton_analytics.html', {'content': context, 'profile': mc_prof, 'profilep': pretty_json(mc_prof['profile']), 'claimsp': pretty_json(mc_prof['claims']) }) else: form = Medicare_Connect() # logger.debug("setting up the GET:") return render(request, 'eimm/medicare_connect.html', {'form': form})
def generic_read(request, interaction_type, resource_type, id=None, vid=None, *args, **kwargs): """ Read from remote FHIR Server :param request: :param interaction_type: :param resource_type: :param id: :param vid: :param args: :param kwargs: :return: # Example client use in curl: # curl -X GET http://127.0.0.1:8000/fhir/Practitioner/1234 Process flow: Is it a valid request? Get the target server info Get the request modifiers Construct the call Make the call Check result for errors Deliver the formatted result """ # DONE: Fix to allow url_id in url for non-key resources. # eg. Patient is key resource so replace url if override_url_id is True # if override_url_id is not set allow url_id to be applied and check # if search_override is True. # interaction_type = 'read' or '_history' or 'vread' or 'search' logger.debug('\n========================\n' 'INTERACTION_TYPE: %s' % interaction_type) # Get the users crosswalk cx = get_crosswalk(request.user) # cx will be the crosswalk record or None rr = get_resourcerouter(cx) # Check if this interaction type and resource type combo is allowed. deny = check_access_interaction_and_resource_type(resource_type, interaction_type, rr) if deny: # if not allowed, return a 4xx error. return deny srtc = check_rt_controls(resource_type, rr) # We get back a Supported ResourceType Control record or None # with earlier if deny step we should have a valid srtc. if srtc.secure_access and request.user.is_anonymous(): return kickout_403('Error 403: %s Resource access is controlled.' ' Login is required:' '%s' % (resource_type, request.user.is_anonymous())) # logger.debug('srtc: %s' % srtc) if cx is None: logger.debug('Crosswalk for %s does not exist' % request.user) if (cx is None and srtc is not None): # There is a srtc record so we need to check override_search if srtc.override_search: # If user is not in Crosswalk and srtc has search_override = True # We need to prevent search to avoid data leakage. return kickout_403('Error 403: %s Resource is access controlled.' ' No records are linked to user:'******'%s' % (resource_type, request.user)) # Need to check if user is logged in. # request.user.is_anonymous() # # if request.user.is_anonymous(): # Request.user = user # interaction_type = read | _history | vread # resource_type = 'Patient | Practitioner | ExplanationOfBenefit ...' # id = fhir_id (potentially masked) # vid = Version Id # Check the resource_type to see if it has a url # Check the resource_type to see if masking is required # Get the FHIR_Server (from crosswalk via request.user) # if masked get the fhir_id from crosswalk # if search_override strip search items (search_block) # if search_override add search keys fhir_url = '' # change source of default_url to ResourceRouter default_path = get_default_path(srtc.resource_name, cx=cx) # get the default path for resource with ending "/" # You need to add resource_type + "/" for full url if srtc: # logger.debug('SRTC:%s' % srtc) fhir_url = default_path + resource_type + '/' if srtc.override_url_id: fhir_url += cx.fhir_id + "/" # logger.debug('fhir_url:%s' % fhir_url) else: logger.debug('CX:%s' % cx) if cx: fhir_url = cx.get_fhir_resource_url(resource_type) else: # logger.debug('FHIRServer:%s' % FhirServerUrl()) fhir_url = FhirServerUrl() + resource_type + '/' # #### SEARCH if interaction_type == 'search': key = None else: key = masked_id(resource_type, cx, srtc, id, slash=False) print("\nMasked_id-key:%s from r_id:%s " "and cx-fhir_id:%s\n" % (key, id, cx.fhir_id)) # add key to fhir_url unless already in place. fhir_url = add_key_to_fhir_url(fhir_url, key) logger.debug('FHIR URL with key:%s' % fhir_url) ########################### # Now we get to process the API Call. # Internal handling format is json # Remove the oauth elements from the GET pass_params = strip_oauth(request.GET) # Let's store the inbound requested format # We need to simplify the format call to the backend # so that we get data we can manipulate requested_format = request_format(pass_params) # now we simplify the format/_format request for the back-end pass_params = strip_format_for_back_end(pass_params) if "_format" in pass_params: back_end_format = pass_params['_format'] else: back_end_format = "json" # #### SEARCH if interaction_type == 'search': if cx is not None: # logger.debug("cx.fhir_id=%s" % cx.fhir_id) if cx.fhir_id.__contains__('/'): id = cx.fhir_id.split('/')[1] else: id = cx.fhir_id # logger.debug("Patient Id:%s" % r_id) if resource_type.lower() == "patient": key = cx.fhir_id else: key = id pass_params = build_params(pass_params, srtc, key, patient_id=cx.fhir_id) # Add the call type ( READ = nothing, VREAD, _HISTORY) # Before we add an identifier key pass_to = fhir_call_type(interaction_type, fhir_url, vid) logger.debug('\nHere is the URL to send, %s now add ' 'GET parameters %s' % (pass_to, pass_params)) if pass_params is not '': pass_to += pass_params logger.debug("\nMaking request:%s" % pass_to) ############################################### ############################################### # Now make the call to the backend API if interaction_type == "search": r = request_call(request, pass_to, cx, reverse_lazy('home'), timeout=settings.REQUEST_CALL_TIMEOUT) else: r = request_call(request, pass_to, cx, reverse_lazy('home')) # BACK FROM THE CALL TO BACKEND ############################################### ############################################### # logger.debug("r returned: %s" % r) # Check for Error here try: error_check = r.text logger.debug("We got r.text back:%s" % r.text[:200] + "...") except: error_check = "HttpResponse status_code=502" logger.debug("Something went wrong with call to %s" % pass_to) logger.debug("Checking for errors:%s" % error_check[:200] + "...") if 'status_code' in error_check: # logger.debug("We have a status code to check: %s" % r) if r.status_code in ERROR_CODE_LIST: logger.debug("\nError Status Code:%s" % r.status_code) return error_status(r, r.status_code) elif 'status_code=302' in error_check: return error_status(r, 302) elif 'status_code=502' in error_check: return error_status(r, 502) else: logger.debug("Status Code:%s " "in:%s" % (r.status_code, r)) # We should have a 200 - good record to deal with # We can occasionaly get a 200 with a Connection Error. eg. Timeout try: if "ConnectionError" in r.text: logger.debug("Error:%s" % r.text) return error_status(r, 502) except: pass text_out = '' # if 'text' in r: # logger.debug('r:%s' % r.text) # logger_debug.debug('r:%s' % r.text) # else: # logger.debug("r not returning text:%s" % r) # logger_debug.debug("r not returning text:%s" % r) # logger.debug("r.json: %s" % json.dumps(r.json)) # logger.debug('Rewrite List:%s' % rewrite_url_list) host_path = get_host_url(request, resource_type)[:-1] # logger.debug('host path:%s' % host_path) # Add default FHIR Server URL to re-write rewrite_url_list = build_rewrite_list(cx) # print("Starting Rewrite_list:%s" % rewrite_url_list) # ct_detail = get_content_type(r) # logger.debug('Content-Type:%s \n work with %s' % (ct_detail, # back_end_format)) try: text_in = r.text except: text_in = "" text_out = post_process_request(request, back_end_format, host_path, text_in, rewrite_url_list) od = build_output_dict(request, OrderedDict(), resource_type, key, vid, interaction_type, requested_format, text_out) # write session variables if _getpages was found ikey = '' try: ikey = find_ikey(r.text) except: ikey = '' if ikey is not '': save_url = get_target_url(fhir_url, resource_type) # print("Store fhir_url:%s but only: %s" % (fhir_url,save_url)) content = { 'fhir_to': save_url, 'rwrt_list': rewrite_url_list, 'res_type': resource_type, 'intn_type': interaction_type, 'key': key, 'vid': vid, 'resource_router': rr.id } sesn_var = write_session(request, ikey, content, skey=SESSION_KEY) if sesn_var: logger.debug("Problem writing session variables." " Returned %s" % sesn_var) if requested_format == 'xml': # logger.debug('We got xml back in od') return HttpResponse(r.text, content_type='application/%s' % requested_format) # return HttpResponse(tostring(dict_to_xml('content', od)), # content_type='application/%s' % requested_format) elif requested_format == 'json': # logger.debug('We got json back in od') return HttpResponse(pretty_json(od['bundle']), content_type='application/%s' % requested_format) query_string = build_querystring(request.GET.copy()) if "xml" in requested_format: # logger.debug("Sending text_out for display: %s" % text_out[0:100]) div_text = get_div_from_xml(text_out) # print("DIV TEXT returned:[%s]%s" % (type(div_text), div_text)) return render( request, 'bluebutton/default_xml.html', { 'output': text_out, 'content': { 'parameters': query_string, 'resource_type': resource_type, 'request_method': "GET", 'interaction_type': interaction_type, 'div_texts': [ div_text, ], 'source': cx.fhir_source.name } }) else: text_out = pretty_json(od['bundle']) div_text = get_div_from_json(od['bundle']) # logger.debug('We got a different format:%s' % requested_format) return render( request, 'bluebutton/default.html', { 'output': text_out, 'content': { 'parameters': query_string, 'resource_type': resource_type, 'request_method': "GET", 'interaction_type': interaction_type, 'div_texts': div_text, 'source': cx.fhir_source.name } })
def generic_read(request, interaction_type, resource_type, id=None, via_oauth=False, vid=None, *args, **kwargs): """ Read from remote FHIR Server :param request: :param interaction_type: :param resource_type: :param id: :param vid: :param args: :param kwargs: :return: # Example client use in curl: # curl -X GET http://127.0.0.1:8000/fhir/Practitioner/1234 Process flow: Is it a valid request? Get the target server info Get the request modifiers - change url_id - remove unwanted search parameters - add search parameters Construct the call Make the call Check result for errors Deliver the formatted result """ # DONE: Fix to allow url_id in url for non-key resources. # eg. Patient is key resource so replace url if override_url_id is True # if override_url_id is not set allow id to be applied and check # if search_override is True. # interaction_type = 'read' or '_history' or 'vread' or 'search' logger.debug('\n========================\n' 'INTERACTION_TYPE: %s - Via Oauth:%s' % (interaction_type, via_oauth)) # if via_oauth we need to call crosswalk with if via_oauth: # get crosswalk from the resource_owner cx = get_crosswalk(request.resource_owner) else: # Get the users crosswalk cx = get_crosswalk(request.user) # cx will be the crosswalk record or None rr = get_resourcerouter(cx) # Check if this interaction type and resource type combo is allowed. deny = check_access_interaction_and_resource_type(resource_type, interaction_type, rr) if deny: # if not allowed, return a 4xx error. return deny srtc = check_rt_controls(resource_type, rr) # We get back a Supported ResourceType Control record or None # with earlier if deny step we should have a valid srtc. if not via_oauth: # we don't need to check if user is anonymous if coming via_oauth if srtc.secure_access and request.user.is_anonymous(): return kickout_403('Error 403: %s Resource access is controlled.' ' Login is required:' '%s' % (resource_type, request.user.is_anonymous())) # logger.debug('srtc: %s' % srtc) if cx is None: logger.debug('Crosswalk for %s does not exist' % request.user) if (cx is None and srtc is not None): # There is a srtc record so we need to check override_search if srtc.override_search: # If user is not in Crosswalk and srtc has search_override = True # We need to prevent search to avoid data leakage. return kickout_403('Error 403: %s Resource is access controlled.' ' No records are linked to user:'******'%s' % (resource_type, request.user)) # TODO: Compare id to cx.fhir_id and return 403 if they don't match for # Resource Type - Patient fhir_url = '' # change source of default_url to ResourceRouter default_path = get_default_path(srtc.resource_name, cx=cx) # get the default path for resource with ending "/" # You need to add resource_type + "/" for full url if srtc: # logger.debug('SRTC:%s' % srtc) fhir_url = default_path + resource_type + '/' if srtc.override_url_id: fhir_url += get_fhir_id(cx) + "/" # logger.debug('fhir_url:%s' % fhir_url) else: fhir_url += id + "/" else: logger.debug('CX:%s' % cx) if cx: fhir_url = cx.get_fhir_resource_url(resource_type) else: # logger.debug('FHIRServer:%s' % FhirServerUrl()) fhir_url = FhirServerUrl() + resource_type + '/' # #### SEARCH if interaction_type == 'search': key = None else: key = masked_id(resource_type, cx, srtc, id, slash=False) # print("\nMasked_id-key:%s from r_id:%s " # "and cx-fhir_id:%s\n" % (key, id, cx.fhir_id)) # add key to fhir_url unless already in place. fhir_url = add_key_to_fhir_url(fhir_url, key) logger.debug('FHIR URL with key:%s' % fhir_url) ########################### # Now we get to process the API Call. # Internal handling format is json # Remove the oauth elements from the GET pass_params = request.GET # Let's store the inbound requested format # We need to simplify the format call to the backend # so that we get data we can manipulate # if format is not defined and we come in via_oauth # then default to json for format requested_format = request_format(pass_params) if requested_format == "html" and via_oauth: requested_format = "json" # now we simplify the format/_format request for the back-end pass_params = strip_format_for_back_end(pass_params) if "_format" in pass_params: back_end_format = pass_params['_format'] else: back_end_format = "json" # #### SEARCH if interaction_type == 'search': if cx is not None: # logger.debug("cx.fhir_id=%s" % cx.fhir_id) if cx.fhir_id.__contains__('/'): id = get_fhir_id(cx).split('/')[1] else: id = get_fhir_id(cx) # logger.debug("Patient Id:%s" % r_id) if resource_type.lower() == "patient": key = get_fhir_id(cx) else: key = id pass_params = build_params(pass_params, srtc, key, patient_id=get_fhir_id(cx)) # Add the call type ( READ = nothing, VREAD, _HISTORY) # Before we add an identifier key pass_to = fhir_call_type(interaction_type, fhir_url, vid) logger.debug('\nHere is the URL to send, %s now add ' 'GET parameters %s' % (pass_to, pass_params)) if pass_params is not '': pass_to += pass_params logger.debug("\nMaking request:%s" % pass_to) query_string = build_querystring(request.GET.copy()) ############################################### ############################################### # Now make the call to the backend API if interaction_type == "search": r = request_call(request, pass_to, cx, reverse_lazy('home'), timeout=rr.wait_time) else: r = request_call(request, pass_to, cx, reverse_lazy('home')) # BACK FROM THE CALL TO BACKEND ############################################### ############################################### # logger.debug("r returned: %s" % r) # Check for Error here # logger.debug("what is in r:\n#######\n%s\n##########\n" % dir(r)) logger.debug("status: %s/%s" % (r.status_code, r._status_code)) # logger.debug("text: %s\n#############\n" % (r.text)) if r.status_code in ERROR_CODE_LIST: logger.debug("We have an error code to deal with: %s" % r.status_code) if 'html' in requested_format.lower(): return render( request, 'bluebutton/default.html', { 'output': pretty_json(r._content, indent=4), 'fhir_id': get_fhir_id(cx), 'content': { 'parameters': query_string, 'resource_type': resource_type, 'id': id, 'request_method': "GET", 'interaction_type': interaction_type, 'div_texts': "", 'source': get_fhir_source_name(cx) } }) else: return HttpResponse(json.dumps(r._content, indent=4), status=r.status_code, content_type='application/json') text_out = '' host_path = get_host_url(request, resource_type)[:-1] # logger.debug('host path:%s' % host_path) # Add default FHIR Server URL to re-write rewrite_url_list = build_rewrite_list(cx) # print("Starting Rewrite_list:%s" % rewrite_url_list) # ct_detail = get_content_type(r) # logger.debug('Content-Type:%s \n work with %s' % (ct_detail, # back_end_format)) text_in = get_response_text(fhir_response=r) text_out = post_process_request(request, back_end_format, host_path, text_in, rewrite_url_list) od = build_output_dict(request, OrderedDict(), resource_type, key, vid, interaction_type, requested_format, text_out) # write session variables if _getpages was found ikey = '' try: ikey = find_ikey(r.text) except Exception: ikey = '' if ikey is not '': save_url = get_target_url(fhir_url, resource_type) # print("Store fhir_url:%s but only: %s" % (fhir_url,save_url)) content = { 'fhir_to': save_url, 'rwrt_list': rewrite_url_list, 'res_type': resource_type, 'intn_type': interaction_type, 'key': key, 'vid': vid, 'resource_router': rr.id } sesn_var = write_session(request, ikey, content, skey=SESSION_KEY) if sesn_var: logger.debug("Problem writing session variables." " Returned %s" % sesn_var) if requested_format == 'xml': # logger.debug('We got xml back in od') return HttpResponse(r.text, content_type='application/%s' % requested_format) # return HttpResponse(tostring(dict_to_xml('content', od)), # content_type='application/%s' % requested_format) elif requested_format == 'json': # logger.debug('We got json back in od') return HttpResponse(pretty_json(od['bundle']), content_type='application/%s' % requested_format) # define query string further up before request_call # query_string = build_querystring(request.GET.copy()) if "xml" in requested_format: # logger.debug("Sending text_out for display: %s" % text_out[0:100]) div_text = get_div_from_xml(text_out) # print("DIV TEXT returned:[%s]%s" % (type(div_text), div_text)) return render( request, 'bluebutton/default_xml.html', { 'output': text_out, 'fhir_id': get_fhir_id(cx), 'content': { 'parameters': query_string, 'resource_type': resource_type, 'id': id, 'request_method': "GET", 'interaction_type': interaction_type, 'div_texts': [ div_text, ], 'source': get_fhir_source_name(cx) } }) else: text_out = pretty_json(od['bundle']) div_text = get_div_from_json(od['bundle']) # logger.debug('We got a different format:%s' % requested_format) logger.debug('id or key: %s/%s' % (id, key)) return render( request, 'bluebutton/default.html', { 'output': text_out, 'fhir_id': cx.fhir_id, 'content': { 'parameters': query_string, 'resource_type': resource_type, 'id': id, 'request_method': "GET", 'interaction_type': interaction_type, 'div_texts': div_text, 'source': get_fhir_source_name(cx) } })
def metadata(request, via_oauth=False, *args, **kwargs): """ Arrive here to do capabilityStatement or Conformance aka metadata oauth_fhir_conformance sets via_oauth=True fhir_conformance sets via_oauth=False :param request: :param via_oauth: :param args: :param kwargs: :return: """ cx = None rr = get_resourcerouter() call_to = FhirServerUrl() resource_type = conformance_or_capability(call_to) if call_to.endswith('/'): call_to += 'metadata' else: call_to += '/metadata' pass_params = request.GET # pass_params should be an OrderedDict after strip_auth # logger.debug("result from strip_oauth:%s" % pass_params) # Let's store the inbound requested format # We need to simplify the format call to the backend # so that we get data we can manipulate requested_format = request_format(pass_params) # now we simplify the format/_format request for the back-end pass_params = strip_format_for_back_end(pass_params) back_end_format = pass_params['_format'] encoded_params = urlencode(pass_params) # # Add ? to front of parameters if needed pass_params = prepend_q(encoded_params) # logger.debug("Calling:%s" % call_to + pass_params) query_string = build_querystring(request.GET.copy()) #################################################### #################################################### r = request_call(request, call_to + pass_params, cx, reverse_lazy('authenticated_home')) #################################################### #################################################### text_out = '' host_path = get_host_url(request, '?') if r.status_code in ERROR_CODE_LIST: logger.debug("We have an error code to deal with: %s" % r.status_code) if 'html' in requested_format.lower(): return render( request, 'bluebutton/default.html', {'output': pretty_json(r._content, indent=4), 'fhir_id': get_fhir_id(cx), 'content': {'parameters': query_string, 'resource_type': resource_type, 'id': id, 'request_method': "GET", 'interaction_type': "search", 'div_texts': "", 'source': get_fhir_source_name(cx)}}) else: return HttpResponse(json.dumps(r._content, indent=4), status=r.status_code, content_type='application/json') # get 'xml' 'json' or '' # fmt = get_search_param_format(request.META['QUERY_STRING']) # force to json # logger.debug("Format:%s" % back_end_format) rewrite_url_list = build_rewrite_list(cx) # print("Starting Rewrite_list:%s" % rewrite_url_list) text_in = get_response_text(fhir_response=r) # print("Capability text: %s\n" % r.text) # print("Capability _text: %s\n" % r._text) # text_in = r.text # if text_in == "": # print("Capability assigning _text: %s\n" % r._text[:100]) # # text_in = r._text text_out = post_process_request(request, back_end_format, host_path, text_in, rewrite_url_list) # define query string further up before request_call # query_string = build_querystring(request.GET.copy()) # logger.debug("Query:%s" % query_string) if 'xml' in requested_format: # logger.debug('We got xml back in od') # logger.debug("is xml filtered?%s" % requested_format) xml_dom = xml_to_dom(text_out) text_out = dom_conformance_filter(xml_dom, rr) # Append Security to ConformanceStatement security_endpoint = build_oauth_resource(request, format_type="xml") text_out = append_security(text_out, security_endpoint) # logger.debug("Text from XML function:\n%s\n=========" % text_out) if 'html' not in requested_format: return HttpResponse(text_out, content_type='application' '/%s' % requested_format) else: # logger.debug("Sending text_out for display: %s" % text_out[0:100]) return render( request, 'bluebutton/default_xml.html', {'output': text_out, 'content': {'parameters': query_string, 'resource_type': resource_type, 'request_method': "GET", 'interaction_type': "metadata", 'source': get_fhir_source_name(cx)}}) # return HttpResponse( tostring(dict_to_xml('content', od)), # content_type='application/%s' % fmt) else: # back_end_format == 'json' # logger.debug('We got json back in od') od = conformance_filter(text_out, back_end_format, rr) # Append Security to ConformanceStatement security_endpoint = build_oauth_resource(request, format_type="json") print("OD:\n%s" % od['rest']) od['rest'][0]['security'] = security_endpoint print("OD+Security:\n%s" % od) text_out = pretty_json(od) if 'html' not in requested_format: return HttpResponse(text_out, content_type='application/' '%s' % requested_format) if 'security' in od: print("%s" % pretty_json(od['security'], indent=4)) else: print("No security content in Conformance") print("od: %s" % pretty_json(od, indent=4)) # logger.debug('We got a different format:%s' % back_end_format) return render( request, 'bluebutton/default.html', {'output': text_out, 'content': {'parameters': query_string, 'resource_type': resource_type, 'request_method': "GET", 'interaction_type': "metadata"}})
def rebuild_fhir_search(request): """ Rebuild the Search String We will start to use a session variable We received: http://localhost:8000/cmsblue/fhir/v1 ?_getpages=61c6e2d1-2b7c-49c3-a083-3d5b3874d4ff&_getpagesoffset=10 &_count=10&_format=json&_pretty=true&_bundletype=searchset Session Variables will be storing: - FHIR Target URL/Resource - _getpages value - expires datetime Construct FHIR_Target_URL + search parameters """ # now = str(datetime.now()) ikey = '' if '_getpages' in request.GET: ikey = request.GET['_getpages'] sn_vr = read_session(request, ikey, skey=SESSION_KEY) # logger.debug("Session info:%s" % sn_vr) if sn_vr == {}: # Nothing returned from Session Variables # Key could be expired or not matched return authenticated_home(request) url_call = sn_vr['fhir_to'] url_call += '/?' + request.META['QUERY_STRING'] rewrite_url_list = sn_vr['rwrt_list'] resource_type = sn_vr['res_type'] interaction_type = sn_vr['intn_type'] key = sn_vr['key'] vid = sn_vr['vid'] cx = get_crosswalk(request.user) # logger.debug("Calling:%s" % url_call) r = request_call(request, url_call, cx, reverse_lazy('authenticated_home')) host_path = get_host_url(request, '?') # get 'xml' 'json' or '' fmt = get_search_param_format(request.META['QUERY_STRING']) text_out = post_process_request(request, fmt, host_path, r, rewrite_url_list) od = build_output_dict(request, OrderedDict(), resource_type, key, vid, interaction_type, fmt, text_out) if fmt == 'xml': # logger.debug('We got xml back in od') return HttpResponse(r.text, content_type='application/%s' % fmt) # return HttpResponse( tostring(dict_to_xml('content', od)), # content_type='application/%s' % fmt) elif fmt == 'json': # logger.debug('We got json back in od') return HttpResponse(pretty_json(od), content_type='application/%s' % fmt) # logger.debug('We got a different format:%s' % fmt) return render( request, 'bluebutton/default.html', { 'content': pretty_json(od), 'output': od }, ) return authenticated_home(request)
def __init__(self, json_data, status_code): self.content = pretty_json(json_data) self.json_data = json_data self.status_code = status_code self.ct = 1
def __init__(self, json_data, status_code): self.content = pretty_json(json_data) self.json_data = json_data self.status_code = status_code self.ct = 1
def rebuild_fhir_search(request): """ Rebuild the Search String We will start to use a session variable We received: http://localhost:8000/cmsblue/fhir/v1 ?_getpages=61c6e2d1-2b7c-49c3-a083-3d5b3874d4ff&_getpagesoffset=10 &_count=10&_format=json&_pretty=true&_bundletype=searchset Session Variables will be storing: - FHIR Target URL/Resource - _getpages value - expires datetime Construct FHIR_Target_URL + search parameters """ # now = str(datetime.now()) ikey = "" if "_getpages" in request.GET: ikey = request.GET["_getpages"] sn_vr = read_session(request, ikey, skey=SESSION_KEY) # logger.debug("Session info:%s" % sn_vr) if sn_vr == {}: # Nothing returned from Session Variables # Key could be expired or not matched return authenticated_home(request) url_call = sn_vr["fhir_to"] url_call += "/?" + request.META["QUERY_STRING"] rewrite_url_list = sn_vr["rwrt_list"] resource_type = sn_vr["res_type"] interaction_type = sn_vr["intn_type"] key = sn_vr["key"] vid = sn_vr["vid"] logger.debug("Calling:%s" % url_call) r = request_call(request, url_call, reverse_lazy("authenticated_home")) host_path = get_host_url(request, "?") # get 'xml' 'json' or '' fmt = get_search_param_format(request.META["QUERY_STRING"]) text_out = post_process_request(request, fmt, host_path, r, rewrite_url_list) od = build_output_dict(request, OrderedDict(), resource_type, key, vid, interaction_type, fmt, text_out) if fmt == "xml": # logger.debug('We got xml back in od') return HttpResponse(r.text, content_type="application/%s" % fmt) # return HttpResponse( tostring(dict_to_xml('content', od)), # content_type='application/%s' % fmt) elif fmt == "json": # logger.debug('We got json back in od') return HttpResponse(pretty_json(od), content_type="application/%s" % fmt) # logger.debug('We got a different format:%s' % fmt) return render(request, "bluebutton/default.html", {"content": pretty_json(od), "output": od}) return authenticated_home(request)
def fhir_conformance(request, *args, **kwargs): """ Pull and filter fhir Conformance statement metadata call """ if not request.user.is_authenticated(): return authenticated_home(request) resource_type = "Conformance" call_to = FhirServerUrl() if call_to.endswith("/"): call_to += "metadata" else: call_to += "/metadata" pass_params = urlencode(strip_oauth(request.GET)) # Add ? to front of parameters if needed pass_params = prepend_q(pass_params) logger.debug("Calling:%s" % call_to + pass_params) r = request_call(request, call_to + pass_params, reverse_lazy("authenticated_home")) text_out = "" host_path = get_host_url(request, "?") # get 'xml' 'json' or '' fmt = get_search_param_format(request.META["QUERY_STRING"]) rewrite_url_list = settings.FHIR_SERVER_CONF["REWRITE_FROM"] # print("Starting Rewrite_list:%s" % rewrite_url_list) text_out = post_process_request(request, fmt, host_path, r.text, rewrite_url_list) od = conformance_filter(text_out, fmt) if fmt == "xml": # logger.debug('We got xml back in od') return HttpResponse(text_out, content_type="application/%s" % fmt) # return HttpResponse( tostring(dict_to_xml('content', od)), # content_type='application/%s' % fmt) elif fmt == "json": # logger.debug('We got json back in od') return HttpResponse(pretty_json(od), content_type="application/%s" % fmt) # logger.debug('We got a different format:%s' % fmt) return render( request, "bluebutton/default.html", { "output": pretty_json(od), "content": { "parameters": request.GET.urlencode(), "resource_type": resource_type, "request_method": "GET", "interaction_type": "metadata", }, }, )
def read_search(request, interaction_type, resource_type, id=None, vid=None, *args, **kwargs): """ Read from remote FHIR Server :param request: :param interaction_type: :param resource_type: :param id: :param vid: :param args: :param kwargs: :return: # Example client use in curl: # curl -X GET http://127.0.0.1:8000/fhir/Practitioner/1234?_format=json """ logger.debug('\n========================\n' 'INTERACTION_TYPE: %s' % interaction_type) # Get the users crosswalk cx = get_crosswalk(request.user) # cx will be the crosswalk record or None rr = get_resourcerouter(cx) # Check if this interaction type and resource type combo is allowed. deny = check_access_interaction_and_resource_type(resource_type, interaction_type, rr) if deny: # if not allowed, return a 4xx error. return deny srtc = check_rt_controls(resource_type, rr) # We get back a Supported ResourceType Control record or None # with earlier if deny step we should have a valid srtc. if srtc.secure_access and request.user.is_anonymous(): return kickout_403('Error 403: %s Resource access is controlled.' ' Login is required:' '%s' % (resource_type, request.user.is_anonymous())) # logger.debug('srtc: %s' % srtc) if (cx is None and srtc is not None): # There is a srtc record so we need to check override_search if srtc.override_search: # If user is not in Crosswalk and srtc has search_override = True # We need to prevent search to avoid data leakage. return kickout_403('Error 403: %s Resource is access controlled.' ' No records are linked to user:'******'%s' % (resource_type, request.user)) ################################################ # # Now we should have sorted out all the bounces # Now to structure the call to the back-end # ################################################ # construct the server address, path and release # Get the crosswalk.fhir_source = ResourceRouter # Build url from rr.server_address + rr.server_path + rr.server_release target_url = rr.fhir_url # add resource_type + '/' target_url += srtc.resourceType target_url += "/" # Analyze the _format parameter # Sve the display _format input_parameters = request.GET # requested_format = 'json' | 'xml' | 'html' requested_format = save_request_format(input_parameters) format_mode = eval_format_type(requested_format) # prepare the back-end _format setting back_end_format = set_fhir_format(format_mode) # remove the oauth parameters payload = strip_oauth(request.GET) # Get payload with oauth parameters removed # Add the format for back-end payload['_format'] = back_end_format # remove the srtc.search_block parameters payload = block_params(payload, srtc) # print("id:%s" % str(id)) # move resource_id to _id=resource_id id_dict = set_resource_id(srtc, id, cx.fhir_id) # id_dict['query_mode'] = 'search' | 'read' # id_dict['url_id'] = '' | id # id_dict['_id'] = id | '' # id_dict['patient'] = patient_id | '' # resource_id = id_dict['url_id'] # Add the srtc.search_add parameters # added_params = add_params(srtc, # patient_id=id_dict['patient'], # key=id_dict['url_id']) # print("Added Params:%s" % added_params) params_list = search_add_to_list(srtc.search_add) # print("Params_List:%s" % params_list) payload = payload_additions(payload, params_list) # print('id_dict:%s' % id_dict) # print("what have we got?:%s" % id_dict) if id_dict['_id']: # add rt_id into the search parameters if id_dict['_id'] is not None: payload['_id'] = id_dict['_id'] if resource_type.lower() == 'patient': # print("Working resource:%s" % resource_type) payload['_id'] = id_dict['patient'] if payload['patient']: del payload['patient'] for pyld_k, pyld_v in payload.items(): if pyld_v is None: pass elif '%PATIENT%' in pyld_v: # replace %PATIENT% with cx.fhir_id payload = payload_var_replace(payload, pyld_k, new_value=id_dict['patient'], old_value='%PATIENT%') # print("post futzing:%s" % id_dict) # add the _format setting payload['_format'] = back_end_format # Make the request_call r = request_get_with_parms(request, target_url, json.loads(json.dumps(payload)), cx, reverse_lazy('home'), timeout=settings.REQUEST_CALL_TIMEOUT) ################################################ # # Now we process the response from the back-end # ################################################ # if 'status_code' in r: # r_status_code = r.status_code # else: # r_status_code = 500 rewrite_list = build_rewrite_list(cx) host_path = get_host_url(request, resource_type)[:-1] try: text_in = r.text except: text_in = "" text_out = post_process_request(request, back_end_format, host_path, text_in, rewrite_list) if resource_type.lower() == 'patient': display_key = id_dict['patient'] else: display_key = id od = build_output_dict(request, OrderedDict(), resource_type, display_key, vid, interaction_type, requested_format, text_out) ################################################ # # Now display the result # ################################################ ikey = '' try: ikey = find_ikey(r.text) except: ikey = '' if ikey is not '': save_url = get_target_url(target_url, resource_type) # print("Store target_url:%s but only: %s" % (target_url,save_url)) content = { 'fhir_to': save_url, 'rwrt_list': rewrite_list, 'res_type': resource_type, 'intn_type': interaction_type, 'key': display_key, 'vid': vid, 'resource_router': rr.id } sesn_var = write_session(request, ikey, content, skey=SESSION_KEY) if sesn_var: logger.debug("Problem writing session variables." " Returned %s" % sesn_var) if format_mode == 'xml': # logger.debug('We got xml back in od') return HttpResponse(r.text, content_type='application/%s' % requested_format) # return HttpResponse(tostring(dict_to_xml('content', od)), # content_type='application/%s' % requested_format) elif format_mode == 'json': # logger.debug('We got json back in od') return HttpResponse(pretty_json(od['bundle']), content_type='application/%s' % requested_format) query_string = build_querystring(request.GET.copy()) if "xml" in requested_format: # logger.debug("Sending text_out for display: %s" % text_out[0:100]) div_text = get_div_from_xml(text_out) # print("DIV TEXT returned:[%s]%s" % (type(div_text), div_text)) return render( request, 'bluebutton/default_xml.html', { 'output': text_out, 'content': { 'parameters': query_string, 'resource_type': resource_type, 'request_method': "GET", 'interaction_type': interaction_type, 'div_texts': [ div_text, ], 'source': cx.fhir_source.name } }) else: text_out = pretty_json(od['bundle']) div_text = get_div_from_json(od['bundle']) # logger.debug('We got a different format:%s' % requested_format) return render( request, 'bluebutton/default.html', { 'output': text_out, 'content': { 'parameters': query_string, 'resource_type': resource_type, 'request_method': "GET", 'interaction_type': interaction_type, 'div_texts': div_text, 'source': cx.fhir_source.name } })
def fhir_conformance(request, *args, **kwargs): """ Pull and filter fhir Conformance statement BaseDstu2 = "Conformance" BaseStu3 = "CapabilityStatement" metadata call """ if not request.user.is_authenticated(): return authenticated_home(request) try: cx = Crosswalk.objects.get(user=request.user) except Crosswalk.DoesNotExist: cx = None # logger.debug('Crosswalk for %s does not exist' % request.user) if cx: call_to = cx.fhir_source.fhir_url else: call_to = FhirServerUrl() resource_type = conformance_or_capability(call_to) if call_to.endswith('/'): call_to += 'metadata' else: call_to += '/metadata' pass_params = strip_oauth(request.GET) # pass_params should be an OrderedDict after strip_auth # logger.debug("result from strip_oauth:%s" % pass_params) # Let's store the inbound requested format # We need to simplify the format call to the backend # so that we get data we can manipulate requested_format = request_format(pass_params) # now we simplify the format/_format request for the back-end pass_params = strip_format_for_back_end(pass_params) back_end_format = pass_params['_format'] encoded_params = urlencode(pass_params) # # Add ? to front of parameters if needed pass_params = prepend_q(encoded_params) # logger.debug("Calling:%s" % call_to + pass_params) #################################################### #################################################### r = request_call(request, call_to + pass_params, cx, reverse_lazy('authenticated_home')) #################################################### #################################################### text_out = '' host_path = get_host_url(request, '?') # get 'xml' 'json' or '' # fmt = get_search_param_format(request.META['QUERY_STRING']) # force to json # logger.debug("Format:%s" % back_end_format) rewrite_url_list = settings.FHIR_SERVER_CONF['REWRITE_FROM'] # print("Starting Rewrite_list:%s" % rewrite_url_list) text_out = post_process_request(request, back_end_format, host_path, r.text, rewrite_url_list) query_string = build_querystring(request.GET.copy()) # logger.debug("Query:%s" % query_string) if 'xml' in requested_format: # logger.debug('We got xml back in od') # logger.debug("is xml filtered?%s" % requested_format) xml_dom = xml_to_dom(text_out) text_out = dom_conformance_filter(xml_dom) # logger.debug("Text from XML function:\n%s\n=========" % text_out) if 'html' not in requested_format: return HttpResponse(text_out, content_type='application' '/%s' % requested_format) else: # logger.debug("Sending text_out for display: %s" % text_out[0:100]) return render( request, 'bluebutton/default_xml.html', { 'output': text_out, 'content': { 'parameters': query_string, 'resource_type': resource_type, 'request_method': "GET", 'interaction_type': "metadata", 'source': cx.fhir_source.name } }) # return HttpResponse( tostring(dict_to_xml('content', od)), # content_type='application/%s' % fmt) elif back_end_format == 'json': # logger.debug('We got json back in od') od = conformance_filter(text_out, back_end_format) text_out = pretty_json(od) if 'html' not in requested_format: return HttpResponse(text_out, content_type='application/' '%s' % requested_format) else: # let's make sure we have json to deliver: od = conformance_filter(text_out, back_end_format) text_out = pretty_json(od) # logger.debug('We got a different format:%s' % back_end_format) return render( request, 'bluebutton/default.html', { 'output': text_out, 'content': { 'parameters': query_string, 'resource_type': resource_type, 'request_method': "GET", 'interaction_type': "metadata", 'source': cx.fhir_source.name } })
def connect_first(request): """ Prompt for MyMedicare.gov user and password Ask for confirmation to connect to MyMedicare.gov call connect with userid and password :param request: :return: """ try: xwalk = Crosswalk.objects.get(user=request.user) except Crosswalk.DoesNotExist: xwalk = Crosswalk() xwalk.user = request.user # We may want to add the default FHIR Server to the crosswalk entry # before we save. # xwalk.fhir_source = xwalk.save() xwalk = Crosswalk.objects.get(user=request.user) form = Medicare_Connect() # logger.debug("In eimm.mym_login.connect_first:" # "User:%s \nCrosswalk:%s" % (xwalk.user, xwalk)) if request.POST: form = Medicare_Connect(request.POST) if form.is_valid(): if form.cleaned_data['mmg_user'] and form.cleaned_data['mmg_pwd']: context = {} # make the call # logger.debug("MAKING THE CALL with:", # form.cleaned_data['mmg_user'], # "and ", form.cleaned_data['mmg_pwd']) mmg = {} mmg['mmg_user'] = form.cleaned_data['mmg_user'] mmg['mmg_pwd'] = form.cleaned_data['mmg_pwd'] # see if the call works mmg = connect(request, mmg) if mmg['status'] == 'FAIL': # we had a problem with login messages.info( request, mark_safe("Do you need to connect to " "<a href='https://mymedicare.gov'" " target='_blank'>" "MyMedicare.gov</a> to check your" " account?")) return render(request, 'eimm/medicare_connect.html', {'form': form}) # Now we go and get the BlueButton Text file mmg_bb = get_bluebutton(request, mmg) # mmg_mail = {} # logger.debug("Blue Button returned:", mmg_bb) mc_prof = {} if mmg_bb['status'] == "OK": pretty_name = pretty_json(split_name(mmg['mmg_name'])) mc_prof['user'] = mmg['mmg_user'] mc_prof['password'] = mmg['mmg_pwd'] mc_prof['name'] = mmg['mmg_name'] mc_prof['HumanName'] = pretty_name mc_prof['account'] = mmg['mmg_account'] # need to check what is returned in mmg_account. messages.success( request, "Connection succeeded for " + mc_prof['name'] + "[" + mc_prof['user'] + "].") # Update the Medicare user name to the Crosswalk if xwalk.mb_user == '': xwalk.mb_user = mc_prof['user'] if mmg_bb['status'] == "OK": # We need to save the Blue Button Text # print("We are okay to update mmg_bbdata", # "\n with ", mmg_bb['mmg_bbdata'][:250]) mc_prof['bb_data'] = mmg_bb['mmg_bbdata'] # Save the Blue Button text to the Crosswalk # TODO: Save to BlueButtonText write_bb_text = bb_update_or_create( xwalk.user, mmg_bb['mmg_bbdata']) # xwalk.bb_text = mmg_bb['mmg_bbdata'] if write_bb_text: bb_text = mmg_bb['mmg_bbdata'] else: bb_text = '{}' # Convert the text to JSON result = bb_to_json(request, bb_text) # logger.debug("BB Conversion:", result) if result['result'] == "OK": mc_prof['bb_json'] = result['mmg_bbjson'] mc_prof['email'] = get_bbemail( request, mc_prof['bb_json']) mc_prof['profile'] = get_bbprof( request, mc_prof['bb_json']) # Extract claims from Blue Button JSON mc_prof['claims'] = getbbclm( request, mc_prof['bb_json']) # logger.debug("returned json from xwalk:", result) # for key, value in xwalk.mmg_bbjson.items(): # # print("Key:", key) # if key == "patient": # for k, v in value.items(): # # print("K:", k, "| v:", v) # if k == "email": # xwalk.mmg_email = v # if not xwalk.mmg_bbfhir: # if result['result'] == "OK": # outcome = json_to_eob(request) # if outcome['result'] == "OK": # xwalk.mmg_bbfhir = True # if mmg_mail['status'] == "OK": # xwalk.mmg_email = mmg_mail['mmg_email'] # Save the Crosswalk changes xwalk.save() context['mmg'] = mmg return render( request, 'eimm/bluebutton_analytics.html', { 'content': context, 'profile': mc_prof, 'profilep': pretty_json(mc_prof['profile']), 'claimsp': pretty_json(mc_prof['claims']) }) else: form = Medicare_Connect() # logger.debug("setting up the GET:") return render(request, 'eimm/medicare_connect.html', {'form': form})
def convert_bb(request): """ Read bb_text from CrossWalk Convert to JSON (bb_to_json) Analyze JSON Get Claims Search for Claims Check for Unique Patient Get Unique Patient Store ID in Crosswalk """ try: xwalk = Crosswalk.objects.get(user=request.user) except Crosswalk.DoesNotExist: xwalk = Crosswalk() xwalk.user = request.user # We may want to add the default FHIR Server to the crosswalk entry # before we save. # xwalk.fhir_source = xwalk.save() # Do we have Blue Button text to work with? bb_text = check_for_bb_text(xwalk.user) if not bb_text: return HttpResponseRedirect(reverse('home')) # Convert from text to JSON bb_result = bb_to_json(request, bb_text.bb_content) bb_json = bb_result['mmg_bbjson'] # print("JSON:", bb_result['mmg_bbjson']) # Extract Claims from bb_json bb_claims = getbbclm(request, bb_result['mmg_bbjson']) # print("\nClaims:", bb_claims) fhir_claims = eval_claims(request, bb_claims) # Take bb_claims and get a unique list of patients # Hopefully we only have ONE bb_patient_ids = unique_keys(fhir_claims, key="patient") # print("Patient IDs:", bb_patient_ids) if len(bb_patient_ids) is 0: # We have a problem... # Too many or Too Few Patient IDs returned from Claims messages.error(request, "Unable to find a Patient Match") elif len(bb_patient_ids) > 1: messages.error(request, "Unable to match to a unique Patient ID") else: messages.info(request, "We found a match %s" % bb_patient_ids[0]) if not xwalk.fhir_id: # We need the Id from Patient ID # It should be in format Patient/{ID} fhir_id = bb_patient_ids[0].split('/') if len(fhir_id) > 1: fhir_id_num = fhir_id[-1] xwalk.fhir_id = fhir_id_num mc_prof = {} if bb_json['result'] == "OK": mc_prof['bb_json'] = bb_json['mmg_bbjson'] mc_prof['email'] = get_bbemail(request, bb_json) mc_prof['profile'] = get_bbprof(request, bb_json) # Extract claims from Blue Button JSON mc_prof['claims'] = getbbclm(request, bb_json) return render( request, 'eimm/bluebutton_analytics.html', { 'content': bb_json, 'profile': mc_prof, 'profilep': pretty_json(mc_prof['profile']), 'claimsp': pretty_json(mc_prof['claims']) }) return HttpResponseRedirect(reverse('home'))
def generic_read(request, interaction_type, resource_type, r_id=None, vid=None, *args, **kwargs): """ Read from remote FHIR Server :param request: :param interaction_type: :param resource_type: :param id: :param vid: :param args: :param kwargs: :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' or 'search' logger.debug('interaction_type: %s' % 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 a Supported ResourceType Control record or None # with earlier if deny step we should have a valid srtc. default_path = get_default_path(srtc.resource_name) # get the default path for resource with ending "/" # You need to add resource_type + "/" for full url logger.debug('srtc: %s' % srtc) try: cx = Crosswalk.objects.get(user=request.user) except Crosswalk.DoesNotExist: cx = None # logger.debug('Crosswalk for %s does not exist' % request.user) if (cx is None and srtc is not None): # There is a srtc record so we need to check override_search if srtc.override_search: # If user is not in Crosswalk and srtc has search_override = True # We need to prevent search to avoid data leakage. return kickout_403('Error 403: %s Resource is access controlled.' ' No records are linked to user:'******'%s' % (resource_type, request.user)) # Request.user = user # interaction_type = read | _history | vread # resource_type = 'Patient | Practitioner | ExplanationOfBenefit ...' # id = fhir_id (potentially masked) # vid = Version Id # Check the resource_type to see if it has a url # Check the resource_type to see if masking is required # Get the FHIR_Server (from crosswalk via request.user) # if masked get the fhir_id from crosswalk # if search_override strip search items (search_block) # if search_override add search keys fhir_url = '' # change source of default_url to ResourceRouter # Add default FHIR Server URL to re-write rewrite_url_list = settings.FHIR_SERVER_CONF['REWRITE_FROM'] # print("Starting Rewrite_list:%s" % rewrite_url_list) if srtc: logger.debug('SRTC:%s' % srtc) fhir_url = default_path + resource_type + '/' # Add to the rewrite_url list rewrite_url_list.append(default_path) else: logger.debug('CX:%s' % cx) if cx: fhir_url = cx.get_fhir_resource_url(resource_type) rewrite_url_list.append(fhir_url.replace(resource_type + '/', '')) else: # logger.debug('FHIRServer:%s' % FhirServerUrl()) fhir_url = FhirServerUrl() + resource_type + '/' if FhirServerUrl()[:-1] not in rewrite_url_list: rewrite_url_list.append(FhirServerUrl()[:-1]) logger.debug('FHIR URL:%s' % fhir_url) logger.debug('Rewrite List:%s' % rewrite_url_list) if interaction_type == 'search': key = None else: key = masked_id(resource_type, cx, srtc, r_id, slash=False) if fhir_url.endswith(resource_type + '/'): # we need to make sure we don't specify resource_type twice in URL if key.startswith(resource_type + '/'): key = key.replace(resource_type + '/', '') fhir_url += key + '/' logger.debug('FHIR URL with key:%s' % fhir_url) ########################### # Now we get to process the API Call. # Internal handling format is json # Remove the oauth elements from the GET pass_params = strip_oauth(request.GET) if interaction_type == 'search': if cx is not None: logger.debug("cx.fhir_id=%s" % cx.fhir_id) r_id = cx.fhir_id.split('/')[1] logger.debug("Patient Id:%s" % r_id) if resource_type == "Patient": key = r_id pass_params = build_params(pass_params, srtc, # key, r_id, ) if interaction_type == 'vread': pass_to = fhir_url + '_history' + '/' + vid elif interaction_type == '_history': pass_to = fhir_url + '_history' else: # interaction_type == 'read': pass_to = fhir_url logger.debug('Here is the URL to send, %s now add ' 'GET parameters %s' % (pass_to, pass_params)) if pass_params is not '': pass_to += pass_params logger.debug("Making request:%s" % pass_to) # Now make the call to the backend API r = request_call(request, pass_to, reverse_lazy('api:v1:home')) text_out = '' if 'text' in r: logger.debug('r:%s' % r.text) else: logger.debug("r not returning text:%s" % r) # logger.debug('Rewrite List:%s' % rewrite_url_list) host_path = get_host_url(request, resource_type)[:-1] logger.debug('host path:%s' % host_path) # get 'xml' 'json' or '' fmt = get_search_param_format(pass_params) text_out = post_process_request(request, fmt, host_path, r.text, rewrite_url_list) od = build_output_dict(request, OrderedDict(), resource_type, key, vid, interaction_type, fmt, text_out) # write session variables if _getpages was found ikey = find_ikey(r.text) if ikey is not '': save_url = get_target_url(fhir_url, resource_type) # print("Store fhir_url:%s but only: %s" % (fhir_url,save_url)) content = { 'fhir_to': save_url, 'rwrt_list': rewrite_url_list, 'res_type': resource_type, 'intn_type': interaction_type, 'key': key, 'vid': vid } sesn_var = write_session(request, ikey, content, skey=SESSION_KEY) if sesn_var: logger.debug("Problem writing session variables." " Returned %s" % sesn_var) if fmt == 'xml': # logger.debug('We got xml back in od') return HttpResponse(r.text, content_type='application/%s' % fmt) # return HttpResponse( tostring(dict_to_xml('content', od)), # content_type='application/%s' % fmt) elif fmt == 'json': # logger.debug('We got json back in od') return HttpResponse(pretty_json(od), content_type='application/%s' % fmt) # logger.debug('We got a different format:%s' % fmt) return render( request, 'bluebutton/default.html', {'content': pretty_json(od), 'output': od}, )