def proxy_post(request): """ To act as a proxy for POST requests from Phenotips note: exempting csrf here since phenotips doesn't have this support """ try: # print type(pickle.loads(request.session['current_phenotips_session'])) # re-construct proxy-ed URL again url, parameters = __aggregate_url_parameters(request) project_name = request.session['current_project_id'] uname, pwd = get_uname_pwd_for_project(project_name) curr_session = pickle.loads( request.session['current_phenotips_session']) response = curr_session.post(url, data=dict(request.POST)) http_response = HttpResponse(response.content) for header in response.headers.keys(): if header != 'connection' and header != 'Transfer-Encoding': # these hop-by-hop headers are not allowed by Django http_response[header] = response.headers[header] # persist outside of PhenoTips db as well if len(request.POST) != 0: patient_id = request.session['current_patient_id'] __process_sync_request_helper( patient_id, request.user, project_name, parameters, pickle.loads(request.session['current_phenotips_session'])) return http_response except Exception as e: print 'proxy post error:', e logger.error('phenotips.views:' + str(e)) raise Http404
def fetch_phenotips_pdf_page(request, eid): """ A proxy for phenotips view and edit patient pages Notes: - Exempting csrf here since phenotips doesn't have this support - Each call to this endpoint is atomic, no session information is kept between calls. Each call to this is from within a new Frame, hence no notion of session is kept. Each is a new login into PhenoTips. """ try: current_user = request.user project_id = request.GET['project'] uname, pwd = get_uname_pwd_for_project(project_id, read_only=True) patient_id = get_phenotips_internal_id(eid, project_id) auth_level = get_auth_level(project_id, request.user) if auth_level == 'unauthorized': raise PermissionDenied url = settings.PHENOPTIPS_BASE_URL + '/bin/export/data/' + patient_id + '?format=pdf&pdfcover=0&pdftoc=0&pdftemplate=PhenoTips.PatientSheetCode' response, curr_session = do_authenticated_call_to_phenotips( url, uname, pwd) http_response = HttpResponse(response.content) for header in response.headers.keys(): if header != 'connection' and header != 'Transfer-Encoding': # these hop-by-hop headers are not allowed by Django http_response[header] = response.headers[header] return http_response except Exception as e: print e raise Http404
def fetch_phenotips_pdf_page(request, eid): """ A proxy for phenotips view and edit patient pages Notes: - Exempting csrf here since phenotips doesn't have this support - Each call to this endpoint is atomic, no session information is kept between calls. Each call to this is from within a new Frame, hence no notion of session is kept. Each is a new login into PhenoTips. """ try: current_user = request.user project_id = request.GET['project'] uname, pwd = get_uname_pwd_for_project(project_id, read_only=True) patient_id = get_phenotips_internal_id(eid, project_id) auth_level = get_auth_level(project_id, request.user) if auth_level == 'unauthorized': raise PermissionDenied url = settings.PHENOPTIPS_BASE_URL + '/bin/export/data/' + patient_id + '?format=pdf&pdfcover=0&pdftoc=0&pdftemplate=PhenoTips.PatientSheetCode' response, curr_session = do_authenticated_call_to_phenotips(url, uname, pwd) http_response = HttpResponse(response.content) for header in response.headers.keys(): if header != 'connection' and header != 'Transfer-Encoding': # these hop-by-hop headers are not allowed by Django http_response[header] = response.headers[header] return http_response except Exception as e: print e raise Http404
def proxy_post(request): """ To act as a proxy for POST requests from Phenotips note: exempting csrf here since phenotips doesn't have this support """ try: # print type(pickle.loads(request.session['current_phenotips_session'])) # re-construct proxy-ed URL again url, parameters = __aggregate_url_parameters(request) project_name = request.session['current_project_id'] uname, pwd = get_uname_pwd_for_project(project_name) curr_session = pickle.loads(request.session['current_phenotips_session']) response = curr_session.post(url, data=dict(request.POST)) http_response = HttpResponse(response.content) for header in response.headers.keys(): if header != 'connection' and header != 'Transfer-Encoding': # these hop-by-hop headers are not allowed by Django http_response[header] = response.headers[header] # persist outside of PhenoTips db as well if len(request.POST) != 0: patient_id = request.session['current_patient_id'] __process_sync_request_helper(patient_id, request.user.username, project_name, parameters, pickle.loads(request.session['current_phenotips_session']) ) return http_response except Exception as e: print 'proxy post error:', e logger.error('phenotips.views:' + str(e)) raise Http404
def delete_these_phenotips_patient_ids(project_id, patient_ids): """ Deletes the input list of patient IDs Inputs: 1.A list of patient ids (ex: [P0000138, P0000134,..] Outputs: A list of True/False of all patients were deleted """ uname, pwd = get_uname_pwd_for_project(project_id, read_only=False) base_uri = settings.PHENOPTIPS_HOST_NAME + '/rest/patients/' for p in patient_ids: delete_phenotips_patient_id(project_id, p)
def generate_guid(apps, schema_editor): # figure out which indiv. ids are unique indiv_id_counts = collections.Counter([ indiv.indiv_id for indiv in Individual.objects.raw('select * from base_individual') ]) non_unique_ids = set( [indiv_id for indiv_id, count in indiv_id_counts.items() if count > 1]) for indiv in Individual.objects.raw('select * from base_individual'): # by default, for previously-existing Individual records, set guid = just the indiv_id indiv.guid = indiv.indiv_id # for non-unique ids, only one of these records can be attached to a phenotips record, so check if this is it. If not, switch this to the new-style date-based guid. if indiv.indiv_id in non_unique_ids: print( "non-unique id: %s. Checking if this patient is in phenotips for this project." % indiv.indiv_id) ok_to_use_new_guid = False if settings.PROJECTS_WITHOUT_PHENOTIPS and indiv.project.project_id in settings.PROJECTS_WITHOUT_PHENOTIPS: # phenotips is disabled for this project, so nothing will break if switching to the new-style guid. ok_to_use_new_guid = True else: try: admin_uname, admin_pwd = get_uname_pwd_for_project( indiv.project.project_id) patient_id = convert_external_id_to_internal_id( indiv.indiv_id, admin_uname, admin_pwd) ok_to_use_new_guid = False # patient is in phenotips, so can't use new id print("Reusuing original id: " + str(indiv.indiv_id)) except django.db.utils.IntegrityError: # this means the individual is not in phenotips, so switching to the new guid won't break things # create the new guid with timestamp ok_to_use_new_guid = True except requests.exceptions.ConnectionError: raw_input( "ERROR: Could not connect to PhenoTips. Continue? ") ok_to_use_new_guid = True except Exception as e: raw_input("ERROR on project: %s. %s. Continue? " % (indiv.indiv_id, e)) ok_to_use_new_guid = True if ok_to_use_new_guid: indiv.guid = datetime.now().strftime("%Y%m%d_%H%M%S_%f" + "_%s" % indiv.indiv_id) indiv.save() print("Set guid = " + indiv.guid)
def proxy_post(request): """ To act as a proxy for POST requests from Phenotips note: exempting csrf here since phenotips doesn't have this support """ try: # print type(pickle.loads(request.session['current_phenotips_session'])) # re-construct proxy-ed URL again url, parameters = __aggregate_url_parameters(request) project_name = request.session['current_project_id'] uname, pwd = get_uname_pwd_for_project(project_name) curr_session = pickle.loads(request.session['current_phenotips_session']) logger.info("===> POSTING to url: " + url) logger.info("===> DATA: " + str(dict(request.POST))) logger.info("===> SESSION - headers: " + str(curr_session.headers)) logger.info("===> SESSION - cookies: " + str(curr_session.cookies)) logger.info("===> SESSION - auth: " + str(curr_session.auth)) import requests #response = requests.post(url, headers=curr_session.headers, cookies=curr_session.cookies, auth=curr_session.auth) response = curr_session.post(url, data=dict(request.POST)) from requests_toolbelt.utils import dump data = dump.dump_all(response) logger.info("===> dump - original:\n" + data.decode('utf-8')) http_response = HttpResponse(response.content) for header in response.headers.keys(): if header != 'connection' and header != 'Transfer-Encoding': # these hop-by-hop headers are not allowed by Django http_response[header] = response.headers[header] # persist outside of PhenoTips db as well if len(request.POST) != 0: patient_id = request.session['current_patient_id'] __process_sync_request_helper(patient_id, request.user, project_name, parameters, pickle.loads(request.session['current_phenotips_session']) ) logger.info("===> original api - HTTP RESPONSE DICT: ") for k,v in http_response.__dict__.items(): logger.info("===> %s: %s" % (k,v)) return http_response except Exception as e: print 'proxy post error:', e logger.error('phenotips.views:' + str(e)) raise Http404
def get_phenotypes_entered_for_individual(indiv_id,project_id): ''' Get phenotype data enterred for this individual. Inputs: indiv_id: an individual ID (ex: PIE-OGI855-001726) ''' try: uname,pwd = get_uname_pwd_for_project(project_id,read_only=True) url = os.path.join(settings.PHENOPTIPS_HOST_NAME,'rest/patients/eid/' + indiv_id) response = requests.get(url, auth=HTTPBasicAuth(uname,pwd)) return response.json() except Exception as e: print 'patient phenotype export error:',e raise
def get_phenotypes_entered_for_individual(project_id, external_id): """ Get phenotype data enterred for this individual. Inputs: external_id: an individual ID (ex: PIE-OGI855-001726) """ try: uname, pwd = get_uname_pwd_for_project(project_id, read_only=True) url = os.path.join(settings.PHENOPTIPS_HOST_NAME, 'rest/patients/eid/' + external_id) response = requests.get(url, auth=HTTPBasicAuth(uname, pwd)) return response.json() except Exception as e: print 'patient phenotype export error:', e raise
def proxy_post(request): """ To act as a proxy for POST requests from Phenotips note: exempting csrf here since phenotips doesn't have this support """ try: # print type(pickle.loads(request.session['current_phenotips_session'])) # re-construct proxy-ed URL again url, parameters = __aggregate_url_parameters(request) project_name = request.session['current_project_id'] uname, pwd = get_uname_pwd_for_project(project_name) curr_session = pickle.loads( request.session['current_phenotips_session']) logger.info("===> POSTING to url: " + url) logger.info("===> DATA: " + str(dict(request.POST))) logger.info("===> SESSION - headers: " + str(curr_session.headers)) logger.info("===> SESSION - cookies: " + str(curr_session.cookies)) logger.info("===> SESSION - auth: " + str(curr_session.auth)) import requests #response = requests.post(url, headers=curr_session.headers, cookies=curr_session.cookies, auth=curr_session.auth) response = curr_session.post(url, data=dict(request.POST)) from requests_toolbelt.utils import dump data = dump.dump_all(response) logger.info("===> dump - original:\n" + data.decode('utf-8')) http_response = HttpResponse(response.content) for header in response.headers.keys(): if header != 'connection' and header != 'Transfer-Encoding': # these hop-by-hop headers are not allowed by Django http_response[header] = response.headers[header] # persist outside of PhenoTips db as well if len(request.POST) != 0: patient_id = request.session['current_patient_id'] __process_sync_request_helper( patient_id, request.user, project_name, parameters, pickle.loads(request.session['current_phenotips_session'])) logger.info("===> original api - HTTP RESPONSE DICT: ") for k, v in http_response.__dict__.items(): logger.info("===> %s: %s" % (k, v)) return http_response except Exception as e: print 'proxy post error:', e logger.error('phenotips.views:' + str(e)) raise Http404
def get_phenotypes_entered_for_individual(project_id, external_id): """ Get phenotype data enterred for this individual. Inputs: external_id: an individual ID (ex: PIE-OGI855-001726) """ try: uname, pwd = get_uname_pwd_for_project(project_id, read_only=True) url = os.path.join(settings.PHENOPTIPS_BASE_URL, 'rest/patients/eid/' + external_id) response = requests.get(url, auth=HTTPBasicAuth(uname, pwd)) if 404 != response.status_code: return response.json() return {} except Exception as e: print 'patient phenotype export error:', e raise
def fetch_project_phenotips_patient_ids(project_id): ''' Find all patients IDs (external) belonging to this project Inputs: 1. A project ID Outputs: 1. A list of IDs (ex: P0000138) of patients belonging to this ''' uname,pwd = get_uname_pwd_for_project(project_id,read_only=False) url = settings.PHENOPTIPS_HOST_NAME + '/rest/patients?number=100000' headers = {'Accept': 'application/json'} r = requests.get(url, headers=headers, auth=(uname,pwd)) patient_data = r.json() patient_ids=[] for patient_summary in patient_data['patientSummaries']: patient_ids.append(patient_summary['id']) return patient_ids
def fetch_project_phenotips_patient_ids(project_id): """ Find all patients IDs (external) belonging to this project Inputs: 1. A project ID Outputs: 1. A list of IDs (ex: P0000138) of patients belonging to this """ uname, pwd = get_uname_pwd_for_project(project_id, read_only=False) url = settings.PHENOPTIPS_BASE_URL + '/rest/patients?number=100000' headers = {'Accept': 'application/json'} r = requests.get(url, headers=headers, auth=(uname, pwd)) patient_data = r.json() patient_ids = [] for patient_summary in patient_data['patientSummaries']: patient_ids.append(patient_summary['id']) return patient_ids
def delete_phenotips_patient_id(project_id, patient_id): """ Deletes a single PhenoTips patient ID Inputs: 1. A single patient id (ex:P0000134) Outputs: True if success, raises exception otherwise """ uname, pwd = get_uname_pwd_for_project(project_id, read_only=False) base_uri = settings.PHENOPTIPS_HOST_NAME + '/rest/patients/' url = os.path.join(base_uri, patient_id) print url r = requests.delete(url, auth=(uname, pwd)) if r.status_code == 204: print 'deleted phenotips patient', patient_id, '....' return True
def proxy_get(request): """ To act as a proxy for get requests for Phenotips Note: exempting csrf here since phenotips doesn't have this support """ project_name = request.session['current_project_id'] project_phenotips_uname, project_phenotips_pwd = get_uname_pwd_for_project(project_name) try: curr_session = pickle.loads(request.session['current_phenotips_session']) url, parameters = __aggregate_url_parameters(request) response = curr_session.get(url, data=request.GET) http_response = HttpResponse(response.content) for header in response.headers.keys(): if header != 'connection' and header != 'Transfer-Encoding': # these hop-by-hop headers are not allowed by Django http_response[header] = response.headers[header] return http_response except Exception as e: print 'proxy get error:', e logger.error('phenotips.views:' + str(e)) raise Http404
def get_phenotypes_entered_for_individual(project_id, external_id): """ Get phenotype data enterred for this individual. Inputs: external_id: an individual ID (ex: PIE-OGI855-001726) """ try: uname, pwd = get_uname_pwd_for_project(project_id, read_only=True) url = os.path.join(settings.PHENOPTIPS_HOST_NAME, 'rest/patients/eid/' + external_id) #temp debug print ">>> phenotips API call:",url response = requests.get(url, auth=HTTPBasicAuth(uname, pwd)) #temp error message to track tricky bug print ">>> phenotips API call response_state:",response.status_code,response.text if 404 != response.status_code: return response.json() return {} except Exception as e: print 'patient phenotype export error:', e raise
def generate_guid(apps, schema_editor): # figure out which indiv. ids are unique indiv_id_counts = collections.Counter([indiv.indiv_id for indiv in Individual.objects.all()]) non_unique_ids = set([indiv_id for indiv_id, count in indiv_id_counts.items() if count > 1]) for indiv in Individual.objects.all(): # by default, for previously-existing Individual records, set guid = just the indiv_id indiv.guid = indiv.indiv_id # for non-unique ids, only one of these records can be attached to a phenotips record, so check if this is it. If not, switch this to the new-style date-based guid. if indiv.indiv_id in non_unique_ids: print("non-unique id: %s. Checking if this patient is in phenotips for this project." % indiv.indiv_id ) ok_to_use_new_guid = False if settings.PROJECTS_WITHOUT_PHENOTIPS and indiv.project.project_id in settings.PROJECTS_WITHOUT_PHENOTIPS: # phenotips is disabled for this project, so nothing will break if switching to the new-style guid. ok_to_use_new_guid = True else: try: admin_uname, admin_pwd = get_uname_pwd_for_project(indiv.project.project_id) patient_id = convert_external_id_to_internal_id(indiv.indiv_id, admin_uname, admin_pwd) ok_to_use_new_guid = False # patient is in phenotips, so can't use new id print("Reusuing original id: " + str(indiv.indiv_id)) except django.db.utils.IntegrityError: # this means the individual is not in phenotips, so switching to the new guid won't break things # create the new guid with timestamp ok_to_use_new_guid = True except requests.exceptions.ConnectionError: raw_input("ERROR: Could not connect to PhenoTips. Continue? ") ok_to_use_new_guid = True except Exception as e: raw_input("ERROR on project: %s. %s. Continue? " % (indiv.indiv_id, e)) ok_to_use_new_guid = True if ok_to_use_new_guid: indiv.guid = datetime.now().strftime("%Y%m%d_%H%M%S_%f" + "_%s" % indiv.indiv_id) indiv.save() print("Set guid = " + indiv.guid)
def fetch_phenotips_edit_page(request, eid): """ A proxy for phenotips view and edit patient pages Note: exempting csrf here since phenotips doesn't have this support """ try: current_user = request.user # if projectID key is found in in GET, it is the first connection call from browser if request.GET.has_key('project'): # adding project id and patient_id to session for later use in proxying project_id = request.GET['project'] request.session['current_project_id'] = project_id patient_id = get_phenotips_internal_id(eid, project_id) request.session['current_patient_id'] = patient_id auth_level = get_auth_level(project_id, request.user) if auth_level == 'unauthorized': raise PermissionDenied if auth_level == 'admin': phenotips_uname, phenotips_pwd = get_uname_pwd_for_project( project_id, read_only=False) else: phenotips_uname, phenotips_pwd = get_uname_pwd_for_project( project_id, read_only=True) url = settings.PHENOPTIPS_BASE_URL + '/bin/' + patient_id if auth_level == 'admin': url = settings.PHENOPTIPS_BASE_URL + '/bin/edit/data/' + patient_id response, curr_session = do_authenticated_call_to_phenotips( url, phenotips_uname, phenotips_pwd) # save this session with PhenoTips in current seqr session to be used within it to prevent # re-authenticating request.session['current_phenotips_session'] = pickle.dumps( curr_session) http_response = HttpResponse(response.content) for header in response.headers.keys(): http_response[header] = response.headers[header] return http_response # this is a subsequent call made during the opening of the frame by phenotips # and will use session info for required variables else: project_id = request.session['current_project_id'] patient_id = request.session['current_patient_id'] auth_level = get_auth_level(request.session['current_project_id'], request.user) if auth_level == 'unauthorized': raise PermissionDenied if auth_level == 'admin': phenotips_uname, phenotips_pwd = get_uname_pwd_for_project( project_id, read_only=False) else: phenotips_uname, phenotips_pwd = get_uname_pwd_for_project( project_id, read_only=True) url = settings.PHENOPTIPS_BASE_URL + '/bin/' + patient_id if auth_level == 'admin': url = settings.PHENOPTIPS_BASE_URL + '/bin/edit/data/' + patient_id if not request.GET.has_key('project'): url += '?' counter = 0 for param, val in request.GET.iteritems(): url += param + '=' + val if counter < len(request.GET) - 1: url += '&' counter += 1 # pedigree editor is special if 'sheet' in request.GET.keys(): url += '#' # get back a session and a result curr_session = pickle.loads( request.session['current_phenotips_session']) response, _ = do_authenticated_call_to_phenotips( url, phenotips_uname, phenotips_pwd, curr_session) http_response = HttpResponse(response.content) for header in response.headers.keys(): http_response[header] = response.headers[header] return http_response except Exception as e: print e raise Http404
def fetch_phenotips_edit_page(request, eid): """ A proxy for phenotips view and edit patient pages Note: exempting csrf here since phenotips doesn't have this support """ try: current_user = request.user # if projectID key is found in in GET, it is the first connection call from browser if request.GET.has_key('project'): # adding project id and patient_id to session for later use in proxying project_id = request.GET['project'] request.session['current_project_id'] = project_id patient_id = get_phenotips_internal_id(eid, project_id) request.session['current_patient_id'] = patient_id auth_level = get_auth_level(project_id, request.user) if auth_level == 'unauthorized': raise PermissionDenied if auth_level == 'admin': phenotips_uname, phenotips_pwd = get_uname_pwd_for_project(project_id, read_only=False) else: phenotips_uname, phenotips_pwd = get_uname_pwd_for_project(project_id, read_only=True) url = settings.PHENOPTIPS_BASE_URL + '/bin/' + patient_id if auth_level == 'admin': url = settings.PHENOPTIPS_BASE_URL + '/bin/edit/data/' + patient_id response, curr_session = do_authenticated_call_to_phenotips(url, phenotips_uname, phenotips_pwd) # save this session with PhenoTips in current seqr session to be used within it to prevent # re-authenticating request.session['current_phenotips_session'] = pickle.dumps(curr_session) http_response = HttpResponse(response.content) for header in response.headers.keys(): http_response[header] = response.headers[header] return http_response # this is a subsequent call made during the opening of the frame by phenotips # and will use session info for required variables else: project_id = request.session['current_project_id'] patient_id = request.session['current_patient_id'] auth_level = get_auth_level(request.session['current_project_id'], request.user) if auth_level == 'unauthorized': raise PermissionDenied if auth_level == 'admin': phenotips_uname, phenotips_pwd = get_uname_pwd_for_project(project_id, read_only=False) else: phenotips_uname, phenotips_pwd = get_uname_pwd_for_project(project_id, read_only=True) url = settings.PHENOPTIPS_BASE_URL + '/bin/' + patient_id if auth_level == 'admin': url = settings.PHENOPTIPS_BASE_URL + '/bin/edit/data/' + patient_id if not request.GET.has_key('project'): url += '?' counter = 0 for param, val in request.GET.iteritems(): url += param + '=' + val if counter < len(request.GET) - 1: url += '&' counter += 1 # pedigree editor is special if 'sheet' in request.GET.keys(): url += '#' # get back a session and a result curr_session = pickle.loads(request.session['current_phenotips_session']) response, _ = do_authenticated_call_to_phenotips(url, phenotips_uname, phenotips_pwd, curr_session) http_response = HttpResponse(response.content) for header in response.headers.keys(): http_response[header] = response.headers[header] return http_response except Exception as e: print e raise Http404