Setting up large Flask application using factory pattern is very convinient, because it prevents a code being run at import time and provides more flexible way to setup application.
Celery is a good and must have tool for running asynchonious tasks, but it’s a little bit tricky to configure it in a large application.
Imagine a following project layout
So if controllers will import tasks.py there’s a circular import.
- Import tasks inside a view function. Violates PEP8
- Import tasks using importlib.
- Change celery_factory and don’t import tasks and run them by name
Personally, I prefer a last solution, because it gives more flexibility for structuring codebase of the tasks.
Change celery factory
To make celery factory more reusable let’s remove dependency of application factory and make application parameter mandatory:
And in controllers:
And file with celery worker:
Calling celery tasks by name looks clearer and less magical, so I
Working proof of concept available on github