Запросы, ответы и авторизация
Быстрый запрос
import os
from duckonet import get
response = get(
'https://example.com/',
api_key=os.environ['DUCKONET_API_KEY'],
browser='chrome',
version='last',
)
print(response.status_code)
print(response.text)
request(method, url, *, api_key, browser='chrome', version=None, state_dir=None, client_options=None, **kwargs) открывает временный HttpClient, выполняет один запрос и закрывает клиент. Ответ остаётся доступен после закрытия. Параметры самого клиента, например прокси и ограничения, передаются словарём client_options; параметры запроса — именованными аргументами. api_key и browser нельзя дублировать в client_options. Явные version и state_dir также не должны дублироваться там.
Сокращения get, head, post, put, patch, delete, options принимают url и те же именованные аргументы. Для асинхронного кода доступны async_request, async_get, async_head, async_post, async_put, async_patch, async_delete, async_options; их результат нужно ожидать через await.
Эти функции возвращают буферизованный ответ. Потоковое чтение требует явно открытого клиента и client.stream(...). Для серии запросов также держите один клиент открытым, чтобы переиспользовать его состояние и соединения.
Настройки HTTP-клиента
Пример с общим адресом и параметрами:
import os
from duckonet import HttpClient
with HttpClient(
api_key=os.environ['DUCKONET_API_KEY'],
browser='chrome',
version='last',
base_url='https://example.com/api/',
params={'language': 'ru'},
raise_for_status=True,
) as client:
response = client.get('items', params={'page': 2})
print(response.json())
AsyncHttpClient использует те же настройки; открывайте его через async with, запросы выполняйте через await.
| Параметр конструктора | Значение по умолчанию | Назначение |
|---|---|---|
base_url | None | Базовый абсолютный HTTP(S)-адрес. Относительные адреса разрешаются по обычным правилам URL; абсолютный адрес задаёт собственный сервер. Логин и пароль внутри URL запрещены. |
params | None | Общие query-параметры, словарь или последовательность пар. Параметр запроса с тем же именем заменяет общий; повторяющиеся имена внутри запроса сохраняются. |
auth | None | BasicAuth или BearerAuth. Общая авторизация привязана к origin базового адреса либо первого запроса, если базовый адрес не задан. |
raise_for_status | False | Автоматически вызывать response.raise_for_status() для конечного ответа. |
retry_policy | None | Необязательная политика повторов; без неё повторов нет. |
response_cache | None | Необязательный кеш HTTP-ответов. Это отдельный объект, которым владеет вызывающий код. |
cache_namespace | 'default' | Дополнительная область кеша: 1–64 символа из букв, цифр, _, -, .. |
network | None | Неизменяемый NetworkOptions для соединений этого клиента. |
tls | None | TLSOptions: клиентский сертификат и дополнительные SPKI-пины. |
rate_limit | None | RateLimit: ограничение скорости передачи тела. |
diagnostic_hook | None | Функция, получающая описание завершённого запроса без заголовков и тела. |
Настройки соединения network, tls, rate_limit также принимают Client, AsyncClient, Distribution.session и Distribution.async_session. При прямом создании транспорта они входят в TransportConfig. Они задаются для сессии, а не меняются посреди уже работающего соединения.
Дополнительные параметры client.request и сокращений get/post/других методов:
| Параметр | Если не передан | Поведение |
|---|---|---|
auth | Настройка клиента | Явный None отключает общий helper на этом запросе. Явный helper задаёт авторизацию для выбранного запроса; обычные ограничения перенаправлений сохраняются. |
referer | Заголовок не добавляется helper-ом | Абсолютный HTTP(S)-адрес для Referer. Конфликт с одноимённым явным заголовком вызывает ошибку. |
accept_encoding | Действуют настройки профиля | Список через запятую из identity, gzip, deflate, br, zstd. Неподдержанное имя или конфликт с явным заголовком отклоняется. |
use_default_params | True | False исключает общие params клиента из данного запроса. params=None или пустая последовательность сами по себе общие параметры не очищают. |
raise_for_status | Настройка клиента | True включает автоматическую ошибку HTTP-статуса, False отключает. |
retry_policy | Настройка клиента | Явный None отключает повторы данного запроса. |
cache | Включён, если задан backend | False обходит кеш; True требует настроенный response_cache. Потоковые запросы и запросы с телом кеш не используют. |
BasicAuth(username, password, encoding='latin-1') формирует HTTP Basic. Для UTF-8 укажите encoding='utf-8'; двоеточие в имени пользователя и управляющие символы запрещены. BearerAuth(token) формирует Bearer-заголовок. Эти объекты не показывают свои секреты в repr.
Helper авторизации нельзя совмещать с явным Authorization в том же запросе. Авторизацию другого сервера задавайте отдельным клиентом либо явным параметром запроса. API-ключ DuckoNet предназначен для доступа к библиотеке; он не является Bearer-токеном вашего целевого сайта.
У обоих helper-объектов authorization() возвращает готовое секретное значение заголовка. Обычно вызывать метод вручную не требуется; не выводите его результат в журнал.
Остальные правила запросов сохраняются: json=None отправляет JSON null; body содержит bytes, data — текст, байты или поля формы; для больших тел используйте существующий upload. Общий таймаут ограничивает весь запрос, перенаправления и повторы вместе.
Ответ
| Свойство | Значение |
|---|---|
ok | True, если status_code < 400. Это не проверка содержимого ответа. |
is_redirect | Статус 301, 302, 303, 307 или 308 и присутствующий Location. |
url_text | URL ответа в виде str. Исходное свойство url сохраняет свой прежний тип. |
charset | Кодировка из Content-Type, либо None. |
status_description | Стандартное описание числового HTTP-статуса, например Not Found; пустая строка для неизвестного кода. Это не фраза, полученная от сервера. |
reason | None: серверная reason phrase не предоставляется. |
cookies_received | Кортеж ReceivedCookie(name, value, attributes, accepted=None), разобранных из Set-Cookie этого ответа. |
request_info | Необязательный HttpRequestInfo(method, url, headers) исходящего логического запроса. Query и fragment исключены; известные заголовки авторизации и cookies замаскированы. |
retry_history | Кортеж описаний сделанных повторов RetryAttempt. |
attempt_count | Число сетевых попыток этого запроса; для ответа из кеша — 0. |
from_cache | Получен ли ответ из HTTP-кеша. |
cache_info | CacheInfo(from_cache, age_seconds, expires_at) либо None; возраст в секундах, срок — Unix-время. |
socket_info | Необязательные фактические локальный и удалённый сетевые адреса. |
cookies_received — снимок атрибутов ответа, а не контейнер действующих cookies. accepted=None означает, что снимок не содержит вердикта cookie-политики. Действующие cookies продолжает обслуживать client.cookies; повторно добавлять весь Set-Cookie из снимка не нужно.
request_info не является записью сырых пакетов. Пользовательские заголовки и путь URL могут содержать данные приложения: не публикуйте такой снимок без собственного контроля. Для журнала без заголовков и пути используйте diagnostic_hook.
Существующие content, text, decode, json, headers, history и raise_for_status сохраняют своё назначение. При автоматической ошибке HTTP-статуса ответ находится в HTTPStatusError.response.
Чтение по строкам
import os
from duckonet import HttpClient
with HttpClient(api_key=os.environ['DUCKONET_API_KEY']) as client:
with client.stream('GET', 'https://example.com/events') as stream:
for line in stream.iter_lines(encoding='utf-8'):
print(line)
stream.iter_lines(*, encoding=None, errors='strict', max_line_bytes=1048576, chunk_size=65536) возвращает строки без разделителей. Поддерживаются LF, CRLF и CR, пустые строки и последняя строка без завершающего переноса. Кодировка выбирается по явному параметру, настройке потока, charset ответа, затем UTF-8. Ошибки декодирования обрабатываются согласно errors.
max_line_bytes — предел кодированного представления одной строки, от 1 до 16777216. chunk_size — порция чтения, в том же диапазоне. Превышение предела строки вызывает ValueError; неверные байты при errors='strict' — ошибку декодирования. Для AsyncHttpClient используйте async with client.stream(...) и async for line in stream.aiter_lines(...); iter_lines у асинхронного потока возвращает тот же асинхронный итератор.
При досрочном выходе закрывайте контекст потока. Если сам итератор строк закрыт до EOF, он отменяет незавершённый запрос. Все тело целиком для разделения строк не накапливается.
Выбор браузерной версии на один прогон
import os
from duckonet import HttpClient
with HttpClient(api_key=os.environ['DUCKONET_API_KEY'], version='last') as client:
print(client.available_browser_versions(version_range=(150, 155)))
with client.run(version_range=(150, 155), random_profile=True):
print(client.browser_profile)
response = client.get('https://example.com/')
available_browser_versions(*, version_range=None) возвращает кортеж доступных версий из подписанного совместимого каталога с учётом прав аккаунта и текущего протокола. Метод вызывается на открытом клиенте. Диапазон — включительно, два целых major-номера; он не создаёт отсутствующие версии.
run(*, version_range=None, random_profile=False) фиксирует профиль на полный прогон. Если задан диапазон и random_profile=False, выбирается старшая доступная версия диапазона; при True — один случайный допустимый профиль. Все запросы, перенаправления и повторы внутри прогона используют этот выбор. Вложенный прогон не может произвольно заменить уже закреплённый профиль. Диапазон несовместим с явным profile_id.
Асинхронный вариант использует async with client.run(...); список версий и свойство browser_profile читаются обычным вызовом. Cookies остаются в общем контейнере логического клиента. version='last' продолжает означать последнюю разрешённую версию, а переход на обновлённый профиль происходит между полными прогонами.