Integrations menu
Developer guide

Python Requests Proxy Setup

To send Python requests through a proxy, pass a proxies dictionary with the same proxy URL under both keys: requests.get(url, proxies={"http": PROXY, "https": PROXY}), where PROXY = "http://<login>:<password>@gate.proxyfield.io:7000". ProxyField residential proxies for Python requests cost from $1.95/GB ($2.95/GB for 1 GB), with a 99.6% success rate, according to our service data, and the gateway gives you a new IP on every request, so you don't need a proxy list. Start with the Easy Trial: 1 GB for $2.95, no subscription, and the traffic never expires.

residential IPs
412M+
from, traffic never expires
$1.95/GB
Easy Trial
1 GB for $2.95
gate.proxyfield.io:7000
What goes in requests
requests settingProxyField value
proxies (both keys){"http": PROXY, "https": PROXY} with PROXY = "http://<login>-country-us-city-new_york:<password>@gate.proxyfield.io:7000"; HTTP, HTTPS and SOCKS5 run on the same host and port
Username<login>-country-us-city-new_york; the optional keys are -country-<cc>, -region-<region>, -city-<city>, -session-<id> and -ttl-<seconds> (30 to 129,600 s, 20 min when ttl is left out); add -mobile or -dc right after the login for mobile or rotating datacenter IPs (-dc takes the country only)
Passwordyour ProxyField password; encode special characters with quote() in the URL
SOCKS5socks5h:// with the same username and password on gate.proxyfield.io:7000 (needs requests[socks]), so the gateway resolves the site's name
No passwordadd your server's IP to the allowlist (up to 100 IPv4 addresses), then http://gate.proxyfield.io:<port>, where <port> is the port you set up in the dashboard
IP behavioura new IP on every request, or one IP for 30 s to 36 h with -session-<id>-ttl-<seconds>; no proxy list needed
Threadsunlimited concurrent threads
Headersthe gateway adds no Via, X-Forwarded-For or Forwarded header; the headers requests sends pass through; your Proxy-Authorization is removed before the request goes to the site
Credentialsin your ProxyField account, with the allowlist and the configurator (it generates as many proxy lines as you need); the examples read the login from environment variables, so it stays out of your code

Set up requests with ProxyField

  1. Put your ProxyField login and password in environment variables.
  2. Build the proxy URL http://<login>-country-us-city-new_york:<password>@gate.proxyfield.io:7000.
  3. Pass the same URL under both keys of proxies, or once with session.proxies.update().
  4. Request https://api.ipify.org: a different IP on each call means rotation works.

A Session with the proxy set once, with a New York exit IP.

Python
import requests

PROXY = "http://<login>-country-us-city-new_york:<password>@gate.proxyfield.io:7000"
s = requests.Session()
s.proxies.update({"http": PROXY, "https": PROXY})
print(s.get("https://api.ipify.org", timeout=30).text)

The library's own page on proxies: Advanced Usage: Proxies (Requests docs).

Mobile 5G/4G proxies cost $3.45/GB for 1 GB down to $2.45/GB from 1,000 GB, on the same gateway and the same balance.

Written for Python 3.10+ and requests 2.32.

On this page 11 sections

1. The basic request through a proxy

Python
import os
import requests

PROXY = f"http://{os.environ['PROXY_USER']}:{os.environ['PROXY_PASS']}@gate.proxyfield.io:7000"
proxies = {"http": PROXY, "https": PROXY}

r = requests.get("https://api.ipify.org", proxies=proxies, timeout=30)
print(r.text)  # the proxy's IP, not your server's

The keys of proxies are the schemes of the URLs you request: "https" is used for every https:// URL and "http" for every http:// URL. The value is how requests reaches the proxy, so it starts with http:// in both keys. That does not weaken HTTPS: requests opens a tunnel through the proxy with CONNECT, and TLS runs from your code to the site inside it. A dictionary with only an "http" key leaves every https:// URL on your own IP.

