Skip to content
Async Python HTTP

How to use proxies with Python HTTPX and aiohttp

In HTTPX, pass the proxy URL when you create the client: httpx.AsyncClient(proxy="http://USERNAME:PASSWORD@HOST:PORT"). In aiohttp, pass it per request: session.get(url, proxy="http://USERNAME:PASSWORD@HOST:PORT").

What you need

Async clients let one Python process keep hundreds of requests in flight, which pairs well with CleanProxies ISP proxies (unlimited bandwidth and threads) and with rotating residential pools. The proxy syntax differs between the two libraries, and HTTPX changed it in version 0.28.
  • An active CleanProxies plan: static ISP proxies for fixed US IPs, or rotating residential / mobile proxies for pools. The trial works too.
  • Your credential line from the dashboard's proxy manager: host (or IP), port, username and password.
  • Python 3.9 or later.
  • pip install httpx (add "httpx[socks]" for SOCKS5) and/or pip install aiohttp (add aiohttp-socks for SOCKS5).

New to proxies? For the overview, read Using proxies with cURL, Python and Node.js and Best residential proxies for web scraping. This guide goes deeper on Python HTTPX & aiohttp only.

Your CleanProxies credentials

Every CleanProxies product works over HTTP(S) and SOCKS5. This is what the dashboard gives you.
ProductLine in your dashboardNotes
Static ISP proxiesIP:PORT:USER:PASSOne line per dedicated IP. With IP whitelisting turned on, the line is just IP:PORT and no password is sent.
Rotating residential and mobileHOST:PORT:USER:PASSGenerated in the proxy manager. The username carries the location and session you pick, so generate a new list to change them.

Most tools want the same details as a URL: http://USERNAME:PASSWORD@HOST:PORT for HTTP(S) or socks5://USERNAME:PASSWORD@HOST:PORT for SOCKS5. The examples on this page use those placeholders; copy the host, port, username and password from your CleanProxies dashboard. To convert a whole list at once, paste it into the proxy list formatter.

How to set up CleanProxies in Python HTTPX & aiohttp

  1. 1

    Pick the library

    HTTPX has both sync and async clients and an API close to Requests; aiohttp is async-only and very fast for large crawls.
  2. 2

    Build the proxy URL

    Use http://USERNAME:PASSWORD@HOST:PORT for HTTP(S) or socks5://USERNAME:PASSWORD@HOST:PORT for SOCKS5.
  3. 3

    Attach it

    HTTPX: proxy= on the client. aiohttp: proxy= on each request, or a SOCKS connector on the session.
  4. 4

    Limit concurrency

    Use an asyncio.Semaphore so you control how many requests hit each target at once.

HTTPX proxy example

HTTPX 0.28 removed the old proxies= argument. Use proxy= for a single proxy, or mounts= to route different URL patterns through different proxies.

AsyncClient with an HTTP(S) proxyPython
import asyncio
import httpx

PROXY = "http://USERNAME:PASSWORD@HOST:PORT"

async def main():
    async with httpx.AsyncClient(proxy=PROXY, timeout=30) as client:
        r = await client.get("https://api.ipify.org")
        print(r.text)

asyncio.run(main())
SOCKS5 (pip install "httpx[socks]")Python
client = httpx.Client(proxy="socks5://USERNAME:PASSWORD@HOST:PORT", timeout=30)
print(client.get("https://api.ipify.org").text)

aiohttp proxy example

aiohttp takes HTTP(S) proxies per request (or as a session default). Put the credentials in the proxy URL: aiohttp 3.14 deprecated the separate proxy_auth= argument. For SOCKS5, the aiohttp-socks connector routes the whole session.

HTTP(S) proxyPython
import asyncio
import aiohttp

async def main():
    async with aiohttp.ClientSession(timeout=aiohttp.ClientTimeout(total=30)) as session:
        async with session.get(
            "https://api.ipify.org",
            proxy="http://USERNAME:PASSWORD@HOST:PORT",
        ) as r:
            print(await r.text())

asyncio.run(main())
SOCKS5 with aiohttp-socksPython
from aiohttp_socks import ProxyConnector

connector = ProxyConnector.from_url("socks5://USERNAME:PASSWORD@HOST:PORT", rdns=True)
async with aiohttp.ClientSession(connector=connector) as session:
    async with session.get("https://api.ipify.org") as r:
        print(await r.text())

rdns=True makes the proxy resolve hostnames, so DNS lookups don't leave from your own server.

Bounded concurrency across many proxies

One client per ISP proxy, capped with a semaphorePython
import asyncio
import httpx

PROXIES = ["http://USER1:PASS1@IP1:PORT", "http://USER2:PASS2@IP2:PORT"]
URLS = [f"https://example.com/item/{i}" for i in range(100)]

async def main():
    clients = [httpx.AsyncClient(proxy=p, timeout=30) for p in PROXIES]
    limit = asyncio.Semaphore(20)

    async def fetch(i, url):
        async with limit:
            r = await clients[i % len(clients)].get(url)
            return r.status_code

    print(await asyncio.gather(*(fetch(i, u) for i, u in enumerate(URLS))))
    await asyncio.gather(*(c.aclose() for c in clients))

asyncio.run(main())

Static ISP vs rotating residential in Python HTTPX & aiohttp

Both products use the same setup. What changes is how long an IP stays with you.

Static ISP proxies

Give each ISP proxy its own client: the client pools connections to one dedicated US IP, and cookies stay with the account that IP serves.

Static ISP ProxiesAs low as $0.75/IP

Rotating residential proxies

A client keeps connections alive, so requests can share an exit IP even on a rotating line. Create short-lived clients (or send Connection: close) when you need a new IP per request; use a sticky list for flows that must stay put.

Rotating Residential ProxiesAs low as $0.63/GB

Verify your exit IP

Run the first HTTPX example: it prints the exit IP. In aiohttp, compare await r.text() from https://api.ipify.org with and without the proxy= argument.

Open What is my IP? through the proxy to see the address and headers a website receives, or paste up to ten lines into the free proxy checker to test connectivity, latency and exit IP before you start.

Troubleshooting Python HTTPX & aiohttp proxy errors

ProblemLikely causeFix
TypeError: unexpected keyword argument 'proxies'HTTPX 0.28 removed proxies=.Use proxy= (one proxy) or mounts= (per-pattern routing).
407 Proxy Authentication RequiredWrong credentials, or a password with @ or : that broke the proxy URL.Put the credentials in the proxy URL passed as proxy=; URL-encode special characters.
Using SOCKS proxy, but the 'socksio' package is not installedHTTPX SOCKS extra missing.pip install "httpx[socks]".
Many timeouts under loadToo many concurrent requests per IP for the target.Lower the semaphore, add retries with backoff, and spread work across more IPs.
DNS lookups leak over SOCKS5Local resolution in the connector.Set rdns=True in aiohttp-socks.

Still stuck? Our 24/7 support team answers fast: contact us with the error and the line you used (leave the password out).

Python HTTPX & aiohttp proxy FAQs

HTTPX does by default (trust_env=True). aiohttp only does when you create the session with trust_env=True. An explicit proxy argument is clearer and works the same everywhere.

Get CleanProxies for Python HTTPX & aiohttp

Super clean US ISP IPs from $0.75/IP with unlimited bandwidth, rotating residential from $0.63/GB and mobile from $0.79/GB. Instant delivery, 99.9% uptime and 24/7 support.