Generate Python background workers, cron jobs, message queue consumers. Use when creating scheduled tasks (APScheduler), Celery workers, RabbitMQ/Redis queue consumers, or async job processing...
Background processing patterns for FastAPI applications.
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
ā FastAPI Application ā
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā¤
ā API Request ā Cron Scheduler ā Queue Consumer ā
ā ā ā ā ā ā ā
ā Enqueue Job ā Trigger Task ā Process Message ā
ā ā ā ā ā ā ā
ā āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā ā
ā ā Service Layer ā ā
ā ā (Shared Business Logic) ā ā
ā āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā ā
ā ā ā ā ā
ā Message Queue Database External APIs ā
ā (RabbitMQ/Redis) (PostgreSQL) ā
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
| Component | Purpose | Location |
|---|---|---|
| Cron Jobs | Scheduled recurring tasks | app/jobs/ |
| Celery Tasks | Distributed task queue | app/tasks/ |
| Queue Consumers | Message processing | app/consumers/ |
| Workers | Background processors | app/workers/ |
| Use Case | Solution |
|---|---|
| Run every X minutes/hours | Cron (APScheduler) |
| Async processing after API call | Celery Task |
| Process messages from external system | Queue Consumer |
| Long-running background process | Worker with asyncio |
| Distributed across multiple servers | Celery + RabbitMQ |
| Simple in-process background | FastAPI BackgroundTasks |
Workers should call existing services, not duplicate logic:
# GOOD: Reuse service
async def process_order(order_id: int):
async with get_session() as session:
service = OrderService(session)
await service.process(order_id)
# BAD: Duplicate logic in worker
async def process_order(order_id: int):
# Don't copy-paste service code here!
pass
All background tasks must be idempotent (safe to retry):
# GOOD: Check before processing
async def send_email(user_id: int, email_type: str):
if await was_email_sent(user_id, email_type):
return # Already sent, skip
await do_send_email(user_id, email_type)
await mark_email_sent(user_id, email_type)
Always handle errors gracefully with retries:
@celery.task(bind=True, max_retries=3)
def process_payment(self, payment_id: int):
try:
# Process
pass
except TransientError as e:
raise self.retry(exc=e, countdown=60)
except PermanentError as e:
# Log and don't retry
logger.error(f"Payment {payment_id} failed permanently: {e}")
Scheduling:
Task Queues:
Message Queues:
This skill extends python-backend-development:
app/services/app/core/config.py