From df0d0e65179fa6ae179d44212838a0c778d18fad Mon Sep 17 00:00:00 2001 From: Ole Tytlandsvik Date: Tue, 30 Jan 2024 21:12:20 +0100 Subject: [PATCH] :zap: Use background tasks for mail endpoints --- app/api/events.py | 26 +++++++------------------- app/utils/event_utils.py | 15 +++++++++++++++ tests/test_endpoints/test_event.py | 4 ++-- 3 files changed, 24 insertions(+), 21 deletions(-) diff --git a/app/api/events.py b/app/api/events.py index 5faeda3..c5fa745 100644 --- a/app/api/events.py +++ b/app/api/events.py @@ -1,12 +1,11 @@ from datetime import datetime, timedelta import os import shutil -from fastapi import APIRouter, Response, Request, HTTPException, Depends +from fastapi import APIRouter, Response, Request, HTTPException, Depends, BackgroundTasks from fastapi.datastructures import UploadFile from fastapi.param_functions import File from pydantic import ValidationError from starlette.responses import FileResponse -from starlette.background import BackgroundTasks from uuid import uuid4, UUID from app.utils.event_utils import * from app.utils.validation import validate_image_file_type, validate_uuid @@ -564,7 +563,7 @@ async def get_confirmation_message(request: Request, id: str, token: AccessToken @router.post('/{id}/mail', dependencies=[Depends(validate_uuid)]) -async def send_notification_mail(request: Request, id: str, m: EventMailMessage, token: AccessTokenPayload = Depends(authorize_admin)): +async def send_notification_mail(request: Request, id: str, m: EventMailMessage, background_tasks: BackgroundTasks, token: AccessTokenPayload = Depends(authorize_admin)): db = get_database(request) event = get_event_or_404(db, id) @@ -594,19 +593,13 @@ async def send_notification_mail(request: Request, id: str, m: EventMailMessage, mailingList = [p["_id"] for p in participantsToMail] if request.app.config.ENV == "production": - for addr in mailingList: - email = MailPayload( - to=[addr], - subject=[m.subject], - content=m.msg, - ) - send_mail(email) + background_tasks.add_task(send_emails, mailingList, m.subject, m.msg) - return Response(status_code=200) + return Response(status_code=202) @router.post('/{id}/confirm', dependencies=[Depends(validate_uuid)]) -async def confirmation(request: Request, id: str, m: EventConfirmMessage, token: AccessTokenPayload = Depends(authorize_admin)): +async def confirmation(request: Request, id: str, m: EventConfirmMessage, background_tasks: BackgroundTasks, token: AccessTokenPayload = Depends(authorize_admin)): async with lock: db = get_database(request) event = get_event_or_404(db, id) @@ -678,13 +671,8 @@ async def confirmation(request: Request, id: str, m: EventConfirmMessage, token: # Send email to all participants if request.app.config.ENV == 'production': - for mail in mailingList: - confirmation_email = MailPayload( - to=[mail], - subject=f"Bekreftelse {event['title']}", - content=content, - ) - send_mail(confirmation_email) + background_tasks.add_task( + send_emails, mailingList, f"Bekreftelse {event['title']}", content) return Response(status_code=200) diff --git a/app/utils/event_utils.py b/app/utils/event_utils.py index fa02fae..3dc45ed 100644 --- a/app/utils/event_utils.py +++ b/app/utils/event_utils.py @@ -2,6 +2,8 @@ from uuid import UUID from fastapi import HTTPException from datetime import datetime, timedelta +from ..api.mail import send_mail +from ..models import MailPayload def validate_registartion_opening_time(event_date, opening_date): @@ -136,3 +138,16 @@ def get_default_confirmation(event): content = content.replace("$LOCATION$", event['address']) return content + + +def send_emails(mailing_list, subject, content): + """ + Send emails to addresses in mailing list with given subject and content. + """ + for address in mailing_list: + email = MailPayload( + to=address, + subject=subject, + content=content + ) + send_mail(email) diff --git a/tests/test_endpoints/test_event.py b/tests/test_endpoints/test_event.py index de7f73e..41d67d9 100644 --- a/tests/test_endpoints/test_event.py +++ b/tests/test_endpoints/test_event.py @@ -657,12 +657,12 @@ def test_send_notification_mail(client): assert response.status_code == 200 response = client.post(f'/api/event/{eid}/mail', json=payload) - assert response.status_code == 200 + assert response.status_code == 202 # Test sending to all payload["confirmedOnly"] = False response = client.post(f'/api/event/{eid}/mail', json=payload) - assert response.status_code == 200 + assert response.status_code == 202 # Too long subject payload["subject"] = "a" * 51