DuckoNetДокументация0.11.6Документация DuckoLab
Разделы

Повторы запросов и HTTP-кеш

Повторы запросов

import os
from duckonet import HttpClient, RetryPolicy

with HttpClient(
    api_key=os.environ['DUCKONET_API_KEY'],
    retry_policy=RetryPolicy(max_retries=2),
) as client:
    response = client.get('https://example.com/status')
    print(response.attempt_count)
RetryPolicyПо умолчаниюОграничение / смысл
max_retries0Дополнительные попытки, 0–10; всего не более 1 + max_retries.
methods('GET', 'HEAD', 'OPTIONS')Явный кортеж HTTP-методов; CONNECT запрещён. Остальные методы добавляются только при осознанном разрешении повторной операции.
statuses(408, 425, 429, 500, 502, 503, 504)Кортеж кодов 400–599; 401, 403 и 407 не допускаются.
errors('dns', 'connect', 'timeout', 'receive', 'http2', 'http3')Разрешённые группы сетевых ошибок.
backoff_factor0.25Начальная задержка в секундах, удваивается при последующих повторах; диапазон 0–300.
max_delay30Верхний предел одной задержки в секундах, 0–300.
jitter0.1Относительный разброс задержки, 0–1.
respect_retry_afterTrueУчитывать единственный корректный Retry-After: секунды либо HTTP-дата, в пределах общего бюджета и max_delay.

Все числовые задержки должны быть конечными. Ошибки аргументов, лицензии, проверки TLS-сервера и отмена не превращаются в автоматический повтор. После передачи пользователю части потокового ответа повтор не начинается. Для отправляемого тела нужен повторяемый источник: байты, поддержанный seekable-источник или фабрика из существующего upload API.

Повтор POST может повторить действие на сервере даже при потере ответа. Библиотека не может гарантировать его безопасность по одному Idempotency-Key; разрешайте такие методы только с учётом контракта вашего сервера. Cookies обрабатываются из реально полученных ответов; повторы не перезапускают полный внешний прогон и не выбирают другой профиль.

RetryAttempt(attempt, reason, status_code, delay_seconds) описывает принятое решение о повторе. Причины и группы ошибок конечны; объект не содержит текст тела, заголовки или ключи. retry_history не включает отдельно каждый redirect.

Для собственной обвязки policy.permits(method, retries) проверяет метод и число уже назначенных повторов; policy.error_group(error) возвращает разрешённую группу для известной нативной ошибки либо None; policy.delay(retries, response=None) вычисляет задержку в секундах. Аргумент retries у delay — целый индекс 0–10. Эти методы сами не отправляют запрос и не ожидают задержку; обычному приложению достаточно передать политику клиенту.

Кеш HTTP-ответов

import os
from duckonet import HttpClient, MemoryResponseCache

cache = MemoryResponseCache(max_entries=128)
try:
    with HttpClient(api_key=os.environ['DUCKONET_API_KEY'], response_cache=cache) as client:
        response = client.get('https://example.com/public-data')
        print(response.from_cache)
finally:
    cache.close()
КонструкторПараметры по умолчанию
MemoryResponseCachemax_entries=256, max_bytes=16777216, max_entry_bytes=1048576, default_ttl=0, max_ttl=3600
FileResponseCache(directory, ...)max_entries=256, max_bytes=16777216, max_entry_bytes=524288, default_ttl=0, max_ttl=3600

Общие пределы: max_entries от 1 до 10000; max_bytes от 1 до 1073741824. max_entry_bytes от 1 до 67108864 для памяти и до 524288 для файлового backend. TTL задаются в секундах от 0 до 2592000. default_ttl=0 не кеширует ответ без подходящего срока свежести. max_ttl ограничивает срок, вычисленный из серверных Cache-Control/Expires с учётом Date и Age.

Файловый backend получает отдельный закрытый каталог и сохраняет ограниченные JSON-записи с атомарной заменой. Повреждённая или просроченная запись считается промахом; исполняемый формат и pickle не используются. Объект кеша остаётся во владении приложения. close() памяти очищает её; close() файлового кеша закрывает объект, сохраняя записи на диске. Для удаления принадлежащих ему записей вызовите clear() до close().

Кеш применяется только к полным буферизованным ответам GET/HEAD со статусами 200, 203, 204, 404, 410. Ответы после redirect, запросы с телом, streaming и WebSocket его не используют. no-cache, no-store, private, Vary: *, Range/206, авторизация, cookies и Set-Cookie исключают использование. Изменения сетевых/TLS-настроек также консервативно обходят кеш. Условной валидации ETag/304 и выдачи просроченных ответов нет.

Ключ учитывает адрес, метод, эффективные заголовки, аккаунт, профиль, маршрут и namespace. Права проверяются и при чтении из кеша. Наличие сохранённого тела не даёт права обойти лицензию. Не используйте общий backend для намеренного хранения секретных данных приложения; незнакомый библиотеке пользовательский заголовок не обязательно распознаётся как секрет.

Для собственного backend наследуйте ResponseCache(default_ttl=0, max_ttl=3600) и реализуйте get(key), put(key, entry), clear(), close(). get возвращает CacheEntry либо None; put — удалось ли сохранить запись. Ключ — 64 строчных hex-символа. CacheEntry(status_code, protocol, headers, body, created_at, expires_at, initial_age=0) содержит bytes-тело, пары заголовков и Unix-время; size учитывает тело и заголовки. Ваш backend обязан обеспечить ограничения, изоляцию и безопасность своей реализации. CacheError сообщает об ошибке состояния кеша.

Текст страницы