Интеграции

AI-эндпоинт на FastAPI через AI Gateway: async и стриминг

Как добавить AI-эндпоинт в FastAPI: асинхронный клиент OpenAI SDK с base_url AI Gateway, обычный ответ и стриминг через StreamingResponse, ключ в переменных окружения.

2 минуты чтения

Соберём в FastAPI пару эндпоинтов, которые обращаются к моделям из каталога AI Gateway: один отдаёт готовый ответ, другой стримит его по мере генерации. FastAPI асинхронный, поэтому берём AsyncOpenAI — он совместим с шлюзом на уровне base_url и не блокирует event loop.

Подготовка

Нужен ключ sk-aigate-… из кабинета и базовый URL https://ai-gatewey.ru/v1. Ключ держим в переменной окружения, а не в коде.

pip install fastapi uvicorn openai

Реализация

  1. Настройте асинхронный клиент

    Один экземпляр AsyncOpenAI на всё приложение — создаём при старте и переиспользуем во всех обработчиках:

    import os
    from openai import AsyncOpenAI
    
    client = AsyncOpenAI(
        base_url="https://ai-gatewey.ru/v1",
        api_key=os.environ["AIGATE_API_KEY"],
    )
  2. Эндпоинт с обычным ответом

    Принимаем текст в теле запроса, отдаём ответ модели одним JSON:

    from fastapi import FastAPI
    from pydantic import BaseModel
    
    app = FastAPI()
    
    class Prompt(BaseModel):
        message: str
    
    @app.post("/chat")
    async def chat(body: Prompt):
        resp = await client.chat.completions.create(
            model="deepseek/deepseek-chat",
            messages=[{"role": "user", "content": body.message}],
        )
        return {"reply": resp.choices[0].message.content}
  3. Стриминг через StreamingResponse

    Для «печатающегося» ответа включаем stream=True и отдаём чанки генератором в StreamingResponse:

    from fastapi.responses import StreamingResponse
    
    @app.post("/chat/stream")
    async def chat_stream(body: Prompt):
        async def gen():
            stream = await client.chat.completions.create(
                model="deepseek/deepseek-chat",
                messages=[{"role": "user", "content": body.message}],
                stream=True,
            )
            async for chunk in stream:
                delta = chunk.choices[0].delta.content
                if delta:
                    yield delta
        return StreamingResponse(gen(), media_type="text/plain")
  4. Запустите сервер

    Поднимаем uvicorn и проверяем эндпоинты; расход по токенам виден в кабинете AI Gateway в реальном времени:

    uvicorn main:app --reload
Ключ AI Gateway живёт только на сервере — в переменной окружения (AIGATE_API_KEY), в секретах контейнера или менеджере секретов. Никогда не передавайте его на фронтенд: клиент должен ходить в ваш FastAPI, а тот уже в шлюз.

Какие модели подойдут

Для бэкенд-эндпоинтов под нагрузкой обычно берут быструю недорогую модель, а флагман подключают точечно там, где нужен максимум качества:

МодельВвод, ₽/1МВывод, ₽/1МКонтекст
DeepSeek: DeepSeek V331125128K
OpenAI: GPT-5.4 Mini118705400K
Anthropic Claude Haiku Latest157784200K
Актуальные цены каталога AI Gateway за 1 млн токенов. Все модели →

Частые вопросы

Почему AsyncOpenAI, а не обычный OpenAI?

Обработчики FastAPI выполняются в общем event loop. Синхронный клиент блокировал бы его на время запроса к модели и снижал пропускную способность; AsyncOpenAI с await этого избегает.

Как отдать стрим на фронтенд Server-Sent Events?

Замените media_type на text/event-stream и оборачивайте каждый чанк в формат SSE (data: …\n\n). Клиент читает его через EventSource или fetch с ReadableStream.

Что вернётся при ошибке модели или лимите?

SDK бросит исключение (RateLimitError, APIStatusError) с кодом 429, 403 или 401. Ловите его в обработчике и возвращайте клиенту корректный HTTP-статус вместо 500.

AI-эндпоинт на FastAPI — сразу после регистрации

Получить ключ