mirror of
https://github.com/GSA/notifications-api.git
synced 2026-08-11 17:38:02 -04:00
Add an endpoint to return all the data required for the performance
platform page.
This commit is contained in:
@@ -150,6 +150,7 @@ def register_blueprint(application):
|
||||
from app.organisation.rest import organisation_blueprint
|
||||
from app.organisation.invite_rest import organisation_invite_blueprint
|
||||
from app.complaint.complaint_rest import complaint_blueprint
|
||||
from app.performance_platform.rest import performance_platform_blueprint
|
||||
from app.platform_stats.rest import platform_stats_blueprint
|
||||
from app.template_folder.rest import template_folder_blueprint
|
||||
from app.letter_branding.letter_branding_rest import letter_branding_blueprint
|
||||
@@ -228,6 +229,9 @@ def register_blueprint(application):
|
||||
complaint_blueprint.before_request(requires_admin_auth)
|
||||
application.register_blueprint(complaint_blueprint)
|
||||
|
||||
performance_platform_blueprint.before_request(requires_admin_auth)
|
||||
application.register_blueprint(performance_platform_blueprint)
|
||||
|
||||
platform_stats_blueprint.before_request(requires_admin_auth)
|
||||
application.register_blueprint(platform_stats_blueprint, url_prefix='/platform-stats')
|
||||
|
||||
|
||||
@@ -442,6 +442,37 @@ def get_total_sent_notifications_for_day_and_type(day, notification_type):
|
||||
return result or 0
|
||||
|
||||
|
||||
def get_total_notifications_for_date_range(start_date, end_date):
|
||||
|
||||
result = db.session.query(
|
||||
FactNotificationStatus.bst_date.cast(db.Text).label("bst_date"),
|
||||
func.sum(case(
|
||||
[
|
||||
(FactNotificationStatus.notification_type == 'email', FactNotificationStatus.notification_count)
|
||||
],
|
||||
else_=0)).label('emails'),
|
||||
func.sum(case(
|
||||
[
|
||||
(FactNotificationStatus.notification_type == 'sms', FactNotificationStatus.notification_count)
|
||||
],
|
||||
else_=0)).label('sms'),
|
||||
func.sum(case(
|
||||
[
|
||||
(FactNotificationStatus.notification_type == 'letter', FactNotificationStatus.notification_count)
|
||||
],
|
||||
else_=0)).label('letters'),
|
||||
).filter(
|
||||
FactNotificationStatus.key_type != KEY_TYPE_TEST,
|
||||
FactNotificationStatus.bst_date >= start_date,
|
||||
FactNotificationStatus.bst_date <= end_date
|
||||
).group_by(
|
||||
FactNotificationStatus.bst_date
|
||||
).order_by(
|
||||
FactNotificationStatus.bst_date
|
||||
)
|
||||
return result.all()
|
||||
|
||||
|
||||
def fetch_monthly_notification_statuses_per_service(start_date, end_date):
|
||||
return db.session.query(
|
||||
func.date_trunc('month', FactNotificationStatus.bst_date).cast(Date).label('date_created'),
|
||||
|
||||
@@ -30,3 +30,18 @@ def insert_update_processing_time(processing_time):
|
||||
}
|
||||
)
|
||||
db.session.connection().execute(stmt)
|
||||
|
||||
|
||||
def get_processing_time_percentage_for_date_range(start_date, end_date):
|
||||
query = db.session.query(
|
||||
FactProcessingTime.bst_date.cast(db.Text).label("date"),
|
||||
FactProcessingTime.messages_total,
|
||||
FactProcessingTime.messages_within_10_secs,
|
||||
((FactProcessingTime.messages_within_10_secs / FactProcessingTime.messages_total.cast(
|
||||
db.Float)) * 100).label("percentage")
|
||||
).filter(
|
||||
FactProcessingTime.bst_date >= start_date,
|
||||
FactProcessingTime.bst_date <= end_date
|
||||
).order_by(FactProcessingTime.bst_date)
|
||||
|
||||
return query.all()
|
||||
|
||||
@@ -614,3 +614,23 @@ def dao_find_services_with_high_failure_rates(start_date, end_date, threshold=10
|
||||
)
|
||||
|
||||
return query.all()
|
||||
|
||||
|
||||
def get_live_services_with_organisation():
|
||||
query = db.session.query(
|
||||
Service.id.label("service_id"),
|
||||
Service.name.label("service_name"),
|
||||
Organisation.id.label("organisation_id"),
|
||||
Organisation.name.label("organisation_name")
|
||||
).outerjoin(
|
||||
Service.organisation
|
||||
).filter(
|
||||
Service.count_as_live.is_(True),
|
||||
Service.active.is_(True),
|
||||
Service.restricted.is_(False)
|
||||
).order_by(
|
||||
Organisation.name,
|
||||
Service.name
|
||||
)
|
||||
|
||||
return query.all()
|
||||
10
app/performance_platform/performance_platform_schema.py
Normal file
10
app/performance_platform/performance_platform_schema.py
Normal file
@@ -0,0 +1,10 @@
|
||||
performance_platform_request = {
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"description": "Performance platform request schema",
|
||||
"type": "object",
|
||||
"title": "Performance platform request",
|
||||
"properties": {
|
||||
"start_date": {"type": ["string", "null"], "format": "date"},
|
||||
"end_date": {"type": ["string", "null"], "format": "date"},
|
||||
}
|
||||
}
|
||||
85
app/performance_platform/rest.py
Normal file
85
app/performance_platform/rest.py
Normal file
@@ -0,0 +1,85 @@
|
||||
from datetime import datetime
|
||||
|
||||
from flask import Blueprint, request, jsonify
|
||||
|
||||
from app.dao.fact_notification_status_dao import get_total_notifications_for_date_range
|
||||
from app.dao.fact_processing_time_dao import get_processing_time_percentage_for_date_range
|
||||
from app.dao.services_dao import get_live_services_with_organisation
|
||||
from app.errors import register_errors
|
||||
from app.performance_platform.performance_platform_schema import performance_platform_request
|
||||
from app.schema_validation import validate
|
||||
|
||||
performance_platform_blueprint = Blueprint('performance_platform', __name__, url_prefix='/performance-platform')
|
||||
|
||||
register_errors(performance_platform_blueprint)
|
||||
|
||||
|
||||
@performance_platform_blueprint.route('')
|
||||
def get_performance_platform():
|
||||
# All statistics are as of last night this matches the existing performance platform
|
||||
# and avoids the need to query notifications.
|
||||
if request.args:
|
||||
# Is it ok to reuse this? - should probably create a new one
|
||||
validate(request.args, performance_platform_request)
|
||||
|
||||
# If start and end date are not set, we are expecting today's stats.
|
||||
today = str(datetime.utcnow().date())
|
||||
|
||||
start_date = datetime.strptime(request.args.get('start_date', today), '%Y-%m-%d').date()
|
||||
end_date = datetime.strptime(request.args.get('end_date', today), '%Y-%m-%d').date()
|
||||
results = get_total_notifications_for_date_range(start_date=start_date, end_date=end_date)
|
||||
total_notifications, emails, sms, letters = transform_results_into_totals(results)
|
||||
processing_time_results = get_processing_time_percentage_for_date_range(start_date=start_date, end_date=end_date)
|
||||
services = get_live_services_with_organisation()
|
||||
stats = {
|
||||
"total_notifications": total_notifications,
|
||||
"email_notifications": emails,
|
||||
"sms_notifications": sms,
|
||||
"letter_notifications": letters,
|
||||
"notifications_by_type": transform_results_to_json(results),
|
||||
"processing_time": transform_processing_time_results_to_json(processing_time_results),
|
||||
"live_service_count": len(services),
|
||||
"services_using_notify": transform_services_to_json(services)
|
||||
|
||||
}
|
||||
|
||||
return jsonify(stats)
|
||||
|
||||
|
||||
def transform_results_into_totals(results):
|
||||
total_notifications = 0
|
||||
emails = 0
|
||||
sms = 0
|
||||
letters = 0
|
||||
for x in results:
|
||||
total_notifications += x.emails
|
||||
total_notifications += x.sms
|
||||
total_notifications += x.letters
|
||||
emails += x.emails
|
||||
sms += x.sms
|
||||
letters += x.letters
|
||||
return total_notifications, emails, sms, letters
|
||||
|
||||
|
||||
def transform_results_to_json(results):
|
||||
j = []
|
||||
for x in results:
|
||||
j.append({"date": x.bst_date, "emails": x.emails, "sms": x.sms, "letters": x.letters})
|
||||
return j
|
||||
|
||||
|
||||
def transform_processing_time_results_to_json(results):
|
||||
j = []
|
||||
for x in results:
|
||||
j.append({"date": x.date, "percentage_under_10_seconds": round(x.percentage, 1)})
|
||||
|
||||
return j
|
||||
|
||||
|
||||
def transform_services_to_json(results):
|
||||
j=[]
|
||||
for x in results:
|
||||
j.append({"service_id": x.service_id, "service_name": x.service_name,
|
||||
"organisation_id": x.organisation_id, "organisation_name": x.organisation_name}
|
||||
)
|
||||
return j
|
||||
Reference in New Issue
Block a user