Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow bypass cache on demand and error handling #8

Merged
merged 5 commits into from
Nov 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 19 additions & 23 deletions src/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,6 @@ def before_request_log():
def after_request_log(response):
app.logger.debug(f"{request.remote_addr} \"{request.method} {request.url}\" {response.status_code}")
return response



# APIS: try to load new data, if doesn't work, get most recent
Expand All @@ -153,7 +152,8 @@ def api_imaging():
global api_data_cache
try:
tapis_token = get_tapis_token(request)
if not api_data_index['imaging'] or not check_data_current(datetime.strptime(api_data_index['imaging'], datetime_format)):

if not api_data_index['imaging'] or not check_data_current(request, datetime.strptime(api_data_index['imaging'], datetime_format)):
api_date = datetime.now().strftime(datetime_format)
imaging_data = get_api_imaging_data(tapis_token)
if imaging_data:
Expand All @@ -162,27 +162,25 @@ def api_imaging():
api_data_index['imaging'] = api_date
return jsonify({'date': api_data_index['imaging'], 'data': api_data_cache['imaging']})
except Exception as e:
app.logger.error(("Error in imaging API request: {0}").format(str(e)))
return jsonify('error: {}'.format(e))
return handle_exception(e, "Imaging API")

@app.route("/api/consort")
def api_consort():
global datetime_format
global api_data_index
global api_data_cache
# try:
tapis_token = get_tapis_token(request)
if not api_data_index['consort'] or not check_data_current(datetime.strptime(api_data_index['consort'], datetime_format)):
api_date = datetime.now().strftime(datetime_format)
consort_data_json = get_api_consort_data(tapis_token)
if consort_data_json:
app.logger.info(f"Caching consort report data. Date: {api_date}")
api_data_cache['consort'] = consort_data_json
api_data_index['consort'] = api_date
return jsonify({'date': api_data_index['consort'], 'data': api_data_cache['consort']})
# except Exception as e:
# traceback.print_exc()
# return jsonify('error: {}'.format(e))
try:
tapis_token = get_tapis_token(request)
if not api_data_index['consort'] or not check_data_current(request, datetime.strptime(api_data_index['consort'], datetime_format)):
api_date = datetime.now().strftime(datetime_format)
consort_data_json = get_api_consort_data(tapis_token)
if consort_data_json:
app.logger.info(f"Caching consort report data. Date: {api_date}")
api_data_cache['consort'] = consort_data_json
api_data_index['consort'] = api_date
return jsonify({'date': api_data_index['consort'], 'data': api_data_cache['consort']})
except Exception as e:
return handle_exception(e, "Consort API")

# get_api_consort_data
@app.route("/api/blood")
Expand All @@ -192,7 +190,7 @@ def api_blood():
global api_data_cache
try:
tapis_token = get_tapis_token(request)
if not api_data_index['blood'] or not check_data_current(datetime.strptime(api_data_index['blood'], datetime_format)):
if not api_data_index['blood'] or not check_data_current(request, datetime.strptime(api_data_index['blood'], datetime_format)):
api_date = datetime.now().strftime(datetime_format)
blood_data, blood_data_request_status = get_api_blood_data(tapis_token)
if blood_data:
Expand All @@ -208,8 +206,7 @@ def api_blood():

return jsonify({'date': api_data_index['blood'], 'data': api_data_cache['blood']})
except Exception as e:
app.logger.error(("Error in blood API request: {0}").format(str(e)))
return jsonify('error: {}'.format(e))
return handle_exception(e, "Blood API")


@app.route("/api/subjects")
Expand All @@ -221,7 +218,7 @@ def api_subjects():

try:
tapis_token = get_tapis_token(request)
if not api_data_index['subjects'] or not check_data_current(datetime.strptime(api_data_index['subjects'], datetime_format)):
if not api_data_index['subjects'] or not check_data_current(request, datetime.strptime(api_data_index['subjects'], datetime_format)):
api_date = datetime.now().strftime(datetime_format)
latest_subjects_json = get_api_subjects_json(tapis_token)
if latest_subjects_json:
Expand All @@ -233,8 +230,7 @@ def api_subjects():

