Skip to content

Commit

Permalink
(BSR)[API] feat: use celery for sending mails
Browse files Browse the repository at this point in the history
  • Loading branch information
lgerard-pass committed Jan 16, 2025
1 parent bd3ac3c commit c4144f0
Show file tree
Hide file tree
Showing 11 changed files with 236 additions and 6 deletions.
168 changes: 166 additions & 2 deletions api/poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion api/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,8 @@ dependencies = [
"wtforms-sqlalchemy==0.4.2",
"wtforms==3.2.1",
"xlsxwriter>=3.2.0",
"zeep==4.3.1"
"zeep==4.3.1",
"celery[redis] (>=5.4.0,<6.0.0)"
]

[tool.poetry.group.dev]
Expand Down
Empty file.
15 changes: 15 additions & 0 deletions api/src/pcapi/asynchronous_tasks/celery.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
from celery import Celery, Task
from flask import Flask

def celery_init_app(app: Flask) -> Celery:
class FlaskTask(Task):
def __call__(self, *args: object, **kwargs: object) -> object:
with app.app_context():
return self.run(*args, **kwargs)

celery_app = Celery(app.name, task_cls=FlaskTask)
celery_app.config_from_object(app.config["CELERY"])
celery_app.set_default()
app.extensions["celery"] = celery_app
return celery_app

4 changes: 4 additions & 0 deletions api/src/pcapi/asynchronous_tasks/celery_worker.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
from pcapi.flask_app import app as flask_app


celery_app = flask_app.extensions["celery"]
21 changes: 21 additions & 0 deletions api/src/pcapi/asynchronous_tasks/sendinblue.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
from celery import shared_task

from pcapi.core.external import sendinblue
from pcapi.core.mails.transactional.send_transactional_email import send_transactional_email
from pcapi.tasks.serialization.sendinblue_tasks import SendTransactionalEmailRequest
from pcapi.tasks.serialization.sendinblue_tasks import UpdateSendinblueContactRequest


@shared_task(name="mails.tasks.update_contact_attributes", acks_late=True)
def update_contact_attributes_task(payload: UpdateSendinblueContactRequest) -> None:
sendinblue.make_update_request(payload)


@shared_task(name="mails.tasks.send_transactional_email_primary", acks_late=True)
def send_transactional_email_primary_task(payload: SendTransactionalEmailRequest) -> None:
send_transactional_email(payload)


@shared_task(name="mails.tasks.send_transactional_email_secondary", acks_late=True)
def send_transactional_email_secondary_task(payload: SendTransactionalEmailRequest) -> None:
send_transactional_email(payload)
2 changes: 1 addition & 1 deletion api/src/pcapi/core/external/sendinblue.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,12 @@
from sib_api_v3_sdk.rest import ApiException as SendinblueApiException

from pcapi import settings
from pcapi.asynchronous_tasks.sendinblue import update_contact_attributes_task
from pcapi.core import mails as mails_api
from pcapi.core.cultural_survey import models as cultural_survey_models
from pcapi.core.external.attributes import models as attributes_models
import pcapi.core.users.models as users_models
from pcapi.models.feature import FeatureToggle
from pcapi.tasks.sendinblue_tasks import update_contact_attributes_task
from pcapi.tasks.serialization.sendinblue_tasks import UpdateSendinblueContactRequest


Expand Down
4 changes: 2 additions & 2 deletions api/src/pcapi/core/mails/backends/sendinblue.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@
from sib_api_v3_sdk.rest import ApiException as SendinblueApiException

from pcapi import settings
from pcapi.asynchronous_tasks.sendinblue import send_transactional_email_primary_task
from pcapi.asynchronous_tasks.sendinblue import send_transactional_email_secondary_task
from pcapi.core.users.repository import find_user_by_email
from pcapi.models.feature import FeatureToggle
from pcapi.tasks.sendinblue_tasks import send_transactional_email_primary_task
from pcapi.tasks.sendinblue_tasks import send_transactional_email_secondary_task
import pcapi.tasks.serialization.sendinblue_tasks as serializers
from pcapi.utils import email as email_utils
from pcapi.utils.email import is_email_whitelisted
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ def send_transactional_email(payload: SendTransactionalEmailRequest) -> None:

try:
configuration = sib_api_v3_sdk.Configuration()
if settings.PROXY_CERT_BUNDLE is not None:
configuration.ssl_ca_cert = settings.PROXY_CERT_BUNDLE
if payload.use_pro_subaccount:
configuration.api_key["api-key"] = settings.SENDINBLUE_PRO_API_KEY
else:
Expand Down
20 changes: 20 additions & 0 deletions api/src/pcapi/flask_app.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
from werkzeug.middleware.proxy_fix import ProxyFix

from pcapi import settings
from pcapi.asynchronous_tasks.celery import celery_init_app
from pcapi.core import monkeypatches
from pcapi.core.finance import utils as finance_utils
from pcapi.core.logging import get_or_set_correlation_id
Expand Down Expand Up @@ -167,6 +168,25 @@ def add_security_headers(response: flask.wrappers.Response) -> flask.wrappers.Re
install_commands(app)
finance_utils.install_template_filters(app)

app.config.from_mapping(
CELERY=dict(
broker_url=settings.REDIS_URL,
task_acks_late=True,
task_reject_on_worker_lost=True,
# Pickle seems the best pick since we don't support
# anything other than python https://docs.celeryq.dev/en/latest/userguide/calling.html#serializers
task_serializer="pickle",
result_serializer="pickle",
accept_content=["pickle"],
task_routes={
"mails.tasks.*": {"queue": "mails"},
},
task_ignore_result=True,
),
)

celery_init_app(app)


backoffice_oauth = OAuth(app)
backoffice_oauth.register(
Expand Down
3 changes: 3 additions & 0 deletions api/src/pcapi/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -652,3 +652,6 @@

# HARVESTR
HARVESTR_API_KEY = secrets_utils.get("HARVESTR_API_KEY", "")

# PROXY configuration
PROXY_CERT_BUNDLE = os.environ.get("PROXY_CERT_BUNDLE", None)

0 comments on commit c4144f0

Please sign in to comment.