PythonMiddleTechnical
Что такое ASGI?
ASGI (Asynchronous Server Gateway Interface) — стандартный async-интерфейс между web-сервером и Python-приложением. Приложение — это async callable (scope, receive, send), который обрабатывает HTTP, WebSocket, lifespan и другие протоколы через event-based модель.
Определение
ASGI — Asynchronous Server Gateway Interface, спецификация (asgi.readthedocs.io) интерфейса между async-совместимым web-сервером и Python-приложением. Это преемник WSGI, разработанный командой Django Channels и поддерживаемый Starlette, FastAPI, Django (с 3.0), Quart, Sanic, BlackSheep и другими.
Контракт приложения
ASGI-приложение — это async callable с тремя аргументами:
async def app(scope, receive, send):
...
scope: dict— метаданные соединения:type("http","websocket","lifespan"),method,path,headers,client,serverи т. д.receive: Callable[[], Awaitable[dict]]— корутина, возвращающая входящие события (request body chunks, WebSocket-сообщения, disconnect).send: Callable[[dict], Awaitable[None]]— корутина для отправки событий ответа (start, body, websocket.accept и т. д.).
Минимальное HTTP-приложение
async def app(scope, receive, send):
assert scope["type"] == "http"
# Прочитать тело
body = b""
more = True
while more:
msg = await receive()
body += msg.get("body", b"")
more = msg.get("more_body", False)
# Отправить ответ
await send({
"type": "http.response.start",
"status": 200,
"headers": [(b"content-type", b"text/plain; charset=utf-8")],
})
await send({
"type": "http.response.body",
"body": b"Hello from ASGI",
})
Запуск: uvicorn module:app --host 0.0.0.0 --port 8000.
Поддерживаемые протоколы
http— обычные запросы, с поддержкой streaming request/response через несколькоhttp.response.body-событий.websocket— событияwebsocket.connect,websocket.receive,websocket.send,websocket.disconnect.lifespan— startup/shutdown сообщения от сервера приложению (там удобно открывать DB-пул, прогревать кэш).
Серверы и фреймворки
- Серверы (реализуют протокол): Uvicorn (на uvloop+httptools), Hypercorn (поддерживает HTTP/2 и HTTP/3), Daphne (от Django Channels), Granian.
- Фреймворки (пишут логику поверх ASGI): Starlette, FastAPI, Django, Quart, Litestar.
- Middleware: оборачивает ASGI app в другой ASGI app — например,
CORSMiddleware,GZipMiddleware,SessionMiddleware.
Подводные камни
- ASGI не делает blocking-код автоматически быстрым:
requests,psycopg2,time.sleepвнутриasync defблокируют event loop и убивают параллелизм. Используйтеhttpx.AsyncClient,asyncpg/psycopg[async],asyncio.sleepили выносите blocking-вызовы вasyncio.to_thread/run_in_executor. - Путать ASGI-сервер (Uvicorn) и фреймворк (FastAPI). Uvicorn умеет запускать любое ASGI-приложение, не только FastAPI.
- Забывать про
lifespan: ресурсы, открытые на module-level, не закроются корректно при graceful shutdown. - Использовать sync WSGI-middleware в ASGI-стеке — нужен ASGI-нативный middleware или адаптер
WSGIMiddleware. - Не настраивать
--workers/--loop uvloopв проде — один процесс не использует все ядра.
Common mistakes
- Описывать ASGI как WSGI с async def только по названию.
- Не знать scope/receive/send.
- Не упоминать WebSocket.
What the interviewer is testing
- Называет ASGI callable contract.
- Понимает HTTP/WebSocket support.
- Знает uvicorn/hypercorn роль.