The post has been translated automatically. Original language: Russian
WSGI and ASGI: How HTTP turns into a Python application.
When developers start working with modern APIs, there is often a misconception that using `async def` automatically makes the application fast.
In practice, API speed depends not only on asynchrony, but on many factors: database operation, external services, CPU load, number of processes, and proper organization of expectations.
WSGI and ASGI do not solve the problem of acceleration directly, but rather define the rules of interaction between the HTTP server and the Python application.
Any HTTP request does not start with Python objects, but with a sequence of bytes that arrive over the network.
First, the server analyzes the HTTP method, address, headers, and request body, and then transmits the data to the application.
For example, JSON first exists as text, then it is encoded in UTF-8 and only after that it turns into a set of bytes for transmission over the network.
WSGI is a classic interface for the interaction of a web server with a Python application based on a synchronous request processing model.
In this model, the server calls the application function, passes the request data to it, and waits for execution to complete.
If an application is waiting for a database, file system, or external API during processing, the workflow remains busy until a response is received.
WSGI is well suited for common applications with short queries and a clear load model.
However, this architecture is less convenient for a large number of long-term connections, such as WebSocket or data streaming.
ASGI emerged as a modern alternative focused on the event model and asynchronous processing.
Instead of simply calling a function, the application receives events from the server and interacts independently through the `receive` and `send` mechanisms.
This makes efficient use of the waiting time when the application performs non-blocking I/O operations.
The main element of ASGI is the event loop, which switches between tasks when one of them is waiting for an operation to complete.
For example, while one query is waiting for a response from the database, other queries can continue to be executed.
But if you use blocking code inside `async def`, such as `time.sleep()` or a synchronous HTTP client, the advantage of asynchrony disappears.
In combination with FastAPI and Uvicorn, the processing process looks like this: Uvicorn accepts an HTTP connection, generates ASGI events, transmits them to FastAPI, and after executing the business logic returns the result to the client.
FastAPI receives the request data, checks its structure through Pydantic, executes a handler, and generates a Python response object.
After that, the object is serialized in JSON, encoded in UTF-8, and converted back to HTTP bytes.
It is important to understand the difference between serialization and encoding: serialization turns a Python structure into a JSON format, while encoding turns a JSON text into a sequence of bytes to be transmitted.
Errors often occur when these processes mix or double-serialize data.
The choice between WSGI and ASGI depends on the nature of the application and the load requirements.
WSGI remains a reliable solution for classic synchronous services, while ASGI is better suited for modern high-load APIs, WebSocket, and applications with a large number of simultaneous connections.
At the same time, neither WSGI nor ASGI by themselves make the system fast — performance is determined by proper work with I/O, CPU, databases and application architecture.
The main task of these interfaces is to ensure correct and efficient exchange between the HTTP world and Python code.
WSGI и ASGI: как HTTP превращается в работу Python-приложения
Когда разработчики начинают работать с современными API, часто возникает ошибочное мнение, что использование `async def` автоматически делает приложение быстрым.
На практике скорость API зависит не только от асинхронности, а от множества факторов: работы базы данных, внешних сервисов, нагрузки на CPU, количества процессов и правильной организации ожиданий.
WSGI и ASGI решают не задачу ускорения напрямую, а определяют правила взаимодействия между HTTP-сервером и Python-приложением.
Любой HTTP-запрос начинается не с Python-объектов, а с последовательности байтов, которые приходят по сети.
Сначала сервер анализирует HTTP-метод, адрес, заголовки и тело запроса, а затем передаёт данные приложению.
Например, JSON сначала существует как текст, затем кодируется в UTF-8 и только после этого превращается в набор байтов для передачи по сети.
WSGI — это классический интерфейс взаимодействия веб-сервера с Python-приложением, построенный на синхронной модели обработки запросов.
В этой модели сервер вызывает функцию приложения, передаёт ей данные запроса и ожидает завершения выполнения.
Если приложение во время обработки ждёт базу данных, файловую систему или внешний API, рабочий процесс остаётся занятым до получения ответа.
WSGI хорошо подходит для обычных приложений с короткими запросами и понятной моделью нагрузки.
Однако такая архитектура менее удобна для большого количества длительных соединений, например WebSocket или потоковой передачи данных.
ASGI появился как современная альтернатива, ориентированная на событийную модель и асинхронную обработку.
Вместо простого вызова функции приложение получает события от сервера и самостоятельно взаимодействует через механизмы `receive` и `send`.
Это позволяет эффективно использовать время ожидания, когда приложение выполняет неблокирующие операции ввода-вывода.
Главный элемент ASGI — это event loop, который переключается между задачами, когда одна из них ожидает завершения операции.
Например, пока один запрос ждёт ответ от базы данных, другие запросы могут продолжать выполняться.
Но если внутри `async def` использовать блокирующий код, например `time.sleep()` или синхронный HTTP-клиент, преимущество асинхронности исчезает.
В связке FastAPI и Uvicorn процесс обработки выглядит следующим образом: Uvicorn принимает HTTP-соединение, формирует ASGI-события, передаёт их FastAPI, а после выполнения бизнес-логики возвращает результат клиенту.
FastAPI получает данные запроса, проверяет их структуру через Pydantic, выполняет обработчик и формирует Python-объект ответа.
После этого объект сериализуется в JSON, кодируется в UTF-8 и превращается обратно в HTTP-байты.
Важно понимать разницу между сериализацией и кодированием: сериализация превращает Python-структуру в формат JSON, а кодирование превращает текст JSON в последовательность байтов для передачи.
Ошибки часто возникают, когда эти процессы смешивают или выполняют двойную сериализацию данных.
Выбор между WSGI и ASGI зависит от характера приложения и требований к нагрузке.
WSGI остаётся надёжным решением для классических синхронных сервисов, а ASGI лучше подходит для современных высоконагруженных API, WebSocket и приложений с большим количеством одновременных соединений.
При этом ни WSGI, ни ASGI сами по себе не делают систему быстрой — производительность определяется правильной работой с I/O, CPU, базами данных и архитектурой приложения.
Главная задача этих интерфейсов — обеспечить корректный и эффективный обмен между миром HTTP и Python-кодом.