plugins/litestar/skills/litestar-lifecycle-hooks/SKILL.md
Apply Litestar request lifecycle hooks with `before_request`, `after_request`, and `after_response` for request enrichment, short-circuiting, response mutation, post-send side effects, and layered cross-cutting behavior around handler execution. Use when logic should run immediately before the handler, after the response object is resolved, or after the response has been sent. Do not use for startup/shutdown ownership, `before_send` / `after_exception` / `on_app_init`, decoupled event fanout, or raw ASGI wrapping that belongs in app setup, events, or middleware.
npx skillsauth add alti3/litestar-skills litestar-lifecycle-hooksInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Use this skill when the requirement is specifically about the request-handler lifecycle for HTTP handlers, not application bootstrapping or whole-ASGI wrapping.
before_request, after_request, or after_response (the exact lifecycle stage needed for behavior injection).before_request return values deliberate because any non-None response-compatible value bypasses the route handler.after_request focused on the resolved Response; it may return the same response or a replacement response.after_response side effects safe to run after the response is already sent; it cannot change the response the client received.before_request must pass data into the handler.before_request when you need request gating, request-state enrichment, or an early HTTP result before the handler runs.after_request when you need response-object mutation such as reshaping content, adding headers, or swapping the response type.after_response when you need metrics, counters, audit emission, or third-party notification after the response has already gone out.litestar-middleware instead when the concern needs raw ASGI scope/receive/send, broad wrapping across route groups, built-in middleware, or WebSocket/lifespan coverage.litestar-app-setup instead when the concern is before_send, after_exception, on_app_init, startup/shutdown hooks, or lifespan-managed resources.litestar-events instead when one action should fan out into decoupled in-process side effects rather than inline lifecycle interception.Read only the sections you need:
before_requestRequest as its first parameter.None or any value Litestar can use as a response.request.state.after_requestResponse.Response as its first parameter.Response.after_responseRequest as its first parameter.None.request.state when before_request needs to communicate with the handler.None from before_request unless you intentionally want to short-circuit the handler.after_request when that is sufficient; replace it only when the response contract truly changes.after_response idempotent enough for retries in tests and safe enough that delayed failures do not corrupt request flow assumptions.from litestar import Litestar, Request, Response, get
from litestar.status_codes import HTTP_403_FORBIDDEN
async def before_request(request: Request) -> Response | None:
tenant_id = request.headers.get("x-tenant-id")
if tenant_id is None:
return Response({"detail": "missing tenant"}, status_code=HTTP_403_FORBIDDEN)
request.state.tenant_id = tenant_id
return None
async def after_request(response: Response) -> Response:
response.headers["x-service"] = "orders"
return response
async def after_response(request: Request) -> None:
request.app.state.setdefault("paths_seen", []).append(request.url.path)
@get("/orders")
async def list_orders(request: Request) -> dict[str, str]:
return {"tenant_id": request.state.tenant_id}
app = Litestar(
route_handlers=[list_orders],
before_request=before_request,
after_request=after_request,
after_response=after_response,
)
before_request without treating them as real response contracts.after_request when the concern belongs in after_response, events, or a background mechanism.after_response mutations to show up in the current client response.before_request short-circuit cases bypass the handler as intended.before_request is available where it is later consumed.after_request always returns a valid Response.after_response side effects tolerate the fact that the response is already gone to the client.litestar-app-setup for startup/shutdown hooks, lifespan, before_send, after_exception, and on_app_init.litestar-middleware when the concern must wrap the ASGI pipeline rather than request and response objects.litestar-events for decoupled in-process side effects instead of inline hook fanout.litestar-testing to verify short-circuit behavior, layer precedence, and post-send side effects.development
Build Litestar WebSocket endpoints with low-level websocket handlers, websocket listeners, websocket streams, dependency injection, custom websocket classes, transport-mode control, and graceful connection lifecycle handling. Use when implementing bidirectional real-time communication, reactive websocket message handling, or proactive server push over WebSockets. Do not use for server-side pub/sub fanout that is better expressed with channels alone.
tools
Test Litestar applications with TestClient, AsyncTestClient, create_test_client, websocket test helpers, dependency overrides, mocked dependencies, lifecycle-aware fixtures, and deterministic success and failure assertions. Use when adding or fixing Litestar test coverage, including exception contracts, override precedence, websocket behavior, event-bus side effects, or live-server-only response patterns. Do not use as a substitute for production observability or runtime debugging strategy.
development
Configure Litestar templating with `TemplateConfig`, Jinja/Mako/MiniJinja engines, file-or-string `Template` responses, request and CSRF-aware context, template callables, and custom engine integration. Use when implementing or fixing server-rendered HTML in Litestar. Do not use for static asset serving or pure JSON API endpoints.
development
Configure Litestar stores and the store registry for caching, server-side sessions, rate limiting, and other key-value state with explicit backend selection, bytes-safe data handling, TTL and renewal policy, namespacing, registry wiring, and lifecycle cleanup. Use when a Litestar app depends on `MemoryStore`, `FileStore`, `RedisStore`, `ValkeyStore`, or `StoreRegistry`. Do not use for relational persistence, domain repositories, or response-caching policy details that belong in database or caching-focused skills.