Skip to main content

Flask-Celery-Tools

This is a fork of Flask-Celery-Helper

Even though the Flask documentation says Celery extensions are
unnecessary now, I found that I still need an extension to properly use Celery in large Flask applications. Specifically
I need an init_app() method to initialize Celery after I instantiate it.

This extension also comes with a single_instance method.

  • Python PyPy, 3.11, 3.12 and 3.13 supported.

Tests

Attribution

Single instance decorator inspired by Ryan Roemer.

Quickstart

Install:

pip install Flask-Celery-Tools  

Examples

Basic Example

# example.py  
from flask import Flask  
from flask_celery import Celery  

app = Flask('example')  
app.config['CELERY_BROKER_URL'] = 'redis://localhost'  
app.config['CELERY_RESULT_BACKEND'] = 'redis://localhost'  
app.config['CELERY_TASK_LOCK_BACKEND'] = 'redis://localhost'  
celery = Celery(app)  

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

if __name__ == '__main__':  
    result = add_together.delay(23, 42)  
    print(result.get())  

Run these two commands in separate terminals:

celery -A example.celery worker
python example.py

Factory Example

# extensions.py
from flask_celery import Celery

celery = Celery()
# application.py
from flask import Flask
from extensions import celery

def create_app() -> Flask:
    app = Flask(__name__)
    app.config['CELERY_IMPORTS'] = ('tasks.add_together', )
    app.config['CELERY_BROKER_URL'] = 'redis://localhost'
    app.config['CELERY_RESULT_BACKEND'] = 'redis://localhost'
    app.config['CELERY_TASK_LOCK_BACKEND'] = 'redis://localhost'
    celery.init_app(app)
    return app
# tasks.py
from extensions import celery

@celery.task()
def add_together(a: int, b: int) -> int:
    return a + b
# manage.py
from application import create_app

app = create_app()
app.run()

Custom Task Base Class

You can provide your own base task class to Celery() or init_app(). It must extend celery.Task and will be used as the base for the internal FlaskTask, so Flask context injection is preserved while your custom behaviour (retry logic, logging, etc.) is inherited by all tasks.

# example.py
from celery import Task
from flask import Flask
from flask_celery import Celery

class MyBaseTask(Task):
    abstract = True

    def on_failure(self, exc, task_id, args, kwargs, einfo):
        print(f"Task {task_id} failed: {exc}")

app = Flask('example')
app.config['CELERY_BROKER_URL'] = 'redis://localhost'
app.config['CELERY_RESULT_BACKEND'] = 'redis://localhost'
celery = Celery(app, task_cls=MyBaseTask)

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

The same parameter is available on init_app() for the factory pattern. A value passed to init_app() takes precedence over one passed to Celery().

celery = Celery(task_cls=FallbackTask)
celery.init_app(app, task_cls=MyBaseTask)  # MyBaseTask wins

Single Instance Example

# example.py
import time
from flask import Flask
from flask_celery import Celery, single_instance
from flask_redis import Redis

app = Flask('example')
app.config['REDIS_URL'] = 'redis://localhost'
app.config['CELERY_BROKER_URL'] = 'redis://localhost'
app.config['CELERY_RESULT_BACKEND'] = 'redis://localhost'
app.config['CELERY_TASK_LOCK_BACKEND'] = 'redis://localhost'
celery = Celery(app)
Redis(app)

@celery.task(bind=True)
@single_instance
def sleep_one_second(a: int, b: int) -> int:
    time.sleep(1)
    return a + b

if __name__ == '__main__':
    task1 = sleep_one_second.delay(23, 42)
    time.sleep(0.1)
    task2 = sleep_one_second.delay(20, 40)
    results1 = task1.get(propagate=False)
    results2 = task2.get(propagate=False)
    print(results1)  # 65
    if isinstance(results2, Exception) and str(results2) == 'Failed to acquire lock.':
        print('Another instance is already running.')
    else:
        print(results2)  # Should not happen.

Locking backends

Flask-Celery-Tools supports multiple locking backends you can use:

Filesystem

Filesystem locking backend is using file locks on filesystem where worker is running, WARNING this backend is not usable for distributed tasks!!!

Redis

Redis backend is using redis for storing task locks, this backend is good for distributed tasks.

Database (MariaDB, PostgreSQL, etc)

Database backend is using database supported by SqlAlchemy to store task locks, this backend is good for distributed tasks. Except sqlite database that have same limitations as filesystem backend.

Release files for Flask-Celery-Tools 1.7.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for Flask-Celery-Tools 1.7.0
File Size Uploaded
flask_celery_tools-1.7.0.tar.gz 14.9 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for Flask-Celery-Tools 1.7.0
File Interpreter ABI Platform
flask_celery_tools-1.7.0-py3-none-any.whl Python 3 none any Details

Total release size:29.4 kB

Release files / flask_celery_tools-1.7.0.tar.gz

Download URL flask_celery_tools-1.7.0.tar.gz
Size 14.9 kB
Tags Source
SHA-256 checksum
How to use checksums
65f7b5026b85fd3d0ca1167c6f023bc721930d7724420e4e99d6e7f20db0a327
BLAKE2b-256 checksum
How to use checksums
9912127c8705f3eb25ab907f753c458cfb107ef18e7ecb2bd3732383479975a9
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.13.5

Release files / flask_celery_tools-1.7.0-py3-none-any.whl

Download URL flask_celery_tools-1.7.0-py3-none-any.whl
Size 14.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
70c5b531f2a4db624dec81b0a396ce194bd6ba62ff4c94c5a14071f4f89f7413
BLAKE2b-256 checksum
How to use checksums
1f8f353f8e5d975d16ae23f7c6cd286e379e25577fae70553fb5c5b803bc5b50
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.13.5

Release history Release notifications | RSS feed

This release

1.7.0 This release

2 release files

1.6.2

2 release files

1.5.3

2 release files

1.4.3

1 release file

1.4.1

1 release file

1.4.0

1 release file

1.3.1

1 release file

1.2.9

1 release file

1.2.8

1 release file

1.2.7

1 release file

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page