get_invited_org_users_for_organisation) from app.dao.templates_dao import dao_get_template_by_id from app.errors import register_errors from app.models import EMAIL_TYPE, KEY_TYPE_NORMAL, InvitedOrganisationUser from app.notifications.process_notifications import persist_notification, send_notification_to_queue from app.schema_validation import validate from app.organisation.organisation_schema import ( post_create_invited_org_user_status_schema, post_update_invited_org_user_status_schema) organisation_invite_blueprint = Blueprint( 'organisation_invite', __name__, url_prefix='/organisation/<uuid:organisation_id>/invite') register_errors(organisation_invite_blueprint) @organisation_invite_blueprint.route('', methods=['POST']) def invite_user_to_org(organisation_id): data = request.get_json() validate(data, post_create_invited_org_user_status_schema) invited_org_user = InvitedOrganisationUser( email_address=data['email_address'], invited_by_id=data['invited_by'], organisation_id=organisation_id) save_invited_org_user(invited_org_user) template = dao_get_template_by_id( current_app.config['ORGANISATION_INVITATION_EMAIL_TEMPLATE_ID'])
import iso8601 from flask import jsonify, Blueprint, current_app, request, abort from notifications_utils.recipients import try_validate_and_format_phone_number from notifications_utils.timezones import convert_bst_to_utc from app import statsd_client from app.celery import tasks from app.config import QueueNames from app.dao.services_dao import dao_fetch_service_by_inbound_number from app.dao.inbound_sms_dao import dao_create_inbound_sms from app.models import InboundSms, INBOUND_SMS_TYPE, SMS_TYPE from app.errors import register_errors receive_notifications_blueprint = Blueprint('receive_notifications', __name__) register_errors(receive_notifications_blueprint) @receive_notifications_blueprint.route('/notifications/sms/receive/mmg', methods=['POST']) def receive_mmg_sms(): """ { 'MSISDN': '447123456789' 'Number': '40604', 'Message': 'some+uri+encoded+message%3A', 'ID': 'SOME-MMG-SPECIFIC-ID', 'DateRecieved': '2017-05-21+11%3A56%3A11' } """ post_data = request.get_json()
from flask import Blueprint from flask import current_app from flask import json from flask import request, jsonify from app.errors import InvalidRequest, register_errors from app.notifications.process_client_response import validate_callback_data, process_sms_client_response sms_callback_blueprint = Blueprint("sms_callback", __name__, url_prefix="/notifications/sms") register_errors(sms_callback_blueprint) @sms_callback_blueprint.route('/mmg', methods=['POST']) def process_mmg_response(): client_name = 'MMG' data = json.loads(request.data) errors = validate_callback_data(data=data, fields=['status', 'CID'], client_name=client_name) if errors: raise InvalidRequest(errors, status_code=400) success, errors = process_sms_client_response( status=str(data.get('status')), provider_reference=data.get('CID'), client_name=client_name) safe_to_log = data.copy() safe_to_log.pop("MSISDN")
from flask import Blueprint, jsonify, request from app import DATETIME_FORMAT from app.dao.notifications_dao import dao_get_last_date_template_was_used from app.dao.templates_dao import dao_get_template_by_id_and_service_id from app.dao.fact_notification_status_dao import fetch_notification_status_for_service_for_today_and_7_previous_days from app.errors import register_errors, InvalidRequest template_statistics = Blueprint( 'template_statistics', __name__, url_prefix='/service/<service_id>/template-statistics') register_errors(template_statistics) @template_statistics.route('') def get_template_statistics_for_service_by_day(service_id): whole_days = request.args.get('whole_days', request.args.get('limit_days', '')) try: whole_days = int(whole_days) except ValueError: error = '{} is not an integer'.format(whole_days) message = {'whole_days': [error]} raise InvalidRequest(message, status_code=400) if whole_days < 0 or whole_days > 7: raise InvalidRequest( {'whole_days': ['whole_days must be between 0 and 7']},
from flask import Blueprint from flask import current_app from flask import json from flask import request, jsonify from app import statsd_client from app.errors import InvalidRequest, register_errors from app.notifications.process_client_response import validate_callback_data, process_shortnumber_keyword_client_response from app.dao.services_dao import dao_fetch_service_by_inbound_shortnumber from app.models import INBOUND_SMS_KEYWORD_TYPE, SMS_TYPE shortnumber_keyword_callback_blueprint = Blueprint( "shortnumber_keyword_callback", __name__, url_prefix="/notifications/sms/shortnumber_keyword") register_errors(shortnumber_keyword_callback_blueprint) @shortnumber_keyword_callback_blueprint.route('/sinch', methods=['POST']) def process_sinch_response(): client_name = 'Sinch' data = json.loads(request.data) errors = validate_callback_data( data=data, fields=['id', 'from', 'to', 'body', 'received_at'], client_name=client_name) if errors: raise InvalidRequest(errors, status_code=400)
dao_update_template_reply_to, get_precompiled_letter_template, ) from app.errors import InvalidRequest, register_errors from app.letters.utils import get_letter_pdf from app.models import LETTER_TYPE, SECOND_CLASS, SMS_TYPE, Template from app.notifications.validators import check_reply_to, service_has_permission from app.schema_validation import validate from app.schemas import template_history_schema, template_schema from app.template.template_schemas import post_create_template_schema from app.utils import get_public_notify_type_text, get_template_instance template_blueprint = Blueprint( "template", __name__, url_prefix="/service/<uuid:service_id>/template") register_errors(template_blueprint) def _content_count_greater_than_limit(content, template_type): if template_type != SMS_TYPE: return False template = SMSMessageTemplate({ "content": content, "template_type": template_type }) return template.content_count > SMS_CHAR_COUNT_LIMIT def validate_parent_folder(template_json): if template_json.get("parent_folder_id"): try:
'service_sms_sender', __name__, url_prefix='/service/<uuid:service_id>/sms-sender') service_sms_sender_blueprint.before_request(validate_admin_auth) service_sms_sender_blueprint.before_request(_validate_service_exists) @service_sms_sender_blueprint.errorhandler(SmsSenderDefaultValidationException) @service_sms_sender_blueprint.errorhandler( SmsSenderInboundNumberIntegrityException) def handle_errors(error): current_app.logger.info(error) return jsonify(result='error', message=str(error)), 400 register_errors(service_sms_sender_blueprint) @service_sms_sender_blueprint.route('', methods=['GET']) def get_service_sms_senders_for_service(service_id): sms_senders = dao_get_sms_senders_by_service_id(service_id=service_id) return jsonify([sms_sender.serialize() for sms_sender in sms_senders]), 200 @service_sms_sender_blueprint.route('', methods=['POST']) def add_service_sms_sender(service_id): form = validate(request.get_json(), add_service_sms_sender_request) new_sms_sender = dao_add_sms_sender_for_service(service_id=service_id, **form) return jsonify(new_sms_sender.serialize()), 201
from itsdangerous import SignatureExpired from notifications_utils.url_safe_token import check_token from app.dao.invited_user_dao import get_invited_user_by_id from app.errors import ( register_errors, InvalidRequest ) from app.schemas import invited_user_schema accept_invite = Blueprint('accept_invite', __name__) register_errors(accept_invite) @accept_invite.route('/<token>', methods=['GET']) def get_invited_user_by_token(token): max_age_seconds = 60 * 60 * 24 * current_app.config['INVITATION_EXPIRATION_DAYS'] try: invited_user_id = check_token(token, current_app.config['SECRET_KEY'], current_app.config['DANGEROUS_SALT'], max_age_seconds) except SignatureExpired: errors = {'invitation': ['Your invitation to GOV.UK Notify has expired. '
dao_get_inbound_sms_by_id, dao_get_inbound_sms_for_service, dao_get_paginated_most_recent_inbound_sms_by_user_number_for_service, ) from app.dao.service_data_retention_dao import ( fetch_service_data_retention_by_notification_type, ) from app.errors import register_errors from app.inbound_sms.inbound_sms_schemas import ( get_inbound_sms_for_service_schema, ) from app.schema_validation import validate inbound_sms = Blueprint('inbound_sms', __name__, url_prefix='/service/<uuid:service_id>/inbound-sms') register_errors(inbound_sms) @inbound_sms.route('', methods=['POST']) def post_inbound_sms_for_service(service_id): form = validate(request.get_json(), get_inbound_sms_for_service_schema) user_number = form.get('phone_number') if user_number: # we use this to normalise to an international phone number - but this may fail if it's an alphanumeric user_number = try_validate_and_format_phone_number(user_number, international=True) inbound_data_retention = fetch_service_data_retention_by_notification_type( service_id, 'sms') limit_days = inbound_data_retention.days_of_retention if inbound_data_retention else 7
from flask import (Blueprint, jsonify, current_app) from itsdangerous import SignatureExpired, BadData from notifications_utils.url_safe_token import check_token from app.dao.invited_user_dao import get_invited_user_by_id from app.dao.organisation_dao import dao_get_invited_organisation_user from app.errors import (register_errors, InvalidRequest) from app.schemas import invited_user_schema accept_invite = Blueprint('accept_invite', __name__) register_errors(accept_invite) @accept_invite.route('/<invitation_type>/<token>', methods=['GET']) def validate_invitation_token(invitation_type, token): max_age_seconds = 60 * 60 * 24 * current_app.config[ 'INVITATION_EXPIRATION_DAYS'] try: invited_user_id = check_token(token, current_app.config['SECRET_KEY'], current_app.config['DANGEROUS_SALT'], max_age_seconds) except SignatureExpired: errors = {'invitation': 'invitation expired'} raise InvalidRequest(errors, status_code=400) except BadData:
from flask import Blueprint, current_app from flask_jwt_extended import jwt_required from app.comms.stats import send_ga_event from app.dao.emails_dao import dao_get_emails_sent_count from app.na_celery.stats_tasks import send_num_subscribers_and_social_stats from app.errors import register_errors stats_blueprint = Blueprint('stats', __name__) register_errors(stats_blueprint) @stats_blueprint.route('/stats/social') @jwt_required def send_social_stats(): current_app.logger.info("Sending social stats...") _, _, facebook_count, instagram_count = send_num_subscribers_and_social_stats( inc_subscribers=False) current_app.logger.info("Social stats %r, %r", facebook_count, instagram_count) return f'facebook={facebook_count}, instagram={instagram_count}' @stats_blueprint.route('/stats/subscribers_and_social') @jwt_required def send_subscribers_and_social_stats(): current_app.logger.info("Sending subscribers and social stats...") num_subscribers, num_new_subscribers, facebook_count, instagram_count = send_num_subscribers_and_social_stats( inc_subscribers=True) current_app.logger.info("Social stats %r, %r", facebook_count, instagram_count)
from app.comms.email import get_nice_event_dates from app.errors import register_errors, InvalidRequest from app.models import ( Email, EmailToMember, Member, ANNOUNCEMENT, EVENT, MAGAZINE, MANAGED_EMAIL_TYPES, READY, APPROVED, REJECTED ) from app.routes.emails.schemas import ( post_create_email_schema, post_update_email_schema, post_import_emails_schema, post_preview_email_schema, post_import_email_members_schema ) from app.schema_validation import validate emails_blueprint = Blueprint('emails', __name__) register_errors(emails_blueprint) @emails_blueprint.route('/email/preview', methods=['GET']) def email_preview(): data = json.loads(urlparse.unquote(request.args.get('data'))) validate(data, post_preview_email_schema) current_app.logger.info('Email preview: {}'.format(data)) html = get_email_html(**data) return html @emails_blueprint.route('/email', methods=['POST'])
from flask import Blueprint, jsonify from app.dao.organisation_dao import dao_get_organisations, dao_get_organisation_by_id from app.schemas import organisation_schema from app.errors import register_errors organisation_blueprint = Blueprint('organisation', __name__) register_errors(organisation_blueprint) @organisation_blueprint.route('', methods=['GET']) def get_organisations(): data = organisation_schema.dump(dao_get_organisations(), many=True).data return jsonify(organisations=data) @organisation_blueprint.route('/<uuid:org_id>', methods=['GET']) def get_organisation_by_id(org_id): data = organisation_schema.dump(dao_get_organisation_by_id(org_id)).data return jsonify(organisation=data)
) from app.schemas import (email_data_request_schema, partial_email_data_request_schema, create_user_schema, permission_schema, user_update_schema_load_json, user_update_password_schema_load_json) from app.errors import (register_errors, InvalidRequest) from app.utils import url_with_token from app.user.users_schema import ( post_verify_code_schema, post_send_user_sms_code_schema, post_send_user_email_code_schema, ) from app.schema_validation import validate user_blueprint = Blueprint('user', __name__) register_errors(user_blueprint) @user_blueprint.errorhandler(IntegrityError) def handle_integrity_error(exc): """ Handle integrity errors caused by the auth type/mobile number check constraint """ if 'ck_users_mobile_or_email_auth' in str(exc): # we don't expect this to trip, so still log error current_app.logger.exception( 'Check constraint ck_users_mobile_or_email_auth triggered') return jsonify( result='error', message='Mobile number must be set if auth_type is set to sms_auth' ), 400
dao_get_speakers, dao_get_speaker_by_id, dao_get_speaker_by_name, dao_create_speaker, dao_update_speaker ) from app.errors import register_errors from app.models import Speaker from app.schema_validation import validate from app.routes.speakers.schemas import ( post_create_speaker_schema, post_create_speakers_schema, post_import_speakers_schema, post_update_speaker_schema ) speakers_blueprint = Blueprint('speakers', __name__) speaker_blueprint = Blueprint('speaker', __name__) register_errors(speakers_blueprint) register_errors(speaker_blueprint) @speakers_blueprint.route('/speakers') @jwt_required def get_speakers(): speakers = [s.serialize() if s else None for s in dao_get_speakers()] return jsonify(speakers) @speakers_blueprint.route('/speakers', methods=['POST']) @jwt_required def create_speakers(): data = request.get_json(force=True)
from app.schemas import provider_details_schema from app.dao.provider_details_dao import ( get_provider_details, get_provider_details_by_id, dao_update_provider_details ) from app.errors import ( register_errors, InvalidRequest ) provider_details = Blueprint('provider_details', __name__) register_errors(provider_details) @provider_details.route('', methods=['GET']) def get_providers(): data = provider_details_schema.dump(get_provider_details(), many=True).data return jsonify(provider_details=data) @provider_details.route('/<uuid:provider_details_id>', methods=['GET']) def get_provider_by_id(provider_details_id): data = provider_details_schema.dump(get_provider_details_by_id(provider_details_id)).data return jsonify(provider_details=data) @provider_details.route('/<uuid:provider_details_id>', methods=['POST'])
from jsonschema.exceptions import ValidationError from sqlalchemy.orm.exc import MultipleResultsFound, NoResultFound from app import statsd_client from app.clients.email.govdelivery_client import govdelivery_status_map from app.dao import notifications_dao from app.errors import register_errors, InvalidRequest from app.schema_validation import validate from .govelivery_schema import govdelivery_webhook_schema from ..celery.service_callback_tasks import publish_complaint from ..dao.complaint_dao import save_complaint from ..models import Notification, Complaint govdelivery_callback_blueprint = Blueprint( "govdelivery_callback", __name__, url_prefix="/notifications/govdelivery") register_errors(govdelivery_callback_blueprint) @govdelivery_callback_blueprint.route('', methods=['POST']) def process_govdelivery_response(): try: data = validate(request.form, govdelivery_webhook_schema) sid = data['sid'] reference = data['message_url'].split("/")[-1] govdelivery_status = data['status'] notify_status = govdelivery_status_map[govdelivery_status] except ValidationError as e: raise e except Exception as e: raise InvalidRequest(f'Error processing Govdelivery callback: {e}',
dao_get_template_versions ) from notifications_utils.template import SMSMessageTemplate from app.dao.services_dao import dao_fetch_service_by_id from app.models import SMS_TYPE from app.schemas import (template_schema, template_history_schema) template = Blueprint('template', __name__, url_prefix='/service/<uuid:service_id>/template') from app.errors import ( register_errors, InvalidRequest ) from app.utils import get_template_instance register_errors(template) def _content_count_greater_than_limit(content, template_type): if template_type != SMS_TYPE: return False template = SMSMessageTemplate({'content': content, 'template_type': template_type}) return template.content_count > current_app.config.get('SMS_CHAR_COUNT_LIMIT') @template.route('', methods=['POST']) def create_template(service_id): fetched_service = dao_fetch_service_by_id(service_id=service_id) new_template = template_schema.load(request.get_json()).data new_template.service = fetched_service new_template.content = _strip_html(new_template.content)
from flask import Blueprint, jsonify, current_app from app import db from app.errors import register_errors base_blueprint = Blueprint('', __name__) register_errors(base_blueprint) @base_blueprint.route('/') def get_info(): current_app.logger.info('get_info') query = 'SELECT version_num FROM alembic_version' try: full_name = db.session.execute(query).fetchone()[0] except Exception as e: current_app.logger.error('Database exception: %r', e) full_name = 'Database error, check logs' return jsonify(environment=current_app.config['ENVIRONMENT'], info=full_name, commit=current_app.config['TRAVIS_COMMIT'])
from app.dao.services_dao import dao_fetch_service_by_id from app.errors import register_errors, InvalidRequest from app.models import BroadcastMessage, BroadcastStatusType, BroadcastEvent, BroadcastEventMessageType from app.celery.broadcast_message_tasks import send_broadcast_event from app.broadcast_message.broadcast_message_schema import ( create_broadcast_message_schema, update_broadcast_message_schema, update_broadcast_message_status_schema, ) from app.schema_validation import validate broadcast_message_blueprint = Blueprint( 'broadcast_message', __name__, url_prefix='/service/<uuid:service_id>/broadcast-message') register_errors(broadcast_message_blueprint) def _parse_nullable_datetime(dt): if dt: return iso8601.parse_date(dt).replace(tzinfo=None) return dt def _update_broadcast_message(broadcast_message, new_status, updating_user): if updating_user not in broadcast_message.service.users: raise InvalidRequest( f'User {updating_user.id} cannot approve broadcast_message {broadcast_message.id} from other service', status_code=400) if new_status not in BroadcastStatusType.ALLOWED_STATUS_TRANSITIONS[
from app.utils import convert_utc_to_aet from app.dao.annual_billing_dao import ( dao_get_free_sms_fragment_limit_for_year, dao_get_all_free_sms_fragment_limit, dao_create_or_update_annual_billing_for_year, dao_update_annual_billing_for_future_years) from app.billing.billing_schemas import create_or_update_free_sms_fragment_limit_schema from app.errors import InvalidRequest from app.schema_validation import validate from app.dao.date_util import get_current_financial_year_start_year billing_blueprint = Blueprint('billing', __name__, url_prefix='/service/<uuid:service_id>/billing') register_errors(billing_blueprint) @billing_blueprint.route('/monthly-usage') def get_yearly_usage_by_month(service_id): try: year = int(request.args.get('year')) results = [] for month in get_months_for_financial_year(year): billing_for_month = get_monthly_billing_by_notification_type( service_id, month, SMS_TYPE) if billing_for_month: results.append( _transform_billing_for_month_sms(billing_for_month)) letter_billing_for_month = get_monthly_billing_by_notification_type( service_id, month, LETTER_TYPE)
get_service_inbound_api, reset_service_inbound_api, delete_service_inbound_api, ) from app.dao.service_callback_api_dao import ( save_service_callback_api, get_service_callback_api, reset_service_callback_api, delete_service_callback_api, ) service_callback_blueprint = Blueprint('service_callback', __name__, url_prefix='/service/<uuid:service_id>') register_errors(service_callback_blueprint) @service_callback_blueprint.route('/inbound-api', methods=['POST']) def create_service_inbound_api(service_id): data = request.get_json() validate(data, create_service_callback_api_schema) data["service_id"] = service_id inbound_api = ServiceInboundApi(**data) try: save_service_inbound_api(inbound_api) except SQLAlchemyError as e: return handle_sql_error(e, 'service_inbound_api') return jsonify(data=inbound_api.serialize()), 201
from json import decoder from app.notifications import process_notifications from app.notifications.notifications_ses_callback import ( determine_notification_bounce_type, handle_ses_complaint, handle_smtp_complaint) from app.celery.service_callback_tasks import ( check_and_queue_callback_task, _check_and_queue_complaint_callback_task) from app.errors import (register_errors, InvalidRequest) from cachelib import SimpleCache import validatesns ses_callback_blueprint = Blueprint('notifications_ses_callback', __name__) ses_smtp_callback_blueprint = Blueprint('notifications_ses_smtp_callback', __name__) register_errors(ses_callback_blueprint) register_errors(ses_smtp_callback_blueprint) class SNSMessageType(enum.Enum): SubscriptionConfirmation = 'SubscriptionConfirmation' Notification = 'Notification' UnsubscribeConfirmation = 'UnsubscribeConfirmation' class InvalidMessageTypeException(Exception): pass def verify_message_type(message_type: str): try:
from app.service.send_notification import send_one_off_notification, send_pdf_letter_notification from app.schemas import (service_schema, api_key_schema, notification_with_template_schema, notifications_filter_schema, detailed_service_schema, email_data_request_schema) from app.user.users_schema import post_set_permissions_schema from app.utils import pagination_links from app.smtp.aws import (smtp_add, smtp_get_user_key, smtp_remove) from nanoid import generate CAN_T_BE_EMPTY_ERROR_MESSAGE = "Can't be empty" service_blueprint = Blueprint('service', __name__) register_errors(service_blueprint) @service_blueprint.errorhandler(IntegrityError) def handle_integrity_error(exc): """ Handle integrity errors caused by the unique constraint on ix_organisation_name """ if any('duplicate key value violates unique constraint "{}"'.format( constraint) in str(exc) for constraint in {'services_name_key', 'services_email_from_key'}): return jsonify(result='error', message={ 'name': [ "Duplicate service name '{}'".format( exc.params.get(
from flask import Blueprint, jsonify, request from app.dao.provider_details_dao import ( dao_get_provider_stats, dao_get_provider_versions, dao_update_provider_details, get_provider_details_by_id, ) from app.dao.users_dao import get_user_by_id from app.errors import InvalidRequest, register_errors from app.schemas import provider_details_history_schema, provider_details_schema provider_details = Blueprint("provider_details", __name__) register_errors(provider_details) @provider_details.route("", methods=["GET"]) def get_providers(): data = dao_get_provider_stats() provider_details = [{ "id": row.id, "display_name": row.display_name, "identifier": row.identifier, "priority": row.priority, "notification_type": row.notification_type,
email_notification_schema, notification_with_personalisation_schema, notifications_filter_schema, sms_template_notification_schema, ) from app.service.utils import service_allowed_to_send_to from app.utils import ( get_document_url, get_public_notify_type_text, get_template_instance, pagination_links, ) notifications = Blueprint("notifications", __name__) register_errors(notifications) @notifications.route("/notifications/<uuid:notification_id>", methods=["GET"]) def get_notification_by_id(notification_id): notification = notifications_dao.get_notification_with_personalisation( str(authenticated_service.id), notification_id, key_type=None) return ( jsonify( data={ "notification": notification_with_personalisation_schema.dump( notification).data }), 200, )
from app.dao.users_dao import dao_get_admin_users, dao_get_users from app.dao.venues_dao import dao_get_venue_by_old_id, dao_get_venue_by_id from app.errors import register_errors, InvalidRequest, PaypalException from app.models import Event, EventDate, RejectReason, APPROVED, DRAFT, READY, REJECTED from app.routes import is_running_locally from app.routes.events.schemas import post_create_event_schema, post_update_event_schema, post_import_events_schema from app.schema_validation import validate from app.payments.paypal import PayPal from app.storage.utils import Storage events_blueprint = Blueprint('events', __name__) register_errors(events_blueprint) def extract_startdate(json): if json['event_dates']: return json['event_dates'][0]['event_datetime'] else: return 0 @events_blueprint.route('/paypal/<item_id>', methods=['POST']) @jwt_required def create_test_paypal(item_id): if current_app.config['ENVIRONMENT'] == 'live': return 'Cannot test paypal on live environment'
from flask import Blueprint, jsonify, request from app.dao.events_dao import dao_create_event from app.errors import register_errors from app.schemas import event_schema events = Blueprint('events', __name__, url_prefix='/events') register_errors(events) @events.route('', methods=['POST']) def create_event(): data = request.get_json() event = event_schema.load(data).data dao_create_event(event) return jsonify(data=event_schema.dump(event).data), 201
from flask import (Blueprint, current_app, jsonify, render_template, request) from app.errors import register_errors from app.models import EmailProvider from flask_jwt_extended import jwt_required from app.dao.email_providers_dao import (dao_create_email_provider, dao_update_email_provider, dao_get_email_provider_by_id, dao_get_first_email_provider, dao_get_email_providers) from app.routes.email_providers.schemas import post_create_email_provider_schema, post_update_email_provider_schema from app.schema_validation import validate email_providers_blueprint = Blueprint('email_provider', __name__) register_errors(email_providers_blueprint) @email_providers_blueprint.route('/email_provider', methods=['POST']) @jwt_required def create_email_provider(): data = request.get_json(force=True) validate(data, post_create_email_provider_schema) email_provider = EmailProvider(**data) dao_create_email_provider(email_provider) return jsonify(email_provider.serialize()), 201
fetch_letter_line_items_for_all_services ) from app.dao.fact_notification_status_dao import ( fetch_notification_stats_for_trial_services, fetch_notification_status_totals_for_all_services, ) from app.dao.notifications_dao import send_method_stats_by_service from app.errors import register_errors, InvalidRequest from app.platform_stats.platform_stats_schema import platform_stats_request from app.service.statistics import format_admin_stats from app.schema_validation import validate from app.utils import get_local_timezone_midnight_in_utc platform_stats_blueprint = Blueprint('platform_stats', __name__) register_errors(platform_stats_blueprint) @platform_stats_blueprint.route('') def get_platform_stats(): if request.args: validate(request.args, platform_stats_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() data = fetch_notification_status_totals_for_all_services(start_date=start_date, end_date=end_date) stats = format_admin_stats(data)
from app.dao.templates_dao import dao_get_template_by_id from app.dao.notifications_dao import get_notifications_for_job from app.schemas import (job_schema, unarchived_template_schema, notifications_filter_schema, notification_with_template_schema) from app.celery.tasks import process_job from app.models import JOB_STATUS_SCHEDULED, JOB_STATUS_PENDING, JOB_STATUS_CANCELLED, LETTER_TYPE from app.utils import pagination_links from app.config import QueueNames from app.errors import (register_errors, InvalidRequest) job_blueprint = Blueprint('job', __name__, url_prefix='/service/<uuid:service_id>/job') register_errors(job_blueprint) @job_blueprint.route('/<job_id>', methods=['GET']) def get_job_by_service_and_job_id(service_id, job_id): job = dao_get_job_by_service_id_and_job_id(service_id, job_id) statistics = dao_get_notification_outcomes_for_job(service_id, job_id) data = job_schema.dump(job).data data['statistics'] = [{ 'status': statistic[1], 'count': statistic[0] } for statistic in statistics] return jsonify(data=data)
from flask_jwt_extended import jwt_required from app.dao.venues_dao import (dao_create_venue, dao_get_venues, dao_update_venue, dao_get_venue_by_id) from app.errors import register_errors from app.routes.venues.schemas import (post_create_venue_schema, post_create_venues_schema, post_import_venues_schema, post_update_venue_schema) from app.models import Venue from app.schema_validation import validate venues_blueprint = Blueprint('venues', __name__) venue_blueprint = Blueprint('venue', __name__) register_errors(venues_blueprint) register_errors(venue_blueprint) @venues_blueprint.route('/venues') @jwt_required def get_venues(): venues = [e.serialize() if e else None for e in dao_get_venues()] return jsonify(venues) @venue_blueprint.route('/venue/<uuid:venue_id>', methods=['GET']) def get_venue_by_id(venue_id): current_app.logger.info('get_venue: {}'.format(venue_id)) venue = dao_get_venue_by_id(venue_id) return jsonify(venue.serialize())
from sqlalchemy.exc import IntegrityError from flask import Blueprint, jsonify, request from app.dao.letter_branding_dao import ( dao_get_all_letter_branding, dao_create_letter_branding, dao_update_letter_branding, dao_get_letter_branding_by_id ) from app.errors import register_errors from app.letter_branding.letter_branding_schema import post_letter_branding_schema from app.models import LetterBranding from app.schema_validation import validate letter_branding_blueprint = Blueprint('letter_branding', __name__, url_prefix='/letter-branding') register_errors(letter_branding_blueprint) @letter_branding_blueprint.errorhandler(IntegrityError) def handle_integrity_error(exc): """ Handle integrity errors caused by the unique constraint """ for col in {'name', 'filename'}: if 'letter_branding_{}_key'.format(col) in str(exc): return jsonify( result='error', message={col: ["{} already in use".format(col.title())]} ), 400 current_app.logger.exception(exc) return jsonify(result='error', message="Internal server error"), 500
) from app.celery.tasks import process_job from app.models import JOB_STATUS_SCHEDULED, JOB_STATUS_PENDING, JOB_STATUS_CANCELLED from app.utils import pagination_links job = Blueprint('job', __name__, url_prefix='/service/<uuid:service_id>/job') from app.errors import ( register_errors, InvalidRequest ) register_errors(job) @job.route('/<job_id>', methods=['GET']) def get_job_by_service_and_job_id(service_id, job_id): job = dao_get_job_by_service_id_and_job_id(service_id, job_id) statistics = dao_get_notification_outcomes_for_job(service_id, job_id) data = job_schema.dump(job).data data['statistics'] = [{'status': statistic[1], 'count': statistic[0]} for statistic in statistics] return jsonify(data=data) @job.route('/<job_id>/cancel', methods=['POST']) def cancel_job(service_id, job_id):
from datetime import datetime from flask import Blueprint, jsonify, request from app.complaint.complaint_schema import complaint_count_request from app.dao.complaint_dao import ( fetch_count_of_complaints, fetch_paginated_complaints, ) from app.errors import register_errors from app.schema_validation import validate from app.utils import pagination_links complaint_blueprint = Blueprint('complaint', __name__, url_prefix='/complaint') register_errors(complaint_blueprint) @complaint_blueprint.route('', methods=['GET']) def get_all_complaints(): page = int(request.args.get('page', 1)) pagination = fetch_paginated_complaints(page=page) return jsonify(complaints=[x.serialize() for x in pagination.items], links=pagination_links(pagination, '.get_all_complaints', **request.args.to_dict())), 200 @complaint_blueprint.route('/count-by-date-range', methods=['GET']) def get_complaint_count(): if request.args:
user_schema_load_json, user_update_schema_load_json ) from app.celery.tasks import ( send_email ) from app.errors import ( register_errors, InvalidRequest ) from app.utils import url_with_token user = Blueprint('user', __name__) register_errors(user) @user.route('', methods=['POST']) def create_user(): user_to_create, errors = user_schema.load(request.get_json()) req_json = request.get_json() if not req_json.get('password', None): errors.update({'password': ['Missing data for required field.']}) raise InvalidRequest(errors, status_code=400) save_model_user(user_to_create, pwd=req_json.get('password')) return jsonify(data=user_schema.dump(user_to_create).data), 201 @user.route('/<uuid:user_id>', methods=['PUT']) def update_user(user_id):
from flask import Blueprint, jsonify from app.delivery import send_to_providers from app.models import EMAIL_TYPE from app.celery import provider_tasks from app.dao import notifications_dao from flask import current_app delivery_blueprint = Blueprint('delivery', __name__) from app.errors import register_errors register_errors(delivery_blueprint) @delivery_blueprint.route('/deliver/notification/<uuid:notification_id>', methods=['POST']) def send_notification_to_provider(notification_id): notification = notifications_dao.get_notification_by_id(notification_id) if not notification: return jsonify({"result": "error", "message": "No result found"}), 404 if notification.notification_type == EMAIL_TYPE: send_response( send_to_providers.send_email_to_provider, provider_tasks.deliver_email, notification, 'send-email') else: send_response( send_to_providers.send_sms_to_provider, provider_tasks.deliver_sms,