📝 Ai

Google GenAI SDK в Python: синхронные и асинхронные запросы

P
Автор
PyLand Team
📅
Опубликовано
18.09.2026
⏱️
Время чтения
2 мин
👁️
Просмотров
2
🌿
Уровень
Средний

Официальный пакет google-genai позволяет обращаться к Gemini из Python без ручной сборки HTTP-запросов. Эта памятка подходит для FastAPI-приложений, фоновых задач и обычных скриптов.

SDK можно представить как переводчика: ты вызываешь понятный Python-метод, а библиотека
сама собирает запрос к API и превращает ответ в Python-объект. Сетевые ошибки, timeout,
ключи и проверка результата при этом всё равно остаются ответственностью приложения.

Для первого запуска сохрани demo-режим. Тогда проект работает сразу, а настоящий
Gemini подключается как дополнительная возможность, когда появится учебный ключ.

Установи официальный пакет

В проекте с uv добавь зависимость командой:

uv add "google-genai>=2,<3"

Если зависимость уже зафиксирована в pyproject.toml и uv.lock, ничего добавлять не нужно:

uv sync --frozen --dev

Правильный импорт выглядит так:

from google import genai

Не устанавливай устаревший google-generativeai для нового проекта.

Не храни ключ в коде

Передай ключ через переменную окружения или настройки приложения:

from google import genai

client = genai.Client(api_key=settings.gemini_api_key)

Файл .env с настоящим ключом не должен попадать в Git. В .env.example оставляй только пустое значение:

GEMINI_API_KEY=
GEMINI_MODEL=gemini-2.5-flash

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

Выполни обычный запрос

response = client.models.generate_content(
    model=settings.gemini_model,
    contents="Объясни HTTP-статус 404 одним предложением",
)

text = (response.text or "").strip()
if not text:
    raise RuntimeError("Gemini returned an empty response")

response.text может быть пустым, поэтому проверяй результат до сохранения или отправки пользователю.

Не блокируй FastAPI

В обработчике async def используй асинхронную часть клиента:

import asyncio

response = await asyncio.wait_for(
    client.aio.models.generate_content(
        model=settings.gemini_model,
        contents=prompt,
    ),
    timeout=settings.gemini_timeout_seconds,
)

asyncio.wait_for ограничивает ожидание на уровне твоего приложения. asyncio.TimeoutError можно преобразовать в контролируемый ответ 504, а ожидаемые ошибки провайдера — в 502. Не возвращай пользователю текст исключения: он может содержать лишние технические подробности.

Полезная модель в голове: 502 означает «внешний сервис ответил с ошибкой», а 504
«мы не дождались его вовремя». В обоих случаях само FastAPI-приложение продолжает
работать и может предложить повторить попытку.

Сделай интеграцию заменяемой

Не создавай клиента прямо в маршруте. Спрячь внешний сервис за небольшим интерфейсом:

from typing import Protocol


class TextProvider(Protocol):
    async def improve(self, text: str) -> str: ...

Тогда приложение сможет использовать:

  • GeminiProvider в настроенном окружении;
  • предсказуемый DemoProvider без ключа;
  • fake-провайдер в тестах без сетевого запроса.

Такой подход делает урок и CI воспроизводимыми и не тратит квоту во время тестов.

Частые ошибки

  • ModuleNotFoundError — выполни uv sync --frozen --dev, затем запускай код через uv run.
  • Ответ 401 или 403 — проверь ключ и доступ проекта, но не печатай ключ в терминале или логах.
  • Ответ 404 для модели — проверь доступные для твоего аккаунта модели и измени настройку GEMINI_MODEL.
  • FastAPI зависает на запросе — убедись, что вызываешь client.aio... с await, а не синхронный метод.
  • Тест обращается в интернет — подмени dependency до отправки запроса и очищай overrides после теста.

Проверка готовности

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

Официальная документация

Ваша реакция на статью

💬 Комментарии (0)

🔐 Войдите в систему, чтобы оставить комментарий
🚪 Войти
💭

Комментариев пока нет

Станьте первым, кто поделится мнением об этой статье!

🔗 Похожие

Похожие статьи

Продолжите изучение с этими материалами

📝

if __name__ == "__main__": точка входа Python

Конструкция if name == "main" определяет точку входа Python-программы: она помогает отличить прямой запуск файла...

📅 14.08.2026 👁️ 125
📝

strip() и lower(): подготавливаем пользовательски…

Пользователь может ввести правильное слово с лишними пробелами или буквами другого регистра. Для Python строки...

📅 11.08.2026 👁️ 100
📝

ord(), chr() и циклический сдвиг букв в Python 🔐

Строка состоит из символов, но компьютер хранит каждый символ как числовой код. Python позволяет переходить...

📅 09.08.2026 👁️ 177

Понравилась статья?

Подпишитесь на наши обновления и получайте новые статьи первыми. Развивайтесь вместе с PyLand!