mirror of
https://github.com/GSA/notifications-api.git
synced 2026-02-01 23:55:58 -05:00
'detailed' flag on GET /service/<uuid>
if passed in, returns the service object with additional statistics dictionary, which will be used in the admin app to populate dashboard components. A new schema has been created for this to avoid clashing/ causing confusion with the existing schema, which is already used for PUT/POST as well, and this schema can be easily tailored to reduce ambiguity and lazy-loading
This commit is contained in:
@@ -1,15 +1,13 @@
|
||||
import uuid
|
||||
|
||||
from app import db
|
||||
from app.models import Service
|
||||
from sqlalchemy import asc
|
||||
from sqlalchemy import asc, func
|
||||
from sqlalchemy.orm import joinedload
|
||||
|
||||
from app import db
|
||||
from app.dao.dao_utils import (
|
||||
transactional,
|
||||
version_class
|
||||
)
|
||||
|
||||
from app.models import (
|
||||
NotificationStatistics,
|
||||
TemplateStatistics,
|
||||
@@ -135,3 +133,16 @@ def delete_service_and_all_associated_db_objects(service):
|
||||
db.session.commit()
|
||||
list(map(db.session.delete, users))
|
||||
db.session.commit()
|
||||
|
||||
|
||||
def dao_fetch_stats_for_service(service_id):
|
||||
return db.session.query(
|
||||
Notification.notification_type,
|
||||
Notification.status,
|
||||
func.count(Notification.id).label('count')
|
||||
).filter(
|
||||
Notification.service_id == service_id
|
||||
).group_by(
|
||||
Notification.notification_type,
|
||||
Notification.status,
|
||||
).all()
|
||||
|
||||
@@ -123,6 +123,23 @@ class ServiceSchema(BaseSchema):
|
||||
raise ValidationError('Only alphanumeric characters allowed')
|
||||
|
||||
|
||||
class DetailedServiceSchema(BaseSchema):
|
||||
statistics = fields.Dict()
|
||||
|
||||
class Meta:
|
||||
model = models.Service
|
||||
exclude = (
|
||||
'api_keys',
|
||||
'templates',
|
||||
'users',
|
||||
'created_by',
|
||||
'jobs',
|
||||
'template_statistics',
|
||||
'service_provider_stats',
|
||||
'service_notification_stats'
|
||||
)
|
||||
|
||||
|
||||
class NotificationModelSchema(BaseSchema):
|
||||
class Meta:
|
||||
model = models.Notification
|
||||
@@ -486,6 +503,7 @@ user_schema = UserSchema()
|
||||
user_schema_load_json = UserSchema(load_json=True)
|
||||
service_schema = ServiceSchema()
|
||||
service_schema_load_json = ServiceSchema(load_json=True)
|
||||
detailed_service_schema = DetailedServiceSchema()
|
||||
template_schema = TemplateSchema()
|
||||
template_schema_load_json = TemplateSchema(load_json=True)
|
||||
api_key_schema = ApiKeySchema()
|
||||
|
||||
@@ -8,6 +8,7 @@ from flask import (
|
||||
)
|
||||
from sqlalchemy.orm.exc import NoResultFound
|
||||
|
||||
from app.models import EMAIL_TYPE, SMS_TYPE
|
||||
from app.dao.api_key_dao import (
|
||||
save_model_api_key,
|
||||
get_model_api_keys,
|
||||
@@ -20,7 +21,8 @@ from app.dao.services_dao import (
|
||||
dao_update_service,
|
||||
dao_fetch_all_services_by_user,
|
||||
dao_add_user_to_service,
|
||||
dao_remove_user_from_service
|
||||
dao_remove_user_from_service,
|
||||
dao_fetch_stats_for_service
|
||||
)
|
||||
from app.dao import notifications_dao
|
||||
from app.dao.provider_statistics_dao import get_fragment_count
|
||||
@@ -33,6 +35,7 @@ from app.schemas import (
|
||||
permission_schema,
|
||||
notification_status_schema,
|
||||
notifications_filter_schema,
|
||||
detailed_service_schema
|
||||
)
|
||||
from app.utils import pagination_links
|
||||
from app.errors import (
|
||||
@@ -57,10 +60,13 @@ def get_services():
|
||||
|
||||
@service.route('/<uuid:service_id>', methods=['GET'])
|
||||
def get_service_by_id(service_id):
|
||||
fetched = dao_fetch_service_by_id(service_id)
|
||||
if 'detailed' in request.args:
|
||||
return get_detailed_service(service_id)
|
||||
else:
|
||||
fetched = dao_fetch_service_by_id(service_id)
|
||||
|
||||
data = service_schema.dump(fetched).data
|
||||
return jsonify(data=data)
|
||||
data = service_schema.dump(fetched).data
|
||||
return jsonify(data=data)
|
||||
|
||||
|
||||
@service.route('', methods=['POST'])
|
||||
@@ -227,3 +233,30 @@ def get_all_notifications_for_service(service_id):
|
||||
**kwargs
|
||||
)
|
||||
), 200
|
||||
|
||||
|
||||
def get_detailed_service(service_id):
|
||||
service = dao_fetch_service_by_id(service_id)
|
||||
statistics = dao_fetch_stats_for_service(service_id)
|
||||
service.statistics = format_statistics(statistics)
|
||||
data = detailed_service_schema.dump(service).data
|
||||
return jsonify(data=data)
|
||||
|
||||
|
||||
def format_statistics(statistics):
|
||||
# statistics come in a named tuple with uniqueness from 'notification_type', 'status' - however missing
|
||||
# statuses/notification types won't be represented and the status types need to be simplified/summed up
|
||||
# so we can return emails/sms * created, sent, and failed
|
||||
counts = {
|
||||
template_type: {
|
||||
status: 0 for status in ('requested', 'delivered', 'failed')
|
||||
} for template_type in (EMAIL_TYPE, SMS_TYPE)
|
||||
}
|
||||
for row in statistics:
|
||||
counts[row.notification_type]['requested'] += row.count
|
||||
if row.status == 'delivered':
|
||||
counts[row.notification_type]['delivered'] += row.count
|
||||
elif row.status in ('failed', 'technical-failure', 'temporary-failure', 'permanent-failure'):
|
||||
counts[row.notification_type]['failed'] += row.count
|
||||
|
||||
return counts
|
||||
|
||||
Reference in New Issue
Block a user