return jsonify({'date': api_data_index['subjects'], 'data': api_data_cache['subjects']})
except Exception as e:
app.logger.error(("Error in subjects API request: {0}").format(str(e)))
return jsonify('error: {}'.format(e))
return handle_exception(e, "Subjects API")

def api_tester():

Expand Down
77 changes: 50 additions & 27 deletions src/data_loading.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,43 @@
import datetime
from datetime import datetime
from retrying import retry
from flask import jsonify

import logging
files_api_root = os.environ.get('FILES_API_ROOT')
portal_api_root = os.environ.get('PORTAL_API_ROOT')
logger = logging.getLogger("datastore_app")


class MissingPortalSessionIdException(Exception):
'''Custom Exception for Misisng Session Id'''

class TapisTokenRetrievalException(Exception):
'''Custom Exception for Tapis Token retrieval error'''

def handle_exception(ex, api_message):
'''Handle errors for api requests. Provide error code for categorizing response'''
logger.error(("Error in {0} request: {1}").format(api_message, str(ex)))
error_code = 'DATA_ERROR'
if isinstance(ex, MissingPortalSessionIdException):
error_code = "MISSING_SESSION_ID"
elif isinstance(ex, TapisTokenRetrievalException):
error_code = "INVALID_TAPIS_TOKEN"
json_data = {
'error_code':error_code,
'error':str(ex)
}
return jsonify(json_data)

# ----------------------------------------------------------------------------
# Updating data checks
# ----------------------------------------------------------------------------
def check_data_current(data_date):
def check_data_current(api_request, data_date):
'''test to see if the date in a data dictionary is from after 10am on the same day as checking.'''
if api_request.args.get('ignore_cache') == 'True':
logger.info('Ignoring cache for the request.')
return False

now = datetime.now()

if data_date.date() == now.date():
Expand Down Expand Up @@ -240,13 +265,11 @@ def get_api_consort_data(tapis_token,
return consort_data_json

else:
logger.exception("Unauthorized attempt to access Consort data")
return None
raise TapisTokenRetrievalException()

except Exception as e:
except Exception:
traceback.print_exc()
return None

raise


## Function to rebuild dataset from apis
Expand Down Expand Up @@ -285,12 +308,12 @@ def get_api_imaging_data(tapis_token):

return imaging_data_json
else:
logger.exception("Unauthorized attempt to access Imaging data")
return None
raise TapisTokenRetrievalException()

except Exception as e:

except Exception:
traceback.print_exc()
return "exception: {}".format(e)
raise


## Function to rebuild dataset from apis
Expand Down Expand Up @@ -342,12 +365,11 @@ def get_api_blood_data(tapis_token):

return blood_data_json, request_status
else:
logger.exception("Unauthorized attempt to access Blood data")
return None
raise TapisTokenRetrievalException()

except Exception as e:
except Exception:
traceback.print_exc()
return None
raise



Expand Down Expand Up @@ -377,12 +399,10 @@ def get_api_subjects_json(tapis_token):

return subjects_json
else:
logger.exception("Unauthorized attempt to access Subjects data")
return None

except Exception as e:
raise TapisTokenRetrievalException()
except Exception:
traceback.print_exc()
return None
raise

# Retry handler for requests
@retry(wait_exponential_multiplier=500, wait_exponential_max=5000, stop_max_attempt_number=3)
Expand All @@ -395,14 +415,17 @@ def get_tapis_token(api_request):
'''Get tapis token using the session cookie. If the session is not authenticated, this will fail.'''
session_id = api_request.cookies.get("coresessionid")
if session_id is None:
raise Exception("Missing session id")
cookies = {'coresessionid':session_id}
response = make_request_with_retry(portal_api_root + '/auth/tapis/', cookies)

response.raise_for_status()
tapis_token = response.json()['token']
logger.info("Received tapis token.")
return tapis_token
raise MissingPortalSessionIdException("Missing session id")
try:
cookies = {'coresessionid':session_id}
response = make_request_with_retry(portal_api_root + '/auth/tapis/', cookies)

response.raise_for_status()
tapis_token = response.json()['token']
logger.info("Received tapis token.")
return tapis_token
except Exception as e:
raise TapisTokenRetrievalException('Unable to get Tapis Token') from e

def make_report_data_request(url, tapis_token):
logger.info(f"Sending request to {url}")
Expand Down
Loading