refactoring the getlatest-endpoint. Using a single endpoint to return all databases of interest. Added the endpoint to the application upon building it.

This commit is contained in:
Max Metz 2024-06-10 18:21:29 +02:00
parent 10db47073f
commit ee53d7fd9d
19 changed files with 62 additions and 228 deletions

View File

@ -13,6 +13,7 @@ from .api import ships
from .api import login from .api import login
from .api import user from .api import user
from .api import history from .api import history
from .api import latest
from BreCal.brecal_utils.file_handling import get_project_root, ensure_path from BreCal.brecal_utils.file_handling import get_project_root, ensure_path
from BreCal.brecal_utils.test_handling import execute_test_with_pytest, execute_coverage_test from BreCal.brecal_utils.test_handling import execute_test_with_pytest, execute_coverage_test
@ -61,6 +62,7 @@ def create_app(test_config=None):
app.register_blueprint(login.bp) app.register_blueprint(login.bp)
app.register_blueprint(user.bp) app.register_blueprint(user.bp)
app.register_blueprint(history.bp) app.register_blueprint(history.bp)
app.register_blueprint(latest.bp)
logging.basicConfig(filename='brecaldevel.log', level=logging.DEBUG, format='%(asctime)s | %(name)s | %(levelname)s | %(message)s') logging.basicConfig(filename='brecaldevel.log', level=logging.DEBUG, format='%(asctime)s | %(name)s | %(levelname)s | %(message)s')
local_db.initPool(os.path.dirname(app.instance_path)) local_db.initPool(os.path.dirname(app.instance_path))

View File

