2025, Nov 30 12:01
Ошибка с execute_batch в gql на Python: причина и решение
Разбираем ошибку AttributeError: нет execute_batch в gql при работе с GraphQL на Python через httpx. В какой версии появится и как запустить уже сейчас.
Когда вы подключаете клиент GraphQL на Python поверх httpx, возникает соблазн объединять операции в батчи ради большей пропускной способности и меньшего числа сетевых походов. Частая ловушка проявляется сразу, как только вы пытаетесь вызвать execute_batch у сессии: AttributeError: 'AsyncClientSession' object has no attribute 'execute_batch'. Ниже — короткое объяснение, почему это происходит, и прямой способ все запустить.
Как воспроизвести проблему
Обычно схема такая: создаете Client с HTTPXAsyncTransport, открываете асинхронный контекст и вызываете execute_batch с перечнем объектов GraphQLRequest.
from gql import Client, GraphQLRequest
from gql.transport.httpx import HTTPXAsyncTransport
from itertools import batched
import asyncio
async def run():
async with Client(
transport=HTTPXAsyncTransport(url=GQL_URL, headers=GQL_HEADERS, timeout=3000),
batch_interval=5
) as ctx:
result = await ctx.execute_batch([
GraphQLRequest(document=QUERY, variable_values=VARIABLES) for chunk in batched(DATA, 1000)
])
print(result)
asyncio.run(run())
Что происходит
API execute_batch недоступен в текущей установленной стабильной ветке библиотеки gql. Судя по релизам проекта, execute_batch появится в версии 4 gql, которая пока в бете. Поэтому объект сессии не имеет этого атрибута и во время выполнения выбрасывает AttributeError.
Как исправить
Если вам окей работать с бета-версией, установите бета-выпуск v4, чтобы получить execute_batch:
pip install gql==v4.0.0b0
После этого тот же клиентский код сможет вызывать execute_batch как задумано.
from gql import Client, GraphQLRequest
from gql.transport.httpx import HTTPXAsyncTransport
from itertools import batched
import asyncio
async def run():
async with Client(
transport=HTTPXAsyncTransport(url=GQL_URL, headers=GQL_HEADERS, timeout=3000),
batch_interval=5
) as ctx:
result = await ctx.execute_batch([
GraphQLRequest(document=QUERY, variable_values=VARIABLES) for chunk in batched(DATA, 1000)
])
print(result)
asyncio.run(run())
Почему это важно
Доступность API часто меняется между мажорными версиями. Попытка использовать метод, существующий лишь в будущей версии, приводит к запутанным ошибкам времени выполнения, особенно в асинхронных сценариях, где трассировки могут быть шумными. Понимание, в какой версии появилась нужная возможность, помогает осознанно планировать обновление зависимостей и не охотиться за несуществующими багами в собственном коде.
Выводы
Если execute_batch нужен уже сейчас — используйте бета-сборку gql v4. Если предпочитаете только стабильные зависимости, отложите этот API до релиза v4. В любом случае сверяйте установленные версии пакетов с планируемыми возможностями и заглядывайте в релиз-ноты проекта перед тем, как брать новые методы в работу.