JavaRush /Курсы /Модуль 4: FastAPI /Асинхронная обработка данных: как это работает в FastAPI

Асинхронная обработка данных: как это работает в FastAPI

Модуль 4: FastAPI
2 уровень , 7 лекция
Открыта

Вспомним по аналогии. Представьте себе ресторан: вы заходите, делаете заказ, и официант тут же бежит на кухню, чтобы приготовить каждое блюдо сам. Неудобно, правда? Заказы других клиентов нужно ждать бесконечно долго. Асинхронное программирование — это как официант, который принимает заказ, передаёт его повару и занимается другими клиентами, пока кухня работает.

Асинхронность полезна, когда наш сервер не просто читает и пишет память, а зависает в ожидании (например, пока база данных выполняет запрос или другой API возвращает ответ). Вместо того, чтобы сидеть без дела, он может обрабатывать другие запросы. FastAPI — мастер в этой игре благодаря встроенной поддержке асинхронности.


Как FastAPI работает с асинхронностью?

FastAPI использует asyncio, встроенную библиотеку Python для работы с асинхронным программированием. Давайте разберём, почему это важно:

  • Асинхронные эндпоинты с помощью async def: FastAPI понимает, что ваш эндпоинт может быть "немного занят" (ждать ответа от базы данных, например). Используя async и await, FastAPI позволяет не блокировать выполнение других задач.
  • Event Loop (цикл событий): FastAPI "жонглирует" вашими задачами через event loop. Когда одна задача ждёт, другие задачи продолжают выполняться. Это супер-эффективно для API с высокой нагрузкой.
  • Поддержка асинхронных библиотек: FastAPI идеально совмещается с асинхронными клиентами, такими как httpx для работы с API или asyncpg для работы с PostgreSQL.

Пример асинхронной обработки данных

Вот небольшой пример, который представляет запрос данных с внешнего сервиса (например, с API OpenWeather):


from fastapi import FastAPI
import httpx

app = FastAPI()

@app.get("/weather/{city}")
async def get_weather(city: str):
    # Асинхронный запрос к внешнему API
    async with httpx.AsyncClient() as client:
        response = await client.get(f"https://api.openweathermap.org/data/2.5/weather?q={city}&appid=ваш_ключ")
    if response.status_code == 200:
        # Возвращаем ответ, если всё прошло хорошо
        return response.json()
    else:
        # Генерируем ошибку, если что-то пошло не так
        return {"error": "Could not fetch weather data"}
  1. Используем библиотеку httpx, которая поддерживает асинхронные HTTP-запросы.
  2. Ключевое слово async в функции get_weather говорит FastAPI, что это асинхронный эндпоинт.
  3. Ключевое слово await указывает, что выполнение приостанавливается до получения ответа от внешнего API.
  4. Благодаря асинхронности, пока мы ждём данные от OpenWeather, сервер может обрабатывать другие запросы. Красота!

Преимущества асинхронной обработки данных в FastAPI

  1. Высокая производительность: асинхронность позволяет обрабатывать тысячи запросов одновременно, не блокируя сервер.
  2. Снижение времени ожидания: пользователь видит ответ быстрее, так как ресурсы сервера используются оптимально.
  3. Полноценная поддержка ввода-вывода: асинхронность работает идеально с асинхронными базами данных и библиотеками.

Асинхронность с базой данных

Теперь давайте рассмотрим случай, когда данные необходимо запросить из базы данных.

Настройка асинхронной базы данных (SQLAlchemy + asyncpg)

Asyncpg — асинхронный драйвер для PostgreSQL. Вот пример настройки FastAPI для асинхронного взаимодействия с базой данных:


from fastapi import FastAPI
from sqlalchemy.ext.asyncio import AsyncSession, create_async_engine
from sqlalchemy.orm import sessionmaker
from pydantic import BaseModel

app = FastAPI()

# Создание асинхронного движка SQLAlchemy
DATABASE_URL = "postgresql+asyncpg://user:password@localhost/dbname"

engine = create_async_engine(DATABASE_URL)
SessionLocal = sessionmaker(bind=engine, class_=AsyncSession, expire_on_commit=False)

# Pydantic модель для валидации данных
class Item(BaseModel):
    name: str
    description: str

async def get_db():
    async with SessionLocal() as session:
        yield session

@app.post("/items/")
async def create_item(item: Item, db: AsyncSession = next(get_db())):
    # Пример асинхронного добавления записи в базу данных
    query = f"INSERT INTO items (name, description) VALUES ('{item.name}', '{item.description}')"
    await db.execute(query)
    await db.commit()
    return {"message": "Item created"}

Что здесь происходит?

  1. AsyncPg: мы используем асинхронный движок для работы с PostgreSQL.
  2. Pydantic: валидируем входные данные с помощью модели Item.
  3. Асинхронная работа с базой: запросы к базе данных выполняются через await, а сервер продолжает работать с другими задачами.

Асинхронное выполнение задач с asyncio

Иногда нужно запускать длительные, не зависящие от выполнения эндпоинтов задачи. Например, отправка уведомлений.


import asyncio

@app.get("/process/")
async def process_data():
    # Фоновая задача
    asyncio.create_task(background_task())
    return {"message": "Processing started!"}

async def background_task():
    print("Начинаем долгую обработку...")
    await asyncio.sleep(10)  # Симуляция длительной задачи
    print("Обработка завершена!")

Этот подход позволяет вам одновременно возвращать быстрый ответ клиенту и обрабатывать длительные операции "за кулисами".


Советы и типичные ошибки

  1. Смешивание синхронного и асинхронного кода: если вы используете асинхронные библиотеки, избегайте встроенных синхронных клиентов. Например, вместо requests лучше используйте httpx, а вместо стандартных драйверов для базы данных — асинхронные аналоги (asyncpg).
  2. Blocking Code: даже если используете async def, включение блокирующего кода (например, чтение больших файлов в памяти или синхронные операции) "замораживает" весь event loop.
  3. Пропущенный await: частая ошибка, особенно у новичков. Если забыть await, вместо выполнения задачи вернётся объект coroutine, который не даст результата.

Практическое применение

Асинхронная обработка данных часто используется в реальных проектах:

  • Микросервисы: быстрое взаимодействие между компонентами через API.
  • Интеграция с внешними сервисами: асинхронные запросы к сторонним API.
  • Обработка большого количества запросов: для высоконагруженных систем, таких как социальные платформы или финансовые инструменты, асинхронность — спасение.

Если вы попадёте на собеседование в компанию, работающую с высоконагруженными системами, знание асинхронного программирования и FastAPI будет огромным преимуществом.


FastAPI делает асинхронное программирование действительно удобным и доступным. Использование асинхронности в ваших проектах обеспечивает поддержку больших нагрузок, оптимизацию времени выполнения запросов и плавную интеграцию с другими современными технологиями.

1
Задача
Модуль 4: FastAPI, 2 уровень, 7 лекция
Недоступна
Простой асинхронный эндпоинт
Простой асинхронный эндпоинт
1
Задача
Модуль 4: FastAPI, 2 уровень, 7 лекция
Недоступна
Асинхронный запрос к внешнему API
Асинхронный запрос к внешнему API
Комментарии
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