# Python (requests, httpx, aiohttp)
Source: https://proxuno.com/docs/integration-python
Updated: 2026-08-20

Integrations

Use mobile, residential and static ISP proxies from Python with requests, httpx (sync and async) and aiohttp, including SOCKS5, sticky sessions, rotation and retries.

Updated 20 Aug 2026 1 min read API v1

### On this page

- [requests](#requests)
- [SOCKS5 with requests](#socks5-with-requests)
- [httpx](#httpx)
- [Async with httpx](#async-with-httpx)
- [aiohttp](#aiohttp)
- [Residential: rotating and sticky](#residential-rotating-and-sticky)
- [Rotate a mobile IP between batches](#rotate-a-mobile-ip-between-batches)
- [Common errors](#common-errors)

All examples read credentials from environment variables so they never end up in source control:

cURLCopy

```bash
export PROXY_URL="http://m_k3v9q2xa:Hq7Lr2Nw8Zt4Bc6D@fr.mobile.gw.proxuno.com:10421"
export PROXUNO_API_KEY="pxl_live_…"
```

## requests[#](#requests)

PythonCopy

```python
import os
import requests

proxy = os.environ["PROXY_URL"]
proxies = {"http": proxy, "https": proxy}

r = requests.get("https://api.ipify.org?format=json", proxies=proxies, timeout=(10, 30))
print(r.json())
```

- Use the same URL for both `http` and `https`: HTTPS targets are tunnelled through `CONNECT`, the proxy itself is reached over plain HTTP.
- Pass a `(connect, read)` timeout. Mobile links are slower to connect than data-centre proxies; 10 s connect / 30 s read is a safe start.
- Reuse a `requests.Session()` to keep connections open across requests.

### SOCKS5 with requests[#](#socks5-with-requests)

Requires the SOCKS extra: `pip install "requests[socks]"`.

PythonCopy

```python
proxy = "socks5h://m_k3v9q2xa:Hq7Lr2Nw8Zt4Bc6D@fr.mobile.gw.proxuno.com:20421"
r = requests.get("https://example.com", proxies={"http": proxy, "https": proxy}, timeout=(10, 30))
```

`socks5h` resolves hostnames on the proxy side, so DNS queries do not leak from your machine and geo-DNS answers match the proxy's country.

## httpx[#](#httpx)

PythonCopy

```python
import os
import httpx

with httpx.Client(proxy=os.environ["PROXY_URL"], timeout=httpx.Timeout(30, connect=10)) as client:
print(client.get("https://api.ipify.org?format=json").json())
```

`proxy=` is the httpx ≥ 0.26 argument (older versions use `proxies=`). For SOCKS5 install `httpx[socks]` and use a `socks5://` URL.

### Async with httpx[#](#async-with-httpx)

PythonCopy

```python
import asyncio, os
import httpx

URLS = [f"https://example.com/page/{i}" for i in range(1, 51)]

async def fetch(client: httpx.AsyncClient, sem: asyncio.Semaphore, url: str) -> int:
async with sem:
r = await client.get(url)
return r.status_code

async def main() -> None:
sem = asyncio.Semaphore(10)  # concurrency per proxy — see Limits & best practices
async with httpx.AsyncClient(proxy=os.environ["PROXY_URL"], timeout=30) as client:
codes = await asyncio.gather(*(fetch(client, sem, u) for u in URLS))
print(codes)

asyncio.run(main())
```

## aiohttp[#](#aiohttp)

PythonCopy

```python
import asyncio, os
import aiohttp

async def main() -> None:
timeout = aiohttp.ClientTimeout(total=45, connect=10)
async with aiohttp.ClientSession(timeout=timeout) as session:
async with session.get("https://api.ipify.org?format=json", proxy=os.environ["PROXY_URL"]) as r:
print(await r.json())

asyncio.run(main())
```

aiohttp only supports HTTP proxies natively; for SOCKS5 use the `aiohttp-socks` connector.

## Residential: rotating and sticky[#](#residential-rotating-and-sticky)

PythonCopy

```python
import secrets, requests

LOGIN, PASSWORD = "px4k2m9q7a", "Rb8Tn3Wq6Ys1Kd5P"
HOST = "resi.gw.proxuno.com:7000"

def resi_proxy(country: str = "eu", city: str | None = None, sticky_minutes: int | None = None) -> dict:
user = f"{LOGIN}-country-{country}"
if city:
user += f"-city-{city}"
if sticky_minutes:
user += f"-session-{secrets.token_hex(4)}-ttl-{sticky_minutes}"
url = f"http://{user}:{PASSWORD}@{HOST}"
return {"http": url, "https": url}

# new IP on every request
requests.get("https://example.com", proxies=resi_proxy("de"), timeout=30)

# same IP for up to 10 minutes
s = requests.Session()
s.proxies = resi_proxy("fr", "lyon", sticky_minutes=10)
```

## Rotate a mobile IP between batches[#](#rotate-a-mobile-ip-between-batches)

PythonCopy

```python
import os, time, requests

API = "https://proxuno.com/api/v1"
HEADERS = {"Authorization": f"Bearer {os.environ['PROXUNO_API_KEY']}"}

def rotate(proxy_id: int) -> str:
while True:
r = requests.post(f"{API}/proxies/{proxy_id}/rotate", headers=HEADERS, timeout=45)
if r.status_code == 429:
time.sleep(float(r.headers.get("Retry-After", 10)))
continue
r.raise_for_status()
return r.json()["data"]["ip"]

for batch in batches:          # your own work units
process(batch)
print("new IP:", rotate(1482))
```

Without an API key, call the proxy's rotation link instead: `requests.get(ROTATION_LINK, timeout=45)`.

## Common errors[#](#common-errors)

| Exception | Cause |
| --- | --- |
| `ProxyError: 407 Proxy Authentication Required` | Wrong credentials, expired proxy, or an unknown residential city flag. |
| `InvalidSchema: Missing dependencies for SOCKS support` | Install `requests[socks]`. |
| `ConnectTimeout` right after a rotation | The modem is reconnecting; retry after a few seconds. |
| `SSLError` on every HTTPS request | A corporate proxy or antivirus intercepts TLS on your side — not related to the proxy. |

Something unclear, outdated or wrong on this page? Tell us — documentation issues are fixed in the next release at the latest.

[Report an issue with this page](/contact?topic=support&subject=Documentation%20issue%3A%20Python%20(requests%2C%20httpx%2C%20aiohttp))
