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.
# 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]:9001requests#
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.
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.
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.
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.getwithout aSessionopens one per call; aSessionor an httpxClientkeeps 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 sendingConnection: 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.