Перейти к содержанию

Руководство · На русском

Прокси в HTTPX: Client и AsyncClient

Настройте HTTP-прокси с авторизацией для синхронного или асинхронного запроса Python. Начните с короткой проверки HTTPS, затем перенесите те же параметры в своё приложение.

Инструкции в этом разделе — на русском. Магазин, личный кабинет, документация и условия заказа пока доступны на английском.

Опубликовано:

Короткие ответы

Как передать прокси в HTTPX?

Укажите proxy= при создании Client или AsyncClient. Объект httpx.Proxy позволяет передать адрес шлюза отдельно от имени пользователя и пароля. Настройка действует на запросы этого клиента.

Почему возникает unexpected keyword argument proxies?

В HTTPX 0.28 удалён устаревший аргумент proxies=. Для одного шлюза используйте proxy=. Словарь из примера для Requests нельзя без изменений перенести в HTTPX: интерфейсы библиотек различаются.

Нужно ли писать https:// в адресе прокси?

Для HTTP-шлюза оставьте http://. При запросе HTTPS-страницы клиент сначала создаёт туннель CONNECT, затем проверяет сертификат конечного сайта. Схема адреса шлюза описывает соединение с самим прокси.

Проверьте версию и окружение Python

Примеры рассчитаны на Python 3.11 или новее и HTTPX 0.28.1. Установите библиотеку в окружение проекта и проверьте импорт тем интерпретатором, который запускает задачу. Терминал, notebook и фоновый worker могут использовать разные окружения. Не меняйте зависимости работающего приложения до проверки его lock-файла и совместимости остальных пакетов.

Установка проверенной версииsh
python -m pip install "httpx==0.28.1"
python -c "import httpx; print(httpx.__version__)"

Изменение аргумента описано в заметках о выпуске HTTPX 0.28. Здесь показана настройка одного HTTP-шлюза. Для другого клиента есть отдельные инструкции: Python Requests и aiohttp. Их параметры авторизации и управления соединениями не взаимозаменяемы.

Подготовьте адрес и авторизацию

Получите полное имя пользователя в личном кабинете, выбрав доступные пул и страну. Передайте это имя через переменную окружения PROXY_USER. Пароль прокси вводится отдельно через запрос без отображения ввода. Пароль аккаунта и ключ API здесь не подходят. Сохраните следующие три Python-файла в одной папке, чтобы обе проверки импортировали общий файл настроек.

proxy_settings.py — общие настройкиpython
import getpass
import os
import ssl
from urllib.parse import urlsplit

import certifi
import httpx


def connection_settings():
    server = os.environ.get("PROXY_SERVER", "http://gw.portproof.org:7000")
    address = urlsplit(server)
    if (address.scheme != "http" or not address.hostname
            or address.port is None or address.username is not None
            or address.password is not None or address.path not in ("", "/")
            or address.query or address.fragment):
        raise SystemExit("Use an HTTP gateway URL without credentials or a path")
    proxy = httpx.Proxy(
        server,
        auth=(os.environ["PROXY_USER"], getpass.getpass("Proxy password: ")),
    )
    tls = ssl.create_default_context(
        cafile=os.environ.get("PROXY_CA_BUNDLE") or certifi.where()
    )
    return {
        "proxy": proxy,
        "verify": tls,
        "trust_env": False,
        "follow_redirects": False,
        "timeout": httpx.Timeout(10.0, connect=5.0, pool=2.0),
    }

Имя и пароль передаются парой auth в объект Proxy. Поэтому знаки пунктуации в пароле не превращаются в части URL. Это авторизация на шлюзе: не переносите её в auth конечного запроса или обычный заголовок Authorization. Не выводите объект настроек в журнал. В фоновой задаче замените интерактивный ввод обращением к своему хранилищу секретов до начала сетевой работы.

Параметр trust_env=False исключает влияние HTTP_PROXY, HTTPS_PROXY и NO_PROXY на выбранный маршрут. Проверка сертификатов также задана явно: используется certifi либо одобренный вами набор PROXY_CA_BUNDLE. Переменная SSL_CERT_FILE в этом примере не выбирает набор сертификатов. Если в вашей сети обязателен корпоративный шлюз или сертификат, настройте их осознанно, сохранив требования сети.

HTTPS защищает обмен с конечным сайтом внутри туннеля. Начальный CONNECT к HTTP-шлюзу и его Basic-авторизация не получают от этого отдельного TLS-шифрования. Используйте доверенное сетевое соединение и не сохраняйте трассировки с учётными данными.

Сделайте один запрос через Client

httpx_check.py — синхронная проверкаpython
import json

import httpx

from proxy_settings import connection_settings

settings = connection_settings()
try:
    with httpx.Client(**settings) as client:
        with client.stream("GET", "https://api.portproof.org/v1/echo-ip") as response:
            response.raise_for_status()
            body = bytearray()
            for chunk in response.iter_bytes(chunk_size=8192):
                if len(body) + len(chunk) > 65536:
                    raise ValueError("Echo response exceeds 64 KiB")
                body.extend(chunk)
            payload = json.loads(body)
            if not isinstance(payload, dict) or not isinstance(payload.get("ip"), str):
                raise ValueError("Expected an IP address in the echo response")
            print("HTTP", response.status_code, "exit", payload["ip"])
