Quickstart¶
This guide walks through creating a runnable Litestar application that defines a background task, enqueues work from an HTTP route handler, and inspects task results.
Define a Task and Register the Plugin¶
Create app.py with the following code:
app.py
"""Minimal runnable Litestar Queues quickstart application."""
from uuid import UUID
from litestar import Litestar, get, post
from litestar.di import NamedDependency
from litestar.exceptions import NotFoundException
from litestar.params import FromPath, FromQuery
from litestar_queues import QueueConfig, QueuePlugin, QueueService, task
@task(queue="reports")
async def render_report(report_id: str, requested_by: str) -> dict[str, str]:
"""Render an analytics report in the background."""
return {"report_id": report_id, "requested_by": requested_by, "status": "ready"}
@post("/reports/{report_id:str}")
async def start_report(
report_id: FromPath[str],
queue_service: NamedDependency[QueueService],
requested_by: FromQuery[str] = "team@example.com",
) -> dict[str, str]:
"""Enqueue a background report job and return its tracking ID."""
handle = await queue_service.enqueue(render_report, report_id, requested_by=requested_by)
return {"task_id": str(handle.id), "status": handle.status or "pending"}
@get("/tasks/{task_id:uuid}")
async def get_report_status(task_id: FromPath[UUID], queue_service: NamedDependency[QueueService]) -> dict[str, object]:
"""Inspect the status and return value of a queued task."""
record = await queue_service.get_task(task_id)
if record is None:
raise NotFoundException(detail=f"Task {task_id} not found")
return {
"task_id": str(record.id),
"status": record.status,
"is_terminal": record.is_terminal,
"result": record.result,
}
app = Litestar(route_handlers=[start_report, get_report_status], plugins=[QueuePlugin(config=QueueConfig())])
What Happens Under the Hood¶
@task(queue="reports")wrapsrender_reportin aTaskbound to the"reports"queue and registers it in the task registry while preserving its direct async callability.QueueConfig()defaults toqueue_backend="ephemeral"(a zero-config, cross-process WAL SQLite database) andWorkerConfig(placement="server").QueuePluginregistersQueueServicefor dependency injection (queue_service: NamedDependency[QueueService]) and hooks into the Litestar CLI solitestar runautomatically supervises a dedicated worker subprocess.
Run the Application¶
Start the development server using the Litestar CLI:
When litestar run starts with WorkerConfig(placement="server"), ServerWorkerSupervisor spawns a child litestar queues run process that claims work across all queues.
Enqueue a Task and Inspect the Result¶
In another terminal, enqueue a report job via POST /reports/q4-revenue:
Query the task status and return value using the returned task_id:
{
"task_id": "2c8c9a14-6d3c-4f2b-9f1a-8e3e4d7a1b20",
"status": "completed",
"is_terminal": true,
"result": {
"report_id": "q4-revenue",
"requested_by": "analytics@example.com",
"status": "ready"
}
}
Next Steps¶
- Understand the Core Mental Model separating authoritative task storage from execution dispatch.
- Configure Tasks & Enqueuing and Task Options, Retries & Uniqueness.
- Move to production storage with SQLSpec, Advanced Alchemy, or Redis & Valkey.