From e5bc518f593ff18a90a656d974a13ce963169b63 Mon Sep 17 00:00:00 2001 From: fnguyen Date: Mon, 21 Oct 2024 10:10:01 -0400 Subject: [PATCH] query should handle 401 unauthorized exceptions from Katsu gracefully --- query_server/query_operations.py | 42 +++++++++++++++++++++----------- 1 file changed, 28 insertions(+), 14 deletions(-) diff --git a/query_server/query_operations.py b/query_server/query_operations.py index 814e888..bd26b9c 100644 --- a/query_server/query_operations.py +++ b/query_server/query_operations.py @@ -199,6 +199,22 @@ def fix_dicts(to_fix): else: return to_fix +# Helper function to format the response from a query into a format the data portal understands +def format_query_response(donors, genomic_query, summary_stats, page, page_size): + # Determine which part of the filtered donors to send back + full_data = { + 'results': donors[(page*page_size):((page+1)*page_size)], + 'genomic': genomic_query, + 'count': len(donors), + 'summary': summary_stats + } + # full_data['genomic_query_info'] = genomic_query_info + + # Add prev and next parameters to the repsonse, appending a session ID. + # Essentially we want to go session ID -> list of donors + # and then paginate the list of donors, calling donors_with_clinical_data on each before returning + return fix_dicts(full_data), 200 + @app.route('/query') def query(treatment="", primary_site="", drug_name="", systemic_therapy_type="", chrom="", gene="", page=0, page_size=10, assembly="hg38", exclude_cohorts=[], session_id=""): # Add a service token to the headers so that other services will know this is from the query service: @@ -233,7 +249,17 @@ def query(treatment="", primary_site="", drug_name="", systemic_therapy_type="", params[param[1]] = param[0] full_url = f"{url}?{urllib.parse.urlencode(params, doseq=True)}" - donors = safe_get_request_json(requests.get(full_url, headers=headers), 'Katsu explorer donors')['items'] + donors_req = requests.get(full_url, headers=headers) + if not donors_req.ok: + if donors_req.status_code == 401: + # 401 Unauthorized: the user is not allowed to view any donors at this site + # The rest of the code should just pass quietly + return format_query_response([], [], get_summary_stats([], {}, {}), page, page_size) + else: + err_msg = f"Could not got Katsu donors response: {donors_req.status_code} {donors_req.text}" + logger.error(err_msg) + raise Exception(err_msg) + donors = donors_req.json()['items'] # Filter on excluded cohorts donors = [donor for donor in donors if donor['program_id'] not in exclude_cohorts] @@ -317,19 +343,7 @@ def query(treatment="", primary_site="", drug_name="", systemic_therapy_type="", # TODO: Cache the above list of donor IDs and summary statistics summary_stats = get_summary_stats(donors, summary_info['primary_site'], summary_info['treatment_type']) - # Determine which part of the filtered donors to send back - full_data = { - 'results': [donor for donor in donors[(page*page_size):((page+1)*page_size)]], - 'genomic': genomic_query, - 'count': len(donors), - 'summary': summary_stats - } - # full_data['genomic_query_info'] = genomic_query_info - - # Add prev and next parameters to the repsonse, appending a session ID. - # Essentially we want to go session ID -> list of donors - # and then paginate the list of donors, calling donors_with_clinical_data on each before returning - return fix_dicts(full_data), 200 + return format_query_response(donors, genomic_query, summary_stats, page, page_size) @app.route('/genomic_completeness') def genomic_completeness():