POST, PUT and every other method take the same argument:

Python
r = requests.post("https://httpbin.org/post", json={"q": "test"}, proxies=proxies, timeout=30)

2. Username and password

Put the login in the proxy URL, as above. Encode special characters in the password first:

Python
from urllib.parse import quote

PROXY = f"http://{quote(user, safe='')}:{quote(password, safe='')}@gate.proxyfield.io:7000"

requests.auth.HTTPProxyAuth is not a substitute for HTTPS URLs: it adds the Proxy-Authorization header to the request itself, and for https:// URLs that request travels inside the encrypted tunnel, where the proxy never sees it. The result is a 407 Proxy Authentication Required error. Credentials in the URL are sent when the tunnel is opened, so they work for both schemes. More on the error: HTTP Error 407 Proxy Authentication Required.

With your server's IP on the ProxyField allowlist, drop the login entirely and use the port you set up in the dashboard: PROXY = "http://gate.proxyfield.io:<port>", where <port> is that port. Proxy Authentication compares the two methods.

3. Sessions and environment variables

A Session keeps cookies and reuses connections. Give it the proxy once:

Python
s = requests.Session()
s.proxies.update(proxies)
r = s.get("https://ipinfo.io/json", timeout=30)
print(r.json()["country"])

One catch: if HTTP_PROXY or HTTPS_PROXY is set in the environment, requests uses it ahead of s.proxies. Either pass proxies= on each call, or switch the environment off for the session with s.trust_env = False.

The environment is also the way to proxy a script you don't want to edit:

Shell
export HTTPS_PROXY="http://<login>:<password>@gate.proxyfield.io:7000"
export HTTP_PROXY="$HTTPS_PROXY"
export NO_PROXY="localhost,127.0.0.1"
python3 script.py

requests reads HTTP_PROXY, HTTPS_PROXY, ALL_PROXY and NO_PROXY (upper or lower case); without them it falls back to the operating system's proxy settings. Setting these variables on each system: Set a Proxy From the Command Line.

4. Rotating residential proxies with requests

You don't need a list of IPs or a rotator. ProxyField's gateway gives a new IP on every request, so the same proxy URL rotates on its own:

Python
import os
import requests

PROXY = f"http://{os.environ['PROXY_USER']}:{os.environ['PROXY_PASS']}@gate.proxyfield.io:7000"
proxies = {"http": PROXY, "https": PROXY}

for _ in range(3):
    print(requests.get("https://api.ipify.org", proxies=proxies, timeout=30).text)  # a new IP each time

requests.get opens a new connection each time. A Session keeps one HTTPS tunnel open for repeated requests to the same site, which can keep the same IP for those requests; use plain requests.get when every request needs its own IP, and a session when it should stay put. An open HTTPS connection keeps one exit IP until it closes.

For one IP across a login and the pages behind it, use a sticky session in the username, which holds the IP for 30 s to 36 h. Region, session and session time go in the same username: -region-<region>, -session-<id> and -ttl-<seconds> (30 to 129,600 seconds, 20 minutes by default), as in <login>-country-us-region-new_york-city-new_york-session-he9f2qga-ttl-600; every part after the login is optional. Residential is the default; add -mobile after the login for mobile IPs: <login>-mobile-country-us.

To spread work across countries, build the proxy per country:

Python
def proxies_for(country: str) -> dict:
    url = f"http://{os.environ['PROXY_USER']}-country-{country}:{os.environ['PROXY_PASS']}@gate.proxyfield.io:7000"
    return {"http": url, "https": url}

for c in ("us", "gb", "de"):
    print(c, requests.get("https://ipinfo.io/json", proxies=proxies_for(c), timeout=30).json()["country"])

The -country- key follows the example <login>-country-us-city-new_york. Country keys outside the US: the two-letter country code in lowercase, as in -country-de.

5. Different proxies for different sites

