00
:
00
:
00
:
00
•Corso SEO AI - Usa SEOEMAIL al checkout per il 30% di sconto

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.