Integrations · Beginner

How to use proxies with Python requests, httpx and aiohttp

Three lines of configuration per library, then the same username syntax everywhere: country, city and session live in the proxy URL, so one gateway serves every job.

3 min read 6 sections Updated Published

The proxy URL#

Every Python HTTP library takes a proxy as a URL. With ProxShift the URL carries your credentials and the targeting parameters in the username; the hostname is the gateway and the port picks the protocol.

Proxy URLs
# Rotating: a new United States household on every new connection
http://USER-cc-us:[email protected]:9000

# Sticky: one Berlin household held for 30 minutes under the id "job42"
http://USER-cc-de-city-berlin-sid-job42-ttl-30m:[email protected]:9000

# SOCKS5 with remote DNS (socks5h), same parameters
socks5h://USER-cc-us:[email protected]:9001

requests#

Pass the same URL for http and https; requests uses CONNECT for HTTPS destinations automatically. A Session reuses connections, which keeps you on the same exit until the connection closes; use one Session per sticky job and plain requests.get calls when you want a fresh exit per request.

requests
import requests

PROXY = "http://USER-cc-us:[email protected]:9000"
proxies = {"http": PROXY, "https": PROXY}

# One request, one exit
r = requests.get("https://api.ipify.org", proxies=proxies, timeout=30)
print(r.text)

# A sticky flow: same exit for every request of this session
sticky = "http://USER-cc-de-city-berlin-sid-cart42-ttl-15m:[email protected]:9000"
s = requests.Session()
s.proxies = {"http": sticky, "https": sticky}
s.get("https://example.com/product/1", timeout=30)
s.post("https://example.com/cart", json={"id": 1}, timeout=30)

httpx#

httpx takes a single proxy= argument (older versions: proxies=). It supports HTTP/2 to the destination through the CONNECT tunnel and works the same way in async code.

httpx
import httpx

PROXY = "http://USER-cc-us:[email protected]:9000"

with httpx.Client(proxy=PROXY, timeout=30) as client:
    print(client.get("https://api.ipify.org").text)

# async, one sticky exit per task
import asyncio

async def fetch(sid: str, url: str) -> str:
    proxy = f"http://USER-cc-us-sid-{sid}-ttl-10m:[email protected]:9000"
    async with httpx.AsyncClient(proxy=proxy, timeout=30) as client:
        return (await client.get(url)).text

asyncio.run(fetch("task1", "https://api.ipify.org"))

aiohttp#

aiohttp takes the proxy per request or per session and speaks HTTP proxies natively; SOCKS5 needs the aiohttp-socks connector.

aiohttp
import aiohttp, asyncio

PROXY = "http://USER-cc-us:[email protected]:9000"

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

asyncio.run(main())

Rotation, keep-alive and retries#

  • A new TCP connection means a new exit. requests.get without a Session opens one per call; a Session or an httpx Client keeps connections alive and therefore keeps the exit until the pool recycles it.
  • Force a fresh exit inside a session by changing the -sid- value; force one per request by sending Connection: close.
  • Retry once on 403, 429 and connection errors: on a rotating gateway the retry is a different visitor. Never retry across exits in the middle of a sticky flow.
  • Set timeouts to the exit type: 15 s connect and 45 s read for residential, more for mobile.

Saving gigabytes#

Residential traffic is billed per GB in both directions. Ask for compressed responses (Accept-Encoding: gzip, br is on by default in these libraries), prefer JSON endpoints to HTML, and never download images, fonts or media unless they are the data. A 350 KB page is cheap; a 4 MB page with assets is not.

Questions people ask#

Why do I keep getting the same IP with requests?

A Session reuses the TCP connection, and the exit is chosen per connection. Use plain requests.get calls, send Connection: close, or change the -sid- value to get a new exit.

Do I need a different proxy for HTTPS sites?

No. The same http:// proxy URL handles HTTPS destinations through a CONNECT tunnel; TLS runs end to end between your code and the site.

Can I use the same code for mobile proxies?

Yes: replace res.proxshift.com with mob.proxshift.com. Ports, credentials and parameters are identical.

Ready when you are

Run it for real.

Create an account, top up $20 and paste the endpoint from this guide into your tool. Traffic you buy never expires.