Merge pull request #273 from alphagov/provider_statistics

Fragment count endpoint added and all tests working.
This commit is contained in:
NIcholas Staples
2016-04-29 12:28:54 +01:00
7 changed files with 291 additions and 16 deletions

View File

@@ -1,5 +1,40 @@
from app.models import ProviderStatistics
from sqlalchemy import func
from app.models import (ProviderStatistics, SMS_PROVIDERS, EMAIL_PROVIDERS)
def get_provider_statistics(service, provider):
return ProviderStatistics.query.filter_by(service=service, provider=provider).one()
def get_provider_statistics(service, **kwargs):
return filter_query(ProviderStatistics.query, service, **kwargs)
def get_fragment_count(service, date_from, date_to):
sms_query = filter_query(
ProviderStatistics.query,
service,
providers=SMS_PROVIDERS,
date_from=date_from,
date_to=date_to
)
email_query = filter_query(
ProviderStatistics.query,
service,
providers=EMAIL_PROVIDERS,
date_from=date_from,
date_to=date_to
)
return {
'sms_count': int(sms_query.with_entities(
func.sum(ProviderStatistics.unit_count)).scalar()) if sms_query.count() > 0 else 0,
'email_count': int(email_query.with_entities(
func.sum(ProviderStatistics.unit_count)).scalar()) if email_query.count() > 0 else 0
}
def filter_query(query, service, **kwargs):
query = query.filter_by(service=service)
if 'providers' in kwargs:
query = query.filter(ProviderStatistics.provider.in_(kwargs['providers']))
if 'date_from' in kwargs:
query.filter(ProviderStatistics.day >= kwargs['date_from'])
if 'date_to' in kwargs:
query.filter(ProviderStatistics.day <= kwargs['date_to'])
return query

View File

@@ -187,7 +187,9 @@ TWILIO_PROVIDER = "twilio"
FIRETEXT_PROVIDER = "firetext"
SES_PROVIDER = 'ses'
PROVIDERS = [MMG_PROVIDER, TWILIO_PROVIDER, FIRETEXT_PROVIDER, SES_PROVIDER]
SMS_PROVIDERS = [MMG_PROVIDER, TWILIO_PROVIDER, FIRETEXT_PROVIDER]
EMAIL_PROVIDERS = [SES_PROVIDER]
PROVIDERS = SMS_PROVIDERS + EMAIL_PROVIDERS
class ProviderStatistics(db.Model):

View File

@@ -1,3 +1,4 @@
from datetime import date
from flask_marshmallow.fields import fields
from marshmallow import (
@@ -331,6 +332,31 @@ class EventSchema(BaseSchema):
model = models.Event
class FromToDateSchema(ma.Schema):
date_from = fields.Date()
date_to = fields.Date()
def _validate_not_in_future(self, dte):
if dte > date.today():
raise ValidationError('Date cannot be in the future')
@validates('date_from')
def validate_date_from(self, value):
self._validate_not_in_future(value)
@validates('date_to')
def validate_date_to(self, value):
self._validate_not_in_future(value)
@validates_schema
def validate_dates(self, data):
df = data.get('date_from')
dt = data.get('date_to')
if (df and dt) and (df > dt):
raise ValidationError("date_from needs to be greater than date_to")
user_schema = UserSchema()
user_schema_load_json = UserSchema(load_json=True)
service_schema = ServiceSchema()
@@ -359,3 +385,4 @@ service_history_schema = ServiceHistorySchema()
api_key_history_schema = ApiKeyHistorySchema()
template_history_schema = TemplateHistorySchema()
event_schema = EventSchema()
from_to_date_schema = FromToDateSchema()

View File

@@ -1,4 +1,4 @@
from datetime import datetime
from datetime import (datetime, date)
from flask import Blueprint
from flask import (
@@ -23,12 +23,15 @@ from app.dao.services_dao import (
dao_remove_user_from_service
)
from app.dao.provider_statistics_dao import get_fragment_count
from app.dao.users_dao import get_model_users
from app.models import ApiKey
from app.schemas import (
service_schema,
api_key_schema,
user_schema
user_schema,
from_to_date_schema
)
from app.errors import register_errors
@@ -181,6 +184,20 @@ def _process_permissions(user, service, permission_groups):
return permissions
@service.route('/<uuid:service_id>/fragment/aggregate_statistics')
def get_service_provider_aggregate_statistics(service_id):
service = dao_fetch_service_by_id(service_id)
data, errors = from_to_date_schema.load(request.args)
if errors:
return jsonify(result='error', message=errors), 400
return jsonify(data=get_fragment_count(
service,
date_from=(data.pop('date_from') if 'date_from' in data else date.today()),
date_to=(data.pop('date_to') if 'date_to' in data else date.today())
))
# This is placeholder get method until more thought
# goes into how we want to fetch and view various items in history
# tables. This is so product owner can pass stories as done