except (httpx.HTTPError, ValueError) as error:
    raise SystemExit(f"Check failed: {type(error).__name__}") from None

Запустите python httpx_check.py. Скрипт выводит HTTP-код и значение поля ip, полученное от echo-сервиса. Это адрес, который увидел сервис в данном запросе; он не подтверждает страну выхода или доступность другого сайта. Сначала убедитесь, что ответ имеет ожидаемый формат, затем переходите к одной разрешённой операции вашего приложения.

В примере отключены переходы по перенаправлениям и нет автоматических повторов. Тело читается частями; накопление прекращается, если декодированный ответ превышает 64 КиБ. Этот предел относится к памяти диагностического скрипта, а не к оплачиваемым сетевым байтам. Контекстные менеджеры закрывают ответ и клиент, в том числе после ошибки разбора JSON.

Используйте AsyncClient в асинхронной задаче

httpx_async_check.py — асинхронная проверкаpython
import asyncio
import json

import httpx

from proxy_settings import connection_settings

settings = connection_settings()


async def main():
    try:
        async with asyncio.timeout(20):
            async with httpx.AsyncClient(**settings) as client:
                async with client.stream("GET", "https://api.portproof.org/v1/echo-ip") as response:
                    response.raise_for_status()
                    body = bytearray()
                    async for chunk in response.aiter_bytes(chunk_size=8192):
                        if len(body) + len(chunk) > 65536:
                            raise ValueError("Echo response exceeds 64 KiB")
                        body.extend(chunk)
                    payload = json.loads(body)
                    if not isinstance(payload, dict) or not isinstance(payload.get("ip"), str):
                        raise ValueError("Expected an IP address in the echo response")
                    print("HTTP", response.status_code, "exit", payload["ip"])
    except (httpx.HTTPError, ValueError, TimeoutError) as error:
        raise SystemExit(f"Check failed: {type(error).__name__}") from None


if __name__ == "__main__":
    asyncio.run(main())

Запустите python httpx_async_check.py как отдельный процесс. Если цикл событий уже работает, вызывайте await main(), а не вложенный asyncio.run(). Настройки и пароль должны быть получены заранее. Ожидание человека у скрытого приглашения не входит в сетевой таймаут и не подходит для запуска по расписанию без оператора.

HTTPX отдельно ограничивает ожидание соединения, чтения, записи и свободного соединения в пуле. Таймаут чтения ограничивает ожидание очередных данных: медленная передача может длиться дольше этого значения. В асинхронном варианте asyncio.timeout дополнительно запрашивает отмену через двадцать секунд. Освобождение ресурсов может занять дополнительное время. Для синхронной задачи задайте общий срок выполнения в worker или планировщике.

Создавайте клиент на срок связанной работы и переиспользуйте его, закрывая после завершения. Клиент внутри каждой итерации создаёт лишние соединения. При параллельной обработке отдельно ограничьте очередь задач: размер пула соединений не заменяет предел объёма работы. Подробнее: таймауты HTTPX и асинхронные клиенты.

Что подтверждено локальной проверкой

Эти же примеры выполнялись 30 сентября 2026 года с Python 3.12.14, HTTPX 0.28.1 и httpcore 1.0.9. Локальный HTTP-прокси с тестовыми учётными данными создавал CONNECT-туннели к локальному HTTPS-серверу. Русская версия использует тот же исполняемый код. Проверка не обращалась к рабочему пулу и не измеряла его скорость.

  • Client и AsyncClient успешно авторизовались с пунктуацией в пароле; сервер назначения не получил пароль прокси или заголовок Authorization.
  • Конфликтующие настройки прокси в окружении не меняли явно выбранный маршрут.
  • Неверный пароль приводил к ProxyError после ответа 407, а недоверенный сертификат — к ConnectError.
  • Задержка чтения и общий асинхронный предел завершались соответствующими исключениями; закрытие ответа и клиента проверялось.

Отделите ошибку соединения от ответа сайта

ProxyError требует проверки шлюза и авторизации. Начните с разбора 407 либо ошибок CONNECT — на английском. HTTPStatusError после raise_for_status() относится к полученному HTTP-ответу; выясните, какой сервис его вернул. При ошибке сертификата проверяйте имя сайта, системное время и цепочку доверия, сохраняя проверку TLS.

Переиспользование соединения не означает смену выходного адреса при каждом вызове HTTPX. Параметры ротации и sticky-сессии задаются в имени пользователя шлюза. Sticky удерживает устройство, но его адрес может измениться. Сверяйте результат конкретного запроса; подробнее в руководстве по сессиям.

После подключения измерьте небольшой типичный запуск: полезные ответы, попытки, длительность и расход в кабинете. Повторять операции с побочными эффектами автоматически нельзя. Для выбора объёма используйте расчёт трафика — на английском, а для покупки сверяйте актуальные тарифы — на английском. Оба общих пула используют баланс в ГБ.

Допустимое использование

Используйте примеры для разрешённого тестирования, мониторинга и исследований с соблюдением правил сайтов и политики использования.

Следующий шаг

Прокси в HTTPX: Client и AsyncClient · Portproof