Task Asincroni con Celery
Celery e una coda di task distribuita per Python che si integra perfettamente con Django. Permette di eseguire operazioni lunghe o pesanti in background, come lâinvio di email, lâelaborazione di immagini o la generazione di report, senza bloccare la risposta HTTP.
Cosâe Celery
Celery funziona con un modello produttore-consumatore: la tua applicazione Django (produttore) invia i task a un broker di messaggi (come Redis o RabbitMQ), e uno o piu worker Celery (consumatori) li eseguono in background. Questo approccio mantiene lâapplicazione reattiva anche durante operazioni costose.
Installazione
Installa Celery e le dipendenze necessarie:
pip install celery redis django-celery-results
Configurazione del Progetto
Crea il file celery.py nella cartella principale del progetto, accanto a settings.py:
# mio_progetto/celery.py
import os
from celery import Celery
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mio_progetto.settings")
app = Celery("mio_progetto")
app.config_from_object("django.conf:settings", namespace="CELERY")
app.autodiscover_tasks()
Aggiorna il file __init__.py del progetto:
# mio_progetto/__init__.py
from .celery import app as celery_app
__all__ = ("celery_app",)
Aggiungi le configurazioni in settings.py:
# settings.py
INSTALLED_APPS = [
# ...
"django_celery_results",
]
CELERY_BROKER_URL = "redis://localhost:6379/0"
CELERY_RESULT_BACKEND = "django-db"
CELERY_ACCEPT_CONTENT = ["json"]
CELERY_TASK_SERIALIZER = "json"
CELERY_RESULT_SERIALIZER = "json"
CELERY_TIMEZONE = "Europe/Rome"
Esegui la migrazione per il backend dei risultati:
python manage.py migrate django_celery_results
Creare Task con @shared_task
Definisci i task nel file tasks.py della tua app:
# myapp/tasks.py
from celery import shared_task
from django.core.mail import send_mail
from time import sleep
@shared_task
def invia_email_benvenuto(email_utente, nome):
"""Invia un'email di benvenuto in background."""
send_mail(
subject="Benvenuto!",
message=f"Ciao {nome}, benvenuto nella nostra piattaforma!",
from_email="noreply@miosito.com",
recipient_list=[email_utente],
)
return f"Email inviata a {email_utente}"
@shared_task
def genera_report(report_id):
"""Genera un report pesante in background."""
sleep(30) # Simulazione di operazione lunga
return f"Report {report_id} generato con successo"
Chiamare i Task
Esistono diversi modi per richiamare un task:
from myapp.tasks import invia_email_benvenuto, genera_report
# .delay() - modo rapido
invia_email_benvenuto.delay("utente@example.com", "Marco")
# .apply_async() - modo avanzato con opzioni
invia_email_benvenuto.apply_async(
args=["utente@example.com", "Marco"],
countdown=60, # Esegui tra 60 secondi
)
genera_report.apply_async(
args=[42],
eta=datetime(2026, 2, 7, 8, 0, 0), # Esegui a un orario specifico
queue="reports", # Invia a una coda specifica
)
Verificare lo Stato di un Task
risultato = genera_report.delay(42)
print(risultato.id) # ID del task
print(risultato.status) # PENDING, STARTED, SUCCESS, FAILURE
print(risultato.ready()) # True se completato
print(risultato.result) # Il valore restituito dal task
Task Periodici con Celery Beat
Per eseguire task a intervalli regolari, configura Celery Beat:
# settings.py
from celery.schedules import crontab
CELERY_BEAT_SCHEDULE = {
"pulizia-giornaliera": {
"task": "myapp.tasks.pulisci_dati_vecchi",
"schedule": crontab(hour=3, minute=0), # Ogni giorno alle 3:00
},
"report-settimanale": {
"task": "myapp.tasks.genera_report_settimanale",
"schedule": crontab(hour=9, minute=0, day_of_week=1), # Lunedi alle 9:00
},
}
Avvia il beat scheduler:
celery -A mio_progetto beat --loglevel=info
Avviare i Worker
Per avviare Celery in modalita worker:
celery -A mio_progetto worker --loglevel=info
Monitoraggio con Flower
Flower e unâinterfaccia web per monitorare i task Celery in tempo reale:
pip install flower
celery -A mio_progetto flower --port=5555
Accedi a http://localhost:5555 per visualizzare lo stato dei worker, i task in esecuzione, la cronologia e le statistiche.
Conclusione
Celery e lo strumento ideale per gestire operazioni asincrone in Django. Dalla configurazione iniziale con Redis come broker, alla definizione dei task con @shared_task, fino ai task periodici con Celery Beat, hai a disposizione un sistema completo per migliorare le prestazioni e la reattivita della tua applicazione.