A key can name a scheme and a host, so one dictionary can route sites differently:

Python
proxies = {
    "https://example.com": proxies_for("us")["https"],  # this site through a US IP
    "https": proxies_for("gb")["https"],                  # every other https:// URL through a UK IP
}

The more specific key wins. To keep a host off the proxy, list it in NO_PROXY.

6. SOCKS5 with requests

Shell
pip install "requests[socks]"
Python
PROXY = "socks5h://<login>:<password>@gate.proxyfield.io:7000"
proxies = {"http": PROXY, "https": PROXY}

Without the extra package, requests stops with InvalidSchema: Missing dependencies for SOCKS support. socks5h resolves hostnames at the proxy; socks5 resolves them on your machine. SOCKS5 takes the same username and password. HTTP is enough for web pages; SOCKS5 proxies explains when SOCKS5 is worth it.

7. Retries, timeouts and TLS

Mount an adapter with a retry policy, and always set a timeout:

Python
from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry

retry = Retry(total=3, backoff_factor=1, status_forcelist=[429, 500, 502, 503, 504])
s = requests.Session()
s.mount("https://", HTTPAdapter(max_retries=retry))
s.mount("http://", HTTPAdapter(max_retries=retry))
r = s.get("https://api.ipify.org", proxies=proxies, timeout=(10, 30))

In rotating mode each retry is a new request, so it goes out from a new IP. Treat a 403 as a block rather than a glitch: slow down, check the request headers, and don't retry the same request in a loop; 403 Forbidden When Scraping Through a Proxy lists the causes. Keep verify=True (the default): the site's certificate is checked end to end through the tunnel, so there is no need to switch verification off for the proxy.

Check and debug

  1. requests.get("https://api.ipify.org", proxies=proxies).text prints the exit IP; it should not be your server's.
  2. Still your own IP? The "https" key is missing or misspelled, NO_PROXY matches the host, or a session's environment overrides it.
  3. A ProxyError with an authentication error (407 in most proxies) means the login was not accepted: check the credentials and encode special characters.
  4. ConnectTimeout points to the port or a firewall: allow outgoing port 7000.
  5. Test a proxy line without code with the proxy checker.

Gateway error messages: 407 Proxy Authentication Required for a wrong login or password, an IP not on the allowlist or a malformed location, 402 Payment Required when no traffic is left and 502 Bad Gateway when no exit could be connected; a restricted site gets no separate response, and a 403 comes from the site itself. Common error codes are explained in proxy errors. Some site categories are restricted to protect the network, including financial and government services. Our 24/7 live chat helps with setup and integration.

Which proxies to use with requests

What your script doesProxyPrice
Collect public pages at scaleRotating residentialfrom $1.95/GB
Check what mobile users seeMobile 5G/4Gfrom $2.45/GB ($3.45 for 1 GB)
Call an API that allowlists one fixed IPDedicated ISPfrom $2.29 per IP per 30 days
High-volume jobs on sites that accept datacenter IPsDatacenter$0.29/GB down to $0.22/GB

requests is one of several Python clients; httpx, aiohttp and urllib are covered on Python proxy setup, and crawls of many pages on Scrapy proxy setup. Use ProxyField for lawful work such as public web data collection, price and SEO monitoring and testing, within our acceptable use policy.

Get started

Start with the Easy Trial: 1 GB for $2.95, with no minimum purchase and no subscription. The traffic never expires and all purchases are final. See pricing per GB.

Python Requests Proxy Setup FAQ

How do I use rotating residential proxies with Python requests?

ProxyField rotating residential proxies work with Python requests from $1.95/GB ($2.95 for 1 GB): pass proxies={"http": PROXY, "https": PROXY} with PROXY = "http://<login>:<password>@gate.proxyfield.io:7000". The gateway gives a new IP on every request, so there is no list to rotate.

How do I pass a proxy username and password in Python requests?

