2

I would like to define some celery tasks. This is my tasks.py module:

from celery import Celery


def create_celery_app(app):
    celery = Celery(__name__, broker=app.config['CELERY_BROKER_URL'])
    celery.conf.update(app.config)
    TaskBase = celery.Task

    class ContextTask(TaskBase):
        abstract = True

        def __call__(self, *args, **kwargs):
            with app.app_context():
                return TaskBase.__call__(self, *args, **kwargs)

    celery.Task = ContextTask
    return celery


celery = create_celery_app(app)  # <--- How to access app here?

@celery.task()
def add_together(a, b):
    return a + b

The problem is, I have no access to the app here! My app is defined in my wsgi.py module (I am serving with gunicorn)

from myproj.app import create_app

app = create_app()

With app.py being:

...

def create_app():
    """
    app = Flask(__name__)
    ...
    return app

How can I access the app singleton instance, created in the wsgi.py module, from my tasks.py?

blueFast
  • 41,341
  • 63
  • 198
  • 344
  • `from wgsi import app` ... `celery = create_celery_app(app)` – Kyle Pittman Sep 28 '15 at 18:05
  • @KylePittman: does not work, creates circular import – blueFast Sep 28 '15 at 18:24
  • Why not just call `create_app`? – dirn Sep 28 '15 at 19:26
  • @dirn: app is already created by the wsgi middleware, and besides, importing create_app causes a circular import – blueFast Sep 28 '15 at 19:53
  • You should be able to refactor your application to avoid a circular import. – Kyle Pittman Sep 28 '15 at 23:16
  • What about `from flask import current_app as app` – goodcow Sep 29 '15 at 00:30
  • @goodcow: no current_app during declaration time ... – blueFast Sep 29 '15 at 07:52
  • @Monkey: don't know how to achieve that. There seems to be a real circular dependency: the flask views (part of the flask application) need celery tasks, and the celery worker (running the tasks, in a separate process), need the flask application. I have seen simple implementations where the Flask application and the celery tasks are defined in the same module (`app.py`), so both the flask application and the celery worker can be run from the same file (no need to import anything), but in my case wsgi.py defines the application, so I need to import it, causing circular dependency. – blueFast Sep 29 '15 at 07:57
  • But even in those simple cases, I do not know how the dependency flask <-> celery worker is solved at the process level. I would say the celery worker instantiates a new flask application, different than the one used to serve the requests, and uses that to access the flask objects. That to me seems very brittle, since it is difficult to guarantee that the "fake" flask application instance used by the worker follows the exact same configuration path than the real flask application serving the requests. – blueFast Sep 29 '15 at 08:00
  • Possible duplicate of [How can I use an app-factory in Flask / WSGI servers and why might it be unsafe?](http://stackoverflow.com/questions/13751277/how-can-i-use-an-app-factory-in-flask-wsgi-servers-and-why-might-it-be-unsafe) – Paul Sweatte Aug 31 '16 at 22:27

0 Answers0