1
\$\begingroup\$

I am implementing a few Celery background tasks (e.g sending an email, subscribing someone to an Audience via Mailchimp API, etc.) and my project relies on a Flask application factory. Now, I am trying to understand if the way I've used application contexts makes sense at all or if it can be improved (I've quite a few resources lying around presenting very different approaches).
Here's my __init__.py

from flask import Flask
from .config import Config
form celery import Celery

# [...] A bunch of external components
celery = Celery(__name__)

def create_app():
    app = Flask(__name__)
    app.config.from_object(Config)

    celery.conf.update(app.config)

    # Instantiate external components
    # Blueprint registration

    return app

Now, the tasks that get executed in my blueprints are declared in the way presented below (in a ~/app/tasks.py file). As you can see, an application context gets created each time a task gets executed. This is the point where I am struggling: does it make sense to instantiate a Flask app each time a task needs to be executed or should I find a way to create a new 'global' app context?

from flask import current_app
from . import create_app, celery, mailchimp

@celery.task()
def newsletter_subscribe(user):
    """
    Subscribe a new user to a newsletter via Mailchimp API
    """
    app = create_app()  # Create a new Flask app instance

    with app.app_context():
        mailchimp.lists.members.create(
            list_id=current_app.config['MAILCHIMP_LISTS'][user["frequency"]],
            data={
                'email_address': user['email'],
                'status': 'subscribed'
            }
        )

# ... some more tasks following the same structure

Celery gets its worker thanks to the following command in my docker-compose file:

  celery:
    build:
      context: .
      dockerfile: 'Dockerfile.dev'
    command: celery worker -B -A app.tasks -l info
    env_file:
      - '.env'
    volumes: 
      - '.:/app'

Everything seems to work just fine but I am wondering if there's any pitfall in the way I am using app contexts or any margin for improvement.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.