Практикум: описание API для расчёта доставки¶
Это краткое описание задачи и нужного ей API к статье о документации. Здесь собраны зависимости примера, правила работы и команда проверки. Полный справочник библиотеки находится отдельно.
Окружение и задача¶
| Что нужно знать | Правило |
|---|---|
| Пакет | deadline-budget==0.1.3 |
| Импорты | from deadline_budget import BudgetContext, DeadlineExceededError |
| Окружение примера | Python 3.13; asyncio.timeout() требует Python 3.11+ |
| Методы библиотеки | Синхронные: возвращают значения или выбрасывают исключения без await |
| Задача библиотеки | Считать остаток времени и таймаут следующего вызова |
| Отмена | Приложение использует asyncio.timeout(); сам бюджет ничего не отменяет |
Приложение проверяет остаток товара и затем рассчитывает доставку с общим бюджетом 600 мс. Для каждого шага задан предел 400 мс. Если товара нет, результат равен None; иначе возвращается ответ адаптера доставки.
stock и shipping являются асинхронными функциями приложения, а не клиентами из deadline-budget. Обе принимают (sku, *, timeout), где таймаут задан в секундах. stock возвращает целое количество товара, а shipping возвращает расчёт доставки. Настоящие адаптеры должны применять переданный таймаут и не подавлять отмену. Практикум подставляет управляемые функции в том же процессе; HTTP-библиотека и развёрнутый склад здесь не проверяются.
Используемый API¶
BudgetContext.create(total_seconds, call_caps=None, *, min_timeout=0.1, safety_margin=0.0)синхронно возвращаетBudgetContext.ctx.remaining()возвращает остаток секунд какfloat; после истечения времени он может быть отрицательным.ctx.timeout_for_call(call_name, reserve_for_next=0.0)возвращает секунды или выбрасываетDeadlineExceededError, если бюджет уже исчерпан.- Для неизвестного
call_nameотдельного ограничения нет. Опечатка в имени не вызывает ошибку конфигурации. - Минимум по умолчанию равен 100 мс и может превышать остаток времени. В примере явно заданы
min_timeout=0и отдельное ограничение всей операции.
Рабочий пример¶
import asyncio
from deadline_budget import BudgetContext
async def shipping_quote(sku, *, stock, shipping):
ctx = BudgetContext.create(
total_seconds=0.6,
min_timeout=0,
call_caps={"stock": 0.4, "shipping": 0.4},
)
async with asyncio.timeout(ctx.remaining()):
available = await stock(sku, timeout=ctx.timeout_for_call("stock"))
if available <= 0:
return None
return await shipping(sku, timeout=ctx.timeout_for_call("shipping"))
Один контекст создаётся на вызов функции и используется в обоих шагах. DeadlineExceededError означает, что расчёт бюджета не позволил начать следующую работу. TimeoutError может прийти от ограничения всей операции или от адаптера; пример передаёт оба типа ошибок вызывающему коду. Блокирующий код и код, подавляющий отмену, могут выйти за пределы таймаута asyncio.
Запуск проверок¶
С установленным uv выполните из корня репозитория сайта:
cd docs/blog/lab/2026-09-07-documentation-for-ai-coding-agents
uv run --no-project --python 3.13 --with-requirements requirements.txt python test_contract.py
Тесты на стандартной библиотеке проверяют версию и значения аргументов по умолчанию, ошибочный await перед синхронным методом, общий бюджет, ошибку с новым контекстом на каждом шаге из статьи, маленький остаток, который доходит до адаптера без изменений, отсутствие лимита для неизвестного имени, нулевой остаток товара, исчерпание времени перед следующим шагом и отличие расчёта от отмены. Код выше и его копии в английской и русской статьях сравниваются с shipping.py по синтаксическому дереву: если поменять только одну копию, проверка упадёт. Эти проверки синхронизации нужны тем, кто поддерживает страницу; самостоятельную реализацию оценивают поведенческие тесты.
Во всех тестах подменены часы внутри модуля библиотеки; тест сдвигает их вручную. Часы asyncio остаются настоящими. Отдельная проверка зависшего вызова дожидается реальной отмены по общему лимиту 600 мс; дополнительный таймаут в пять секунд защищает сам тест. Точные миллисекунды выполнения не проверяются.
Docker, внешний сервис и ключ API не нужны. Сеть нужна только для загрузки Python или зафиксированной версии пакета, если их нет в кеше. Несовпадение утверждения завершает запуск с ошибкой. Эти тесты проверяют документацию и код, а не качество работы ИИ-модели.
Файлы и дальнейшее чтение¶
shipping.py: функция приложения, показанная на этой странице.test_contract.py: проверки кода и документации.requirements.txt: версия пакета для примера.- Руководство deadline-budget 0.1.3 для агентов: более полный API зафиксированной версии.
- Статья о дедлайнах: передача бюджета и подключение клиентов.