AI-интеграции для Python-разработчика

ChatGPT API в Python: первое приложение за 30 минут

ChatGPT API — самый быстрый способ добавить «ум» в любой Python-скрипт: от суммаризатора отзывов до ассистента в Telegram-боте. За 30 минут получим работающее приложение: ключ, первый запрос, стриминг и защита от типовых граблей.

Версии: Python 3.12, openai SDK 1.x.

Шаг 1. Ключ и установка

pip install openai
export OPENAI_API_KEY="sk-..."
export OPENAI_BASE_URL=""   # для агрегаторов: их OpenAI-совместимый URL
export OPENAI_MODEL="gpt-4o-mini"  # актуальное имя модели смотрите у провайдера

Про доступ из России: OpenAI напрямую не работает с РФ, поэтому практика 2026 года — агрегаторы с OpenAI-совместимым endpoint (рублёвая оплата, те же модели). Важно: весь код ниже с ними работает без изменений, отличается только base_url. Ключ — только в переменные окружения, никогда в git: украденный ключ кто-то будет использовать, а платить придётся вам.

Шаг 2. Первый запрос

import os

from openai import OpenAI

client = OpenAI()  # читает OPENAI_API_KEY и OPENAI_BASE_URL из окружения

response = client.chat.completions.create(
    model=os.environ["OPENAI_MODEL"],
    messages=[
        {"role": "system", "content": "Ты — лаконичный ассистент-программист. Отвечай по-русски, без воды."},
        {"role": "user", "content": "Чем asyncio отличается от threading в одном абзаце?"},
    ],
    max_tokens=300,
    temperature=0.3,
)
print(response.choices[0].message.content)

Три параметра, которые стоит понимать с первого дня:

  • messages — диалог как список ролей. system задаёт характер (видит только модель), user — запрос, assistant — прошлые ответы (так поддерживается контекст).
  • max_tokens — потолок длины ответа. Обязателен в боевом коде: без него сбой логики = непредсказуемый счёт.
  • temperature — креативность. 0–0.3 для фактических задач, 0.7+ для текстов. Для кода и извлечения данных — всегда низкая.

Шаг 3. Стриминг: ответ по мере генерации

Пока модель пишет 20 секунд, пользователь смотрит на курсор. Стриминг решает: токены приходят порциями, как в чате ChatGPT:

stream = client.chat.completions.create(
    model=os.environ["OPENAI_MODEL"],
    messages=[{"role": "user", "content": "Напиши план обучения Python на месяц"}],
    max_tokens=800,
    stream=True,
)

for chunk in stream:
    delta = chunk.choices[0].delta.content
    if delta:
        print(delta, end="", flush=True)

Для CLI и чат-ботов — почти всегда правильный выбор. Позже, в треке Django, разберём стриминг в веб через SSE — там он же.

Шаг 4. Устойчивый клиент: ретраи и обработка ошибок

API падает: rate limits, перегрузки, обрывы. Боевой код обязан переживать это:

import time

from openai import APIConnectionError, APITimeoutError, OpenAI, RateLimitError

client = OpenAI(max_retries=0)  # ретраи делаем сами, с экспоненциальным бэкоффом


def ask(messages: list[dict], max_tokens: int = 500) -> str:
    for attempt in range(4):
        try:
            response = client.chat.completions.create(
                model=os.environ["OPENAI_MODEL"],
                messages=messages,
                max_tokens=max_tokens,
                temperature=0.2,
                timeout=30,
            )
            return response.choices[0].message.content
        except (RateLimitError, APIConnectionError, APITimeoutError) as exc:
            if attempt == 3:
                raise
            wait = 2 ** attempt  # 1, 2, 4 секунды
            print(f"{type(exc).__name__}, повтор через {wait}с")
            time.sleep(wait)
    return ""

Два нюанса: ретраим только транзиентные ошибки (лимиты, сеть), а не InvalidRequestError — она повторится всегда. И max_retries=0 в клиенте — встроенные ретраи SDK без бэкоффа под ваш лимит часто усугубляют RateLimit.

Шаг 5. Приложение за минуту: суммаризатор отзывов

Скрестим с прошлыми статьями: парсер собрал отзывы, API их суммаризует:

import json


def summarize_reviews(reviews: list[str]) -> dict:
    prompt = (
        "Проанализируй отзывы и верни строго JSON с ключами "
        "'pluses' (список), 'minuses' (список), 'summary' (одна строка):\\n"
        + "\\n".join(f"- {r}" for r in reviews[:50])
    )
    text = ask([{"role": "user", "content": prompt}], max_tokens=600)
    return json.loads(text)  # модель вернула валидный JSON — см. caveat ниже


reviews = [
    "Отличный товар, но доставка неделю",
    "Качество хорошее, цена кусается",
    "Всё супер, рекомендую",
]
print(summarize_reviews(reviews))

Caveat про JSON: модель может вернуть текст вокруг JSON. Практика: просить строго JSON, низкий temperature, и на всякий случай извлекать первое {...} из ответа регуляркой. Для критичных схем смотрите structured outputs у провайдера — но на старте хватает дисциплины промпта.

Деньги и токены: как не получить сюрприз в счёте

  • Счёт = токены входа + выхода. Длинный system-промпт и история диалога платятся на каждый запрос. Контекст обрезайте осознанно.
  • Дешёвая модель для черновиков. Классификация, извлечение данных, перефраз — отлично делаются на мини-моделях в 10–20 раз дешевле флагманских. Флагман — для сложных рассуждений.
  • Алерт на расход в кабинете провайдера — первая настройка после получения ключа, не последняя.

Итог

За 30 минут: ключ в окружении → openai SDK → стриминг → ретраи → первое реальное приложение. Дальше по плану кластера: подключаем это к Telegram-боту — получаем бота, который отвечает осмысленно, а потом учим его отвечать по вашим документам через RAG.

FAQ

Чем ChatGPT API отличается от чата на chat.openai.com?

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

Как получить API-ключ из России в 2026 году?

Напрямую OpenAI работу с РФ не поддерживает. Рабочие пути: B2B-агрегаторы с OpenAI-совместимым endpoint (оплата в рублях, те же модели) или ключ через зарубежную компанию. Код ниже одинаково работает с любым OpenAI-совместимым endpoint — меняется только base_url.

Сколько стоит один запрос к API?

Цена считается в токенах (фрагментах слов): ~750 токенов ≈ 500 слов на английском. Упрощённо: короткий запрос-ответ на дешёвой модели — копейки, длинный документ на флагманской — рубли. Всегда считайте бюджет на тестовом наборе перед боевым запуском.

Как не слить бюджет на бесконечном цикле с API?

Три правила: max_tokens в каждом запросе, лимит количества запросов в коде (не только настройка в кабинете), алерт по расходу на стороне провайдера. Один зависший while-цикл без max_tokens может сожрать месячный бюджет за ночь.

Один разбор в неделю на YouTube

Каждой статье здесь — пара-видео на канале @PythonSimple: та же задача, живой код, коротко.

Подписаться на @PythonSimple