From 5d5ff72ca28b0cac2139718113cf5f73e52c9866 Mon Sep 17 00:00:00 2001 From: Cliff Hill Date: Wed, 21 Aug 2024 11:09:50 -0400 Subject: [PATCH 1/7] Adding the new fields for template stats. Signed-off-by: Cliff Hill --- app/dao/fact_notification_status_dao.py | 18 +++++++++++++++--- app/template_statistics/rest.py | 2 +- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/app/dao/fact_notification_status_dao.py b/app/dao/fact_notification_status_dao.py index a810ff0db..b1afcc70f 100644 --- a/app/dao/fact_notification_status_dao.py +++ b/app/dao/fact_notification_status_dao.py @@ -1,4 +1,4 @@ -from datetime import timedelta +from datetime import date, timedelta from sqlalchemy import Date, case, func from sqlalchemy.dialects.postgresql import insert @@ -136,7 +136,10 @@ def fetch_notification_status_for_service_for_today_and_7_previous_days( ), FactNotificationStatus.notification_status.cast(db.Text).label("status"), *( - [FactNotificationStatus.template_id.label("template_id")] + [ + FactNotificationStatus.template_id.label("template_id"), + FactNotificationStatus.local_date.label("last_used"), + ] if by_template else [] ), @@ -151,7 +154,14 @@ def fetch_notification_status_for_service_for_today_and_7_previous_days( db.session.query( Notification.notification_type.cast(db.Text), Notification.status.cast(db.Text), - *([Notification.template_id] if by_template else []), + *( + [ + Notification.template_id, + literal(date.today()).label("last_used"), + ] + if by_template + else [] + ), func.count().label("count"), ) .filter( @@ -174,6 +184,8 @@ def fetch_notification_status_for_service_for_today_and_7_previous_days( Template.name.label("template_name"), False, # TODO: this is related to is_precompiled_letter all_stats_table.c.template_id, + Template.folder.name.label("folder"), + Template.created_by.name.label("created_by"), ] if by_template else [] diff --git a/app/template_statistics/rest.py b/app/template_statistics/rest.py index 03a319ecc..08467cfeb 100644 --- a/app/template_statistics/rest.py +++ b/app/template_statistics/rest.py @@ -23,7 +23,7 @@ def get_template_statistics_for_service_by_day(service_id): try: whole_days = int(whole_days) except ValueError: - error = "{} is not an integer".format(whole_days) + error = f"{whole_days} is not an integer" message = {"whole_days": [error]} raise InvalidRequest(message, status_code=400) From 05e27c7f3b250b36d15237810d9037b082970a6b Mon Sep 17 00:00:00 2001 From: Cliff Hill Date: Thu, 22 Aug 2024 14:04:22 -0400 Subject: [PATCH 2/7] Restructured the query to be adhering to SQLAlchemy 2.0. Signed-off-by: Cliff Hill --- app/dao/fact_notification_status_dao.py | 126 +++++++++++++----------- 1 file changed, 70 insertions(+), 56 deletions(-) diff --git a/app/dao/fact_notification_status_dao.py b/app/dao/fact_notification_status_dao.py index b1afcc70f..54eb261f2 100644 --- a/app/dao/fact_notification_status_dao.py +++ b/app/dao/fact_notification_status_dao.py @@ -1,9 +1,10 @@ from datetime import date, timedelta -from sqlalchemy import Date, case, func +from sqlalchemy import Date, case, func, select, union_all, cast from sqlalchemy.dialects.postgresql import insert +from sqlalchemy.orm import aliased from sqlalchemy.sql.expression import extract, literal -from sqlalchemy.types import DateTime, Integer +from sqlalchemy.types import DateTime, Integer, Text from app import db from app.dao.dao_utils import autocommit @@ -126,83 +127,96 @@ def fetch_notification_status_for_service_for_day(fetch_day, service_id): def fetch_notification_status_for_service_for_today_and_7_previous_days( - service_id, by_template=False, limit_days=7 -): + service_id: str, + by_template: bool = False, + limit_days: int = 7 +) -> list[dict | None]: start_date = midnight_n_days_ago(limit_days) now = utc_now() - stats_for_7_days = db.session.query( - FactNotificationStatus.notification_type.cast(db.Text).label( - "notification_type" - ), - FactNotificationStatus.notification_status.cast(db.Text).label("status"), + + # Query for the last 7 days + stats_for_7_days = select( + cast(FactNotificationStatus.notification_type, Text).label("notification_type"), + cast(FactNotificationStatus.notification_status, Text).label("status"), *( [ FactNotificationStatus.template_id.label("template_id"), - FactNotificationStatus.local_date.label("last_used"), - ] - if by_template - else [] + FactNotificationStatus.local_date.label("date_used"), + ] if by_template else [] ), FactNotificationStatus.notification_count.label("count"), - ).filter( + ).where( FactNotificationStatus.service_id == service_id, FactNotificationStatus.local_date >= start_date, FactNotificationStatus.key_type != KeyType.TEST, ) - stats_for_today = ( - db.session.query( - Notification.notification_type.cast(db.Text), - Notification.status.cast(db.Text), - *( - [ - Notification.template_id, - literal(date.today()).label("last_used"), - ] - if by_template - else [] - ), - func.count().label("count"), - ) - .filter( - Notification.created_at >= get_midnight_in_utc(now), - Notification.service_id == service_id, - Notification.key_type != KeyType.TEST, - ) - .group_by( - Notification.notification_type, - *([Notification.template_id] if by_template else []), - Notification.status, - ) + # Query for today's stats + stats_for_today = select( + cast(Notification.notification_type, Text), + cast(Notification.status, Text), + *( + [ + Notification.template_id, + literal(date.today()).label("date_used"), + ] if by_template else [] + ), + func.count().label("count"), + ).where( + Notification.created_at >= get_midnight_in_utc(now), + Notification.service_id == service_id, + Notification.key_type != KeyType.TEST, + ).group_by( + Notification.notification_type, + *([Notification.template_id] if by_template else []), + Notification.status, ) - all_stats_table = stats_for_7_days.union_all(stats_for_today).subquery() + # Combine the queries using union_all + all_stats_union = union_all(stats_for_7_days, stats_for_today).subquery() + all_stats_alias = aliased(all_stats_union) - query = db.session.query( + # Final query with optional template joins + query = select( *( [ Template.name.label("template_name"), - False, # TODO: this is related to is_precompiled_letter - all_stats_table.c.template_id, - Template.folder.name.label("folder"), - Template.created_by.name.label("created_by"), - ] - if by_template - else [] + False, # TODO: Handle `is_precompiled_letter` + all_stats_alias.c.template_id, + Template.folder.label("folder"), + Template.created_by.label("created_by"), + func.max(all_stats_alias.c.date_used).label("last_used"), # Get the most recent date + ] if by_template else [] ), - all_stats_table.c.notification_type, - all_stats_table.c.status, - func.cast(func.sum(all_stats_table.c.count), Integer).label("count"), + all_stats_alias.c.notification_type, + all_stats_alias.c.status, + cast(func.sum(all_stats_alias.c.count), Integer).label("count"), ) if by_template: - query = query.filter(all_stats_table.c.template_id == Template.id) + query = query.join(Template, all_stats_alias.c.template_id == Template.id) - return query.group_by( - *([Template.name, all_stats_table.c.template_id] if by_template else []), - all_stats_table.c.notification_type, - all_stats_table.c.status, - ).all() + # Group by all necessary fields except date_used + query = query.group_by( + *( + [ + Template.name, + all_stats_alias.c.template_id, + Template.folder, + Template.created_by, + ] if by_template else [] + ), + all_stats_alias.c.notification_type, + all_stats_alias.c.status, + ) + + print("*"*79) + print(query) + print("*"*79) + + # Execute the query using Flask-SQLAlchemy's session + result = db.session.execute(query) + return result.mappings().all() def fetch_notification_status_totals_for_all_services(start_date, end_date): From fb743cf28ba4a5092cfc177caf09b436fbdc4a41 Mon Sep 17 00:00:00 2001 From: Cliff Hill Date: Thu, 22 Aug 2024 14:54:16 -0400 Subject: [PATCH 3/7] Fixed the joins. Now to figure out why there's no data. Signed-off-by: Cliff Hill --- app/dao/fact_notification_status_dao.py | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/app/dao/fact_notification_status_dao.py b/app/dao/fact_notification_status_dao.py index 54eb261f2..1dcdce594 100644 --- a/app/dao/fact_notification_status_dao.py +++ b/app/dao/fact_notification_status_dao.py @@ -15,6 +15,9 @@ from app.models import ( NotificationAllTimeView, Service, Template, + TemplateFolder, + User, + template_folder_map, ) from app.utils import ( get_midnight_in_utc, @@ -183,8 +186,8 @@ def fetch_notification_status_for_service_for_today_and_7_previous_days( Template.name.label("template_name"), False, # TODO: Handle `is_precompiled_letter` all_stats_alias.c.template_id, - Template.folder.label("folder"), - Template.created_by.label("created_by"), + TemplateFolder.name.label("folder"), + User.name.label("created_by"), func.max(all_stats_alias.c.date_used).label("last_used"), # Get the most recent date ] if by_template else [] ), @@ -194,7 +197,19 @@ def fetch_notification_status_for_service_for_today_and_7_previous_days( ) if by_template: - query = query.join(Template, all_stats_alias.c.template_id == Template.id) + query = query.join( + Template, + all_stats_alias.c.template_id == Template.id + ).join( + User, + Template.created_by_id == User.id + ).join( + template_folder_map, + Template.id == template_folder_map.c.template_id + ).join( + TemplateFolder, + TemplateFolder.id == template_folder_map.c.template_id + ) # Group by all necessary fields except date_used query = query.group_by( @@ -202,8 +217,8 @@ def fetch_notification_status_for_service_for_today_and_7_previous_days( [ Template.name, all_stats_alias.c.template_id, - Template.folder, - Template.created_by, + TemplateFolder.name, + User.name, ] if by_template else [] ), all_stats_alias.c.notification_type, From 4084a18327ff7750ef324f8d2096e6c0d705d850 Mon Sep 17 00:00:00 2001 From: Cliff Hill Date: Wed, 28 Aug 2024 15:05:42 -0400 Subject: [PATCH 4/7] I think it is working now. Signed-off-by: Cliff Hill --- app/dao/fact_notification_status_dao.py | 104 ++++---- .../dao/test_fact_notification_status_dao.py | 227 ++++++++++++------ 2 files changed, 207 insertions(+), 124 deletions(-) diff --git a/app/dao/fact_notification_status_dao.py b/app/dao/fact_notification_status_dao.py index 1dcdce594..df8e653ee 100644 --- a/app/dao/fact_notification_status_dao.py +++ b/app/dao/fact_notification_status_dao.py @@ -1,6 +1,6 @@ -from datetime import date, timedelta +from datetime import timedelta -from sqlalchemy import Date, case, func, select, union_all, cast +from sqlalchemy import Date, case, cast, func, select, union_all from sqlalchemy.dialects.postgresql import insert from sqlalchemy.orm import aliased from sqlalchemy.sql.expression import extract, literal @@ -130,12 +130,10 @@ def fetch_notification_status_for_service_for_day(fetch_day, service_id): def fetch_notification_status_for_service_for_today_and_7_previous_days( - service_id: str, - by_template: bool = False, - limit_days: int = 7 + service_id: str, by_template: bool = False, limit_days: int = 7 ) -> list[dict | None]: start_date = midnight_n_days_ago(limit_days) - now = utc_now() + now = get_midnight_in_utc(utc_now()) # Query for the last 7 days stats_for_7_days = select( @@ -145,7 +143,9 @@ def fetch_notification_status_for_service_for_today_and_7_previous_days( [ FactNotificationStatus.template_id.label("template_id"), FactNotificationStatus.local_date.label("date_used"), - ] if by_template else [] + ] + if by_template + else [] ), FactNotificationStatus.notification_count.label("count"), ).where( @@ -155,41 +155,53 @@ def fetch_notification_status_for_service_for_today_and_7_previous_days( ) # Query for today's stats - stats_for_today = select( - cast(Notification.notification_type, Text), - cast(Notification.status, Text), - *( - [ - Notification.template_id, - literal(date.today()).label("date_used"), - ] if by_template else [] - ), - func.count().label("count"), - ).where( - Notification.created_at >= get_midnight_in_utc(now), - Notification.service_id == service_id, - Notification.key_type != KeyType.TEST, - ).group_by( - Notification.notification_type, - *([Notification.template_id] if by_template else []), - Notification.status, + stats_for_today = ( + select( + cast(Notification.notification_type, Text), + cast(Notification.status, Text), + *( + [ + Notification.template_id, + literal(now).label("date_used"), + ] + if by_template + else [] + ), + func.count().label("count"), + ) + .where( + Notification.created_at >= now, + Notification.service_id == service_id, + Notification.key_type != KeyType.TEST, + ) + .group_by( + Notification.notification_type, + *([Notification.template_id] if by_template else []), + Notification.status, + ) ) # Combine the queries using union_all all_stats_union = union_all(stats_for_7_days, stats_for_today).subquery() - all_stats_alias = aliased(all_stats_union) + all_stats_alias = aliased(all_stats_union, name="all_stats") # Final query with optional template joins query = select( *( [ + TemplateFolder.name.label("folder"), Template.name.label("template_name"), False, # TODO: Handle `is_precompiled_letter` + template_folder_map.c.template_folder_id, all_stats_alias.c.template_id, - TemplateFolder.name.label("folder"), User.name.label("created_by"), - func.max(all_stats_alias.c.date_used).label("last_used"), # Get the most recent date - ] if by_template else [] + Template.created_by_id, + func.max(all_stats_alias.c.date_used).label( + "last_used" + ), # Get the most recent date + ] + if by_template + else [] ), all_stats_alias.c.notification_type, all_stats_alias.c.status, @@ -197,38 +209,36 @@ def fetch_notification_status_for_service_for_today_and_7_previous_days( ) if by_template: - query = query.join( - Template, - all_stats_alias.c.template_id == Template.id - ).join( - User, - Template.created_by_id == User.id - ).join( - template_folder_map, - Template.id == template_folder_map.c.template_id - ).join( - TemplateFolder, - TemplateFolder.id == template_folder_map.c.template_id + query = ( + query.join(Template, all_stats_alias.c.template_id == Template.id) + .join(User, Template.created_by_id == User.id) + .outerjoin( + template_folder_map, Template.id == template_folder_map.c.template_id + ) + .outerjoin( + TemplateFolder, + TemplateFolder.id == template_folder_map.c.template_folder_id, + ) ) # Group by all necessary fields except date_used query = query.group_by( *( [ + TemplateFolder.name, Template.name, all_stats_alias.c.template_id, - TemplateFolder.name, User.name, - ] if by_template else [] + template_folder_map.c.template_folder_id, + Template.created_by_id, + ] + if by_template + else [] ), all_stats_alias.c.notification_type, all_stats_alias.c.status, ) - print("*"*79) - print(query) - print("*"*79) - # Execute the query using Flask-SQLAlchemy's session result = db.session.execute(query) return result.mappings().all() diff --git a/tests/app/dao/test_fact_notification_status_dao.py b/tests/app/dao/test_fact_notification_status_dao.py index dc46de45d..ccb0c5a06 100644 --- a/tests/app/dao/test_fact_notification_status_dao.py +++ b/tests/app/dao/test_fact_notification_status_dao.py @@ -1,5 +1,4 @@ from datetime import date, datetime, timedelta -from unittest import mock from uuid import UUID import pytest @@ -26,6 +25,7 @@ from tests.app.db import ( create_notification, create_service, create_template, + create_template_folder, ) @@ -252,15 +252,18 @@ def test_fetch_notification_status_by_template_for_service_for_today_and_7_previ notify_db_session, ): service_1 = create_service(service_name="service_1") + test_folder = create_template_folder(service=service_1, name="Test_Folder_For_This") sms_template = create_template( template_name="sms Template 1", service=service_1, template_type=TemplateType.SMS, + folder=test_folder, ) sms_template_2 = create_template( template_name="sms Template 2", service=service_1, template_type=TemplateType.SMS, + folder=test_folder, ) email_template = create_template( service=service_1, template_type=TemplateType.EMAIL @@ -329,82 +332,152 @@ def test_fetch_notification_status_by_template_for_service_for_today_and_7_previ by_template=True, ) - assert [ - ( - "email Template Name", - False, - mock.ANY, - NotificationType.EMAIL, - NotificationStatus.DELIVERED, - 1, - ), - ( - "email Template Name", - False, - mock.ANY, - NotificationType.EMAIL, - NotificationStatus.DELIVERED, - 3, - ), - ( - "sms Template 1", - False, - mock.ANY, - NotificationType.SMS, - NotificationStatus.CREATED, - 1, - ), - ( - "sms Template Name", - False, - mock.ANY, - NotificationType.SMS, - NotificationStatus.CREATED, - 1, - ), - ( - "sms Template 1", - False, - mock.ANY, - NotificationType.SMS, - NotificationStatus.DELIVERED, - 1, - ), - ( - "sms Template 2", - False, - mock.ANY, - NotificationType.SMS, - NotificationStatus.DELIVERED, - 1, - ), - ( - "sms Template Name", - False, - mock.ANY, - NotificationType.SMS, - NotificationStatus.DELIVERED, - 8, - ), - ( - "sms Template Name", - False, - mock.ANY, - NotificationType.SMS, - NotificationStatus.DELIVERED, - 10, - ), - ( - "sms Template Name", - False, - mock.ANY, - NotificationType.SMS, - NotificationStatus.DELIVERED, - 11, - ), - ] == sorted( - results, key=lambda x: (x.notification_type, x.status, x.template_name, x.count) - ) + expected = [ + { + "folder": None, + "template_name": "email Template Name", + "_no_label": False, + "created_by": "Test User", + "last_used": datetime(2018, 10, 31, 0, 0), + "notification_type": NotificationType.EMAIL, + "status": NotificationStatus.DELIVERED, + "count": 1, + }, + { + "folder": None, + "template_name": "email Template Name", + "_no_label": False, + "created_by": "Test User", + "last_used": datetime(2018, 10, 29, 0, 0), + "notification_type": NotificationType.EMAIL, + "status": NotificationStatus.DELIVERED, + "count": 3, + }, + { + "folder": None, + "template_name": "sms Template Name", + "_no_label": False, + "created_by": "Test User", + "last_used": datetime(2018, 10, 29, 0, 0), + "notification_type": NotificationType.SMS, + "status": NotificationStatus.CREATED, + "count": 1, + }, + { + "folder": "Test_Folder_For_This", + "template_name": "sms Template 1", + "_no_label": False, + "created_by": "Test User", + "last_used": datetime(2018, 10, 31, 0, 0), + "notification_type": NotificationType.SMS, + "status": NotificationStatus.CREATED, + "count": 1, + }, + { + "folder": None, + "template_name": "sms Template Name", + "_no_label": False, + "created_by": "Test User", + "last_used": datetime(2018, 10, 29, 0, 0), + "notification_type": NotificationType.SMS, + "status": NotificationStatus.DELIVERED, + "count": 10, + }, + { + "folder": "Test_Folder_For_This", + "template_name": "sms Template 2", + "_no_label": False, + "created_by": "Test User", + "last_used": datetime(2018, 10, 31, 0, 0), + "notification_type": NotificationType.SMS, + "status": NotificationStatus.DELIVERED, + "count": 1, + }, + { + "folder": None, + "template_name": "sms Template Name", + "_no_label": False, + "created_by": "Test User", + "last_used": datetime(2018, 10, 25, 0, 0), + "notification_type": NotificationType.SMS, + "status": NotificationStatus.DELIVERED, + "count": 8, + }, + { + "folder": "Test_Folder_For_This", + "template_name": "sms Template 1", + "_no_label": False, + "created_by": "Test User", + "last_used": datetime(2018, 10, 31, 0, 0), + "notification_type": NotificationType.SMS, + "status": NotificationStatus.DELIVERED, + "count": 1, + }, + { + "folder": None, + "template_name": "sms Template Name", + "_no_label": False, + "created_by": "Test User", + "last_used": datetime(2018, 10, 29, 0, 0), + "notification_type": NotificationType.SMS, + "status": NotificationStatus.DELIVERED, + "count": 11, + }, + ] + + expected = [ + [ + str(row[k]) if k != "last_used" else row[k].strftime("%Y-%m-%d") + for k in ( + "folder", + "template_name", + "created_by", + "last_used", + "notification_type", + "status", + "count", + ) + ] + for row in sorted( + expected, + key=lambda x: ( + str(x["notification_type"]), + str(x["status"]), + x["folder"] if x["folder"] is not None else "", + x["template_name"], + x["count"], + x["last_used"], + ), + ) + ] + + results = [ + [ + str(row[k]) if k != "last_used" else row[k].strftime("%Y-%m-%d") + for k in ( + "folder", + "template_name", + "created_by", + "last_used", + "notification_type", + "status", + "count", + ) + ] + for row in sorted( + results, + key=lambda x: ( + x.notification_type, + x.status, + x.folder if x.folder is not None else "", + x.template_name, + x.count, + x.last_used, + ), + ) + ] + + assert expected == results @pytest.mark.parametrize( From dbfd99cb65432e9af0f3bf8aae0335f5d4889130 Mon Sep 17 00:00:00 2001 From: Cliff Hill Date: Wed, 28 Aug 2024 16:53:00 -0400 Subject: [PATCH 5/7] Added fields to endpoint. Signed-off-by: Cliff Hill --- app/template_statistics/rest.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/app/template_statistics/rest.py b/app/template_statistics/rest.py index 08467cfeb..cf4482caa 100644 --- a/app/template_statistics/rest.py +++ b/app/template_statistics/rest.py @@ -41,6 +41,11 @@ def get_template_statistics_for_service_by_day(service_id): "count": row.count, "template_id": str(row.template_id), "template_name": row.template_name, + "template_folder_id": row.template_folder_id, + "template_folder": row.folder, + "created_by_id": row.created_by_id, + "created_by": row.created_by, + "last_used": row.last_used, "template_type": row.notification_type, "status": row.status, } From 00e0f41d8537f5bf9ad749992fe8244cd611f58a Mon Sep 17 00:00:00 2001 From: Cliff Hill Date: Wed, 28 Aug 2024 17:07:51 -0400 Subject: [PATCH 6/7] Stuff was done. Signed-off-by: Cliff Hill --- tests/app/template_statistics/test_rest.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tests/app/template_statistics/test_rest.py b/tests/app/template_statistics/test_rest.py index 1ae65b22e..958a2df6c 100644 --- a/tests/app/template_statistics/test_rest.py +++ b/tests/app/template_statistics/test_rest.py @@ -79,6 +79,11 @@ def test_get_template_statistics_for_service_by_day_goes_to_db( template_name=sample_template.name, notification_type=sample_template.template_type, status=NotificationStatus.CREATED, + template_folder_id="123456", + folder="Some_Folder", + created_by_id="987654", + created_by="Mr. Nobody", + last_used="0/0/0", ) ], ) @@ -95,6 +100,11 @@ def test_get_template_statistics_for_service_by_day_goes_to_db( "template_name": sample_template.name, "template_type": sample_template.template_type, "status": NotificationStatus.CREATED, + "template_folder_id": "123456", + "template_folder": "Some_Folder", + "created_by_id": "987654", + "created_by": "Mr. Nobody", + "last_used": "0/0/0", } ] # dao only called for 2nd, since redis returned values for first call From d4c4bbdb76e4305ad13a2811b2e662c70b25605c Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Wed, 28 Aug 2024 14:13:58 -0700 Subject: [PATCH 7/7] debug messages for e2e test story --- app/user/rest.py | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/app/user/rest.py b/app/user/rest.py index a789ee128..0a706b9bf 100644 --- a/app/user/rest.py +++ b/app/user/rest.py @@ -1,4 +1,5 @@ import json +import os import uuid from urllib.parse import urlencode @@ -53,7 +54,7 @@ from app.user.users_schema import ( post_verify_code_schema, post_verify_webauthn_schema, ) -from app.utils import url_with_token, utc_now +from app.utils import hilite, url_with_token, utc_now from notifications_utils.recipients import is_us_phone_number, use_numeric_sender user_blueprint = Blueprint("user", __name__) @@ -588,13 +589,27 @@ def get_user_login_gov_user(): return jsonify(data=result) +def debug_not_production(msg): + if os.getenv("NOTIFY_ENVIRONMENT") not in ["production"]: + current_app.logger.info(msg) + + @user_blueprint.route("/email", methods=["POST"]) def fetch_user_by_email(): - email = email_data_request_schema.load(request.get_json()) - - fetched_user = get_user_by_email(email["email"]) - result = fetched_user.serialize() - return jsonify(data=result) + try: + debug_not_production( + hilite(f"enter fetch_user_by_email with {request.get_json()}") + ) + email = email_data_request_schema.load(request.get_json()) + debug_not_production(hilite(f"request schema loads {email}")) + fetched_user = get_user_by_email(email["email"]) + debug_not_production(hilite(f"fetched user is {fetched_user}")) + result = fetched_user.serialize() + debug_not_production(hilite(f"result is serialized to {result}")) + return jsonify(data=result) + except Exception as e: + debug_not_production(hilite(f"Failed with {e}!!")) + raise e # TODO: Deprecate this GET endpoint