@ -3,7 +3,7 @@ import datetime
# global dictionary, which informs about the latest change of a given database (e.g., 'berths') # global dictionary, which informs about the latest change of a given database (e.g., 'berths')
# initialize all values as null (None) # initialize all values as null (None)
latest_get_request_dict = {database:None for database in ["berths", "history", "notifications", "participants", "shipcalls", "ships", "times"]} latest_get_request_dict = {database:None for database in ["shipcalls", "ships", "times"]}
def update_latest_modification_time(key:str, modification_time:datetime.datetime)->None: def update_latest_modification_time(key:str, modification_time:datetime.datetime)->None:
""" """
@ -23,15 +23,13 @@ def update_latest_modification_time(key:str, modification_time:datetime.datetime
return return
def get_latest_modification_time(key:str)->typing.Optional[str]: def get_latest_modification_times()->dict[str,typing.Optional[str]]:
""" """
This function returns the latest modification time in .isoformat, if a datetime is stored for the respective key in {latest_get_request_dict}. This function returns a dictionary, where each key determines the database name, and each value is either an isoformatted datetime
When there has not yet been an update, this function returns None of the latest modification time, or None.
""" """
global latest_get_request_dict global latest_get_request_dict
value = latest_get_request_dict.get(key,None) latest_dict = {k:v.isoformat() if isinstance(v,datetime.datetime) else v for k,v in latest_get_request_dict.items()}
if isinstance(value,datetime.datetime): return latest_dict
return value.isoformat()
return value # None

View File

@ -17,12 +17,3 @@ def GetBerths():
else: else:
return json.dumps("not authenticated"), 403 return json.dumps("not authenticated"), 403
@bp.route('/getlatestberths', methods=['get'])
@auth_guard() # no restriction by role
def GetLatestBerths():
if 'Authorization' in request.headers:
token = request.headers.get('Authorization')
return impl.berths.GetLatestBerths(token)
else:
return json.dumps("not authenticated"), 403

View File

@ -19,13 +19,3 @@ def GetParticipant(): # #TODO: rename? Naming might be a copy-paste typo
else: else:
return json.dumps("not authenticated"), 403 return json.dumps("not authenticated"), 403
@bp.route('/getlatesthistory', methods=['get'])
@auth_guard() # no restriction by role
def GetLatestHistory():
if 'Authorization' in request.headers:
token = request.headers.get('Authorization')
return impl.history.GetLatestHistory(token)
else:
return json.dumps("not authenticated"), 403

View File

@ -0,0 +1,18 @@
from flask import Blueprint, request
from webargs.flaskparser import parser
from .. import impl
from ..services.auth_guard import auth_guard
import json
bp = Blueprint('getlatest', __name__)
@bp.route('/getlatest', methods=['get'])
@auth_guard() # no restriction by role
def GetLatest():
"""This endpoint verifies the user and executes impl.latest.GetLatest"""
if 'Authorization' in request.headers:
token = request.headers.get('Authorization')
return impl.latest.GetLatest(token)
else:
return json.dumps("not authenticated"), 403

View File

@ -18,13 +18,4 @@ def GetNotifications():
logging.warning("attempt to load notifications without shipcall id") logging.warning("attempt to load notifications without shipcall id")
return json.dumps("missing argument"), 400 return json.dumps("missing argument"), 400
@bp.route('/getlatestnotifications', methods=['get'])
@auth_guard() # no restriction by role
def GetLatestNotifications():
if 'Authorization' in request.headers:
token = request.headers.get('Authorization')
return impl.notifications.GetLatestNotifications(token)
else:
return json.dumps("not authenticated"), 403

View File

@ -17,12 +17,3 @@ def GetParticipant():
else: else:
return json.dumps("not authenticated"), 403 return json.dumps("not authenticated"), 403
@bp.route('/getlatestparticipants', methods=['get'])
@auth_guard() # no restriction by role
def GetLatestParticipants():
if 'Authorization' in request.headers:
token = request.headers.get('Authorization')
return impl.participant.GetLatestParticipants(token)
else:
return json.dumps("not authenticated"), 403

View File

@ -54,11 +54,3 @@ def PutShipcalls():
return impl.shipcalls.PutShipcalls(loadedModel) return impl.shipcalls.PutShipcalls(loadedModel)
@bp.route('/getlatestshipcalls', methods=['get'])
@auth_guard() # no restriction by role
def GetLatestShipcalls():
if 'Authorization' in request.headers:
token = request.headers.get('Authorization')
return impl.shipcalls.GetLatestShipcalls(token)
else:
return json.dumps("not authenticated"), 403

View File

@ -67,12 +67,4 @@ def DeleteShip():
return impl.ships.DeleteShip(options) return impl.ships.DeleteShip(options)
@bp.route('/getlatestships', methods=['get'])
@auth_guard() # no restriction by role
def GetLatestShips():
if 'Authorization' in request.headers:
token = request.headers.get('Authorization')
return impl.ships.GetLatestShips(token)
else:
return json.dumps("not authenticated"), 403

View File

@ -68,12 +68,3 @@ def DeleteTimes():
logging.warning("Times delete missing id argument") logging.warning("Times delete missing id argument")
return json.dumps("missing argument"), 400 return json.dumps("missing argument"), 400
@bp.route('/getlatesttimes', methods=['get'])
@auth_guard() # no restriction by role
def GetLatestTimes():
if 'Authorization' in request.headers:
token = request.headers.get('Authorization')
return impl.times.GetLatestTimes(token)
else:
return json.dumps("not authenticated"), 403

View File

@ -5,7 +5,6 @@ import datetime
from ..schemas import model from ..schemas import model
from .. import local_db from .. import local_db
from BreCal.api import latest_get_request_dict, update_latest_modification_time, get_latest_modification_time
def GetBerths(token): def GetBerths(token):
""" """
@ -31,29 +30,6 @@ def GetBerths(token):
pooledConnection.close() pooledConnection.close()
def GetLatestBerths(token):
"""
Returns a datetime of the latest modification within the 'berth' database. When there has not yet been a modification, this method returns null.
Always creates an output dictionary with the format {key:string, value:str (datetime isoformat)}
# #TODO: should this become a data model?
"""
try:
modification_time = get_latest_modification_time(key="berths")
data = {"key":"berths", "value":modification_time}
return json.dumps(data), 200, {'Content-Type': 'application/json; charset=utf-8'}
except Exception as ex:
logging.error(ex)
print(ex)
result = {}
result["message"] = "call failed"
return json.dumps(result), 500

View File

@ -7,7 +7,6 @@ from ..schemas import model
from ..schemas.model import History from ..schemas.model import History
from .. import local_db from .. import local_db
from BreCal.api import latest_get_request_dict, update_latest_modification_time, get_latest_modification_time
def GetHistory(options): def GetHistory(options):
@ -39,24 +38,4 @@ def GetHistory(options):
return json.dumps(data, default=model.obj_dict), 200, {'Content-Type': 'application/json; charset=utf-8'} return json.dumps(data, default=model.obj_dict), 200, {'Content-Type': 'application/json; charset=utf-8'}
def GetLatestHistory(token):
"""
Returns a datetime of the latest modification within the 'history' database. When there has not yet been a modification, this method returns null.
Always creates an output dictionary with the format {key:string, value:str (datetime isoformat)}
# #TODO: should this become a data model?
"""
try:
modification_time = get_latest_modification_time(key="history")
data = {"key":"history", "value":modification_time}
return json.dumps(data), 200, {'Content-Type': 'application/json; charset=utf-8'}
except Exception as ex:
logging.error(ex)
print(ex)
result = {}
result["message"] = "call failed"
return json.dumps(result), 500

View File

@ -0,0 +1,32 @@
import json
import logging
import pydapper
import datetime
from ..schemas import model
from .. import local_db
from BreCal.api import get_latest_modification_times
def GetLatest(token):
"""
Returns a dictionary of the latest modification dates within the databases 'ships', 'shipcalls' and 'times'. When there has not yet been a modification, this method returns null.
Creates a dictionary of type dict[str, typing.Optional[datetime.datetime]]
"""
try:
data = get_latest_modification_times()
return json.dumps(data), 200, {'Content-Type': 'application/json; charset=utf-8'}
except Exception as ex:
logging.error(ex)
print(ex)
result = {}
result["message"] = "call failed"
return json.dumps(result), 500

View File

@ -6,7 +6,6 @@ import bcrypt
from ..schemas import model from ..schemas import model
from .. import local_db from .. import local_db
from ..services import jwt_handler from ..services import jwt_handler
from BreCal.api import latest_get_request_dict, update_latest_modification_time
def GetUser(options): def GetUser(options):

View File

@ -4,7 +4,6 @@ import pydapper
from ..schemas import model from ..schemas import model
from .. import local_db from .. import local_db
from BreCal.api import latest_get_request_dict, update_latest_modification_time, get_latest_modification_time
def GetNotifications(options): def GetNotifications(options):
""" """
@ -31,25 +30,4 @@ def GetNotifications(options):
return json.dumps(data, default=model.obj_dict), 200, {'Content-Type': 'application/json; charset=utf-8'} return json.dumps(data, default=model.obj_dict), 200, {'Content-Type': 'application/json; charset=utf-8'}
def GetLatestNotifications(token):
"""
Returns a datetime of the latest modification within the 'notification' database. When there has not yet been a modification, this method returns null.
Always creates an output dictionary with the format {key:string, value:str (datetime isoformat)}
# #TODO: should this become a data model?
"""
try:
modification_time = get_latest_modification_time(key="notifications")
data = {"key":"notifications", "value":modification_time}
return json.dumps(data), 200, {'Content-Type': 'application/json; charset=utf-8'}
except Exception as ex:
logging.error(ex)
print(ex)
result = {}
result["message"] = "call failed"
return json.dumps(result), 500

View File

@ -4,7 +4,6 @@ import pydapper
from ..schemas import model from ..schemas import model
from .. import local_db from .. import local_db
from BreCal.api import latest_get_request_dict, update_latest_modification_time, get_latest_modification_time
def GetParticipant(options): def GetParticipant(options):
""" """
@ -34,25 +33,3 @@ def GetParticipant(options):
if pooledConnection is not None: if pooledConnection is not None:
pooledConnection.close() pooledConnection.close()
def GetLatestParticipants(token):
"""
Returns a datetime of the latest modification within the 'participant' database. When there has not yet been a modification, this method returns null.
Always creates an output dictionary with the format {key:string, value:str (datetime isoformat)}
# #TODO: should this become a data model?
"""
try:
modification_time = get_latest_modification_time(key="participants")
data = {"key":"participants", "value":modification_time}
return json.dumps(data), 200, {'Content-Type': 'application/json; charset=utf-8'}
except Exception as ex:
logging.error(ex)
print(ex)
result = {}
result["message"] = "call failed"
return json.dumps(result), 500

View File

@ -9,7 +9,7 @@ from .. import local_db
from ..services.auth_guard import check_jwt from ..services.auth_guard import check_jwt
from BreCal.database.update_database import evaluate_shipcall_state from BreCal.database.update_database import evaluate_shipcall_state
from BreCal.api import latest_get_request_dict, update_latest_modification_time, get_latest_modification_time from BreCal.api import update_latest_modification_time
def GetShipcalls(options): def GetShipcalls(options):
""" """
@ -264,25 +264,3 @@ def PutShipcalls(schemaModel):
finally: finally:
if pooledConnection is not None: if pooledConnection is not None:
pooledConnection.close() pooledConnection.close()
def GetLatestShipcalls(token):
"""
Returns a datetime of the latest modification within the 'shipcall' database. When there has not yet been a modification, this method returns null.
Always creates an output dictionary with the format {key:string, value:str (datetime isoformat)}
# #TODO: should this become a data model?
"""
try:
modification_time = get_latest_modification_time(key="shipcalls")
data = {"key":"shipcalls", "value":modification_time}
return json.dumps(data), 200, {'Content-Type': 'application/json; charset=utf-8'}
except Exception as ex:
logging.error(ex)
print(ex)
result = {}
result["message"] = "call failed"
return json.dumps(result), 500

View File

@ -5,7 +5,7 @@ import datetime
from ..schemas import model from ..schemas import model
from .. import local_db from .. import local_db
from BreCal.api import latest_get_request_dict, update_latest_modification_time, get_latest_modification_time from BreCal.api import update_latest_modification_time
def GetShips(token): def GetShips(token):
""" """
@ -159,24 +159,4 @@ def DeleteShip(options):
result = {} result = {}
result["message"] = "call failed" result["message"] = "call failed"
return json.dumps(result), 500, {'Content-Type': 'application/json; charset=utf-8'} return json.dumps(result), 500, {'Content-Type': 'application/json; charset=utf-8'}
def GetLatestShips(token):
"""
Returns a datetime of the latest modification within the 'ship' database. When there has not yet been a modification, this method returns null.
Always creates an output dictionary with the format {key:string, value:str (datetime isoformat)}
# #TODO: should this become a data model?
"""
try:
modification_time = get_latest_modification_time(key="ships")
data = {"key":"ships", "value":modification_time}
return json.dumps(data), 200, {'Content-Type': 'application/json; charset=utf-8'}
except Exception as ex:
logging.error(ex)
print(ex)
result = {}
result["message"] = "call failed"
return json.dumps(result), 500

View File

@ -7,8 +7,8 @@ import datetime
from ..schemas import model from ..schemas import model
from .. import local_db from .. import local_db
from ..services.auth_guard import check_jwt from ..services.auth_guard import check_jwt
from BreCal.api import latest_get_request_dict, update_latest_modification_time, get_latest_modification_time
from BreCal.api import update_latest_modification_time
from BreCal.database.update_database import evaluate_shipcall_state from BreCal.database.update_database import evaluate_shipcall_state
def GetTimes(options): def GetTimes(options):
@ -215,24 +215,3 @@ def DeleteTimes(options):
finally: finally:
if pooledConnection is not None: if pooledConnection is not None:
pooledConnection.close() pooledConnection.close()
def GetLatestTimes(token):
"""
Returns a datetime of the latest modification within the 'times' database. When there has not yet been a modification, this method returns null.
Always creates an output dictionary with the format {key:string, value:str (datetime isoformat)}
# #TODO: should this become a data model?
"""
try:
modification_time = get_latest_modification_time(key="times")
data = {"key":"times", "value":modification_time}
return json.dumps(data), 200, {'Content-Type': 'application/json; charset=utf-8'}
except Exception as ex:
logging.error(ex)
print(ex)
result = {}
result["message"] = "call failed"
return json.dumps(result), 500