Merge pull request #2610 from alphagov/get-pdf-contents-via-api

add api endpoint to get pdf for letter
This commit is contained in:
Leo Hemsted
2019-09-17 14:55:34 +01:00
committed by GitHub
9 changed files with 168 additions and 27 deletions

View File

@@ -57,6 +57,11 @@ class BadRequestError(InvalidRequest):
self.message = message if message else self.message
class PDFNotReadyError(BadRequestError):
def __init__(self):
super().__init__(message='PDF not available yet, try again later', status_code=400)
def register_errors(blueprint):
@blueprint.errorhandler(InvalidEmailError)
def invalid_format(error):

View File

@@ -1,9 +1,20 @@
from flask import jsonify, request, url_for, current_app
from io import BytesIO
from flask import jsonify, request, url_for, current_app, send_file
from app import api_user, authenticated_service
from app.dao import notifications_dao
from app.letters.utils import get_letter_pdf
from app.schema_validation import validate
from app.v2.errors import BadRequestError, PDFNotReadyError
from app.v2.notifications import v2_notification_blueprint
from app.v2.notifications.notification_schemas import get_notifications_request, notification_by_id
from app.models import (
NOTIFICATION_PENDING_VIRUS_CHECK,
NOTIFICATION_VIRUS_SCAN_FAILED,
NOTIFICATION_TECHNICAL_FAILURE,
LETTER_TYPE,
)
@v2_notification_blueprint.route("/<notification_id>", methods=['GET'])
@@ -13,10 +24,37 @@ def get_notification_by_id(notification_id):
notification = notifications_dao.get_notification_with_personalisation(
authenticated_service.id, notification_id, key_type=None
)
return jsonify(notification.serialize()), 200
@v2_notification_blueprint.route('/<notification_id>/pdf', methods=['GET'])
def get_pdf_for_notification(notification_id):
_data = {"notification_id": notification_id}
validate(_data, notification_by_id)
notification = notifications_dao.get_notification_by_id(
notification_id, authenticated_service.id, _raise=True
)
if notification.notification_type != LETTER_TYPE:
raise BadRequestError(message="Notification is not a letter")
if notification.status == NOTIFICATION_VIRUS_SCAN_FAILED:
raise BadRequestError(message='Document did not pass the virus scan')
if notification.status == NOTIFICATION_TECHNICAL_FAILURE:
raise BadRequestError(message='PDF not available for letters in status {}'.format(notification.status))
if notification.status == NOTIFICATION_PENDING_VIRUS_CHECK:
raise PDFNotReadyError()
try:
pdf_data = get_letter_pdf(notification)
except Exception:
raise PDFNotReadyError()
return send_file(filename_or_fp=BytesIO(pdf_data), mimetype='application/pdf')
@v2_notification_blueprint.route("", methods=['GET'])
def get_notifications():
_data = request.args.to_dict(flat=False)

View File

@@ -256,10 +256,11 @@ def process_letter_notification(*, letter_data, api_key, template, reply_to_text
template=template,
reply_to_text=reply_to_text)
should_send = not (api_key.key_type == KEY_TYPE_TEST)
test_key = api_key.key_type == KEY_TYPE_TEST
# if we don't want to actually send the letter, then start it off in SENDING so we don't pick it up
status = NOTIFICATION_CREATED if should_send else NOTIFICATION_SENDING
status = NOTIFICATION_CREATED if not test_key else NOTIFICATION_SENDING
queue = QueueNames.CREATE_LETTERS_PDF if not test_key else QueueNames.RESEARCH_MODE
notification = create_letter_notification(letter_data=letter_data,
template=template,
@@ -267,18 +268,19 @@ def process_letter_notification(*, letter_data, api_key, template, reply_to_text
status=status,
reply_to_text=reply_to_text)
if should_send:
create_letters_pdf.apply_async(
[str(notification.id)],
queue=QueueNames.CREATE_LETTERS_PDF
)
elif current_app.config['NOTIFY_ENVIRONMENT'] in ['preview', 'development']:
create_fake_letter_response_file.apply_async(
(notification.reference,),
queue=QueueNames.RESEARCH_MODE
)
else:
update_notification_status_by_reference(notification.reference, NOTIFICATION_DELIVERED)
create_letters_pdf.apply_async(
[str(notification.id)],
queue=queue
)
if test_key:
if current_app.config['NOTIFY_ENVIRONMENT'] in ['preview', 'development']:
create_fake_letter_response_file.apply_async(
(notification.reference,),
queue=queue
)
else:
update_notification_status_by_reference(notification.reference, NOTIFICATION_DELIVERED)
return notification