Put them in the proxy URL: http://<login>:<password>@gate.proxyfield.io:7000, under both the "http" and "https" keys. Encode special characters with urllib.parse.quote(password, safe="") first.

Why doesn't HTTPProxyAuth work for HTTPS URLs in requests?

HTTPProxyAuth adds its header to the request itself, and for https:// URLs that request travels inside the encrypted tunnel, where the proxy can't see it. The proxy answers 407; put the credentials in the proxy URL instead.

What do the http and https keys in the proxies dictionary mean?

They name the scheme of the URL you request, not the proxy's protocol. Set both to the same http:// proxy URL; leave out "https" and every https:// request goes out from your own IP.

How do I set a proxy on a requests Session?

Call s.proxies.update({"http": PROXY, "https": PROXY}) once. If HTTP_PROXY or HTTPS_PROXY is set in the environment, it wins over s.proxies, so pass proxies= per call or set s.trust_env = False.

Why is my Python requests proxy still showing my real IP?

Usually the "https" key is missing or misspelled, so https:// URLs skip the proxy, or NO_PROXY matches the host. Print requests.get("https://api.ipify.org", proxies=proxies).text to see which IP the site gets.

Why are my Python requests proxies not working?

A ProxyError with an authentication error (407 in most proxies) means the login was rejected, a timeout points to a blocked port, and a 403 from the site means the site refused the request. Check the credentials, allow outgoing port 7000, and test the same line with the proxy checker.

Which environment variables does requests read for proxies?

HTTP_PROXY, HTTPS_PROXY, ALL_PROXY and NO_PROXY, in upper or lower case; without them it uses the operating system's proxy settings. Set trust_env = False on a session to ignore them all.

Can I use different proxies for different sites in requests?

Yes. A key can name a scheme and host, such as "https://example.com", next to the general "https" key; the more specific key wins. Hosts in NO_PROXY skip the proxy.

How do I send a POST request through a proxy with requests?

The same way as a GET: requests.post(url, json=data, proxies=proxies, timeout=30). Every method takes the proxies argument, and a session's proxies apply to all of them.

Show 8 more questionsShow fewer questions

Why does requests say "Missing dependencies for SOCKS support"?

SOCKS needs an extra package that requests doesn't install by default. Run pip install "requests[socks]", then use a socks5h:// proxy URL.

How do I use TLS in Python Requests through a proxy?

Nothing changes: requests opens a tunnel through the proxy and runs TLS to the site inside it, checking the site's certificate as usual. Keep verify=True, the default.

Can I use Python requests retries with a proxy?

Yes. Mount an HTTPAdapter with a urllib3 Retry policy on the session and pass the proxies as usual. In rotating mode each retry is a new request and gets a new IP.

Should Python requests retry a 403 response?

Not in a tight loop. A 403 usually means the site refused that request, so retrying it unchanged mostly repeats the refusal; slow down, check your headers, and retry later from a new IP if the site allows the access.

How do I check that requests goes through the proxy?

Request https://api.ipify.org with your proxies and compare the IP with your server's; https://ipinfo.io/json also shows the country and city. Run it from the same session and environment as your script.

Can I use Python requests with an IP allowlist instead of a password?

Yes. Add your server's IP to the allowlist in your ProxyField account and use http://gate.proxyfield.io:<port> with no login, where <port> is the port you set up in the dashboard. It suits servers with a fixed IP; on a laptop whose IP changes, keep the username and password.

Is Python Requests the same as cURL?

No, but they do the same job: both are HTTP clients, one a Python library, the other a command-line tool. The same proxy URL works in both, so you can test a line with cURL and paste it into your script.

What is the purpose of using proxies with Python Requests?

To send your script's requests from other IPs and places: spreading many requests over many IPs, seeing a site as visitors in another country see it, or reaching an API that allows only one fixed IP.

Easy Trial: 1 GB for $2.95.

Try for the price of 1 GB, no subscription, traffic never expires.