Literal restricts a type to specific values.
1from typing import Literal23# Basic usage4Status = Literal["pending", "active", "deleted"]56def update_status(status: Status) -> None:7 print(f"Status: {status}")89update_status("active") # OK10update_status("deleted") # OK11# update_status("unknown") # Type error!1213# With FastAPI14from fastapi import FastAPI1516app = FastAPI()1718@app.get("/items/")19async def read_items(20 q: Literal["foo", "bar"] | None = None21):22 if q:23 return {"q": q}24 return {"q": None}2526# Combining with Union27Priority = Literal["low", "medium", "high"]2829class Task(BaseModel):30 title: str31 priority: Priority32 status: Literal["todo", "done"]3334task = Task(title="Work", priority="high", status="todo")3536# Enum alternative37from enum import Enum3839class StatusEnum(str, Enum):40 PENDING = "pending"41 ACTIVE = "active"42 DELETED = "deleted"4344def update_status(status: StatusEnum) -> None:45 print(status.value)
Literal vs Enum:
Literal: simpler, no class definition.Enum: more features (iteration, methods).