Python SOCKS5 setup

How to use SOCKS5 proxies in Python Requests

Install requests[socks], pick socks5h for proxy-side DNS, encode credentials safely, and stop environment variables from hijacking the session.

Field notes Setup checks Updated 2026-06-11

Install SOCKS support first

Requests needs the SOCKS extra before socks5:// works. Without it, the proxy line can look correct and still fail before any traffic reaches the proxy.

python -m pip install "requests[socks]"

Use socks5h:// when DNS resolution should happen through the proxy, which is the safer default for scraping, and plain socks5:// only when resolving names locally is acceptable (RFC 1928).

import os
                        import requests
                        
                        proxy = (
                            'socks5h://'
                            f'{os.environ["PROXY_USER"]}:{os.environ["PROXY_PASS"]}'
                            '@proxynade.net:2555'
                        )
                        
                        session = requests.Session()
                        session.trust_env = False
                        session.proxies = {
                            'http': proxy,
                            'https': proxy,
                        }
                        
                        response = session.get('https://example.com', timeout=30)
                        print(response.status_code)

On a Proxynade pool, PROXY_USER is the expanded username that carries the routing options, for example rt97db6958d9-plan-volume-country-us-lifetime-30: the base username, a required plan token (volume, premium, or datacenter), an optional lowercase country code, and an optional rotation lifetime in minutes. Datacenter usernames carry a lifetime token only on a sticky session, and the password stays exactly as issued.

Use curl before debugging Python

Before debugging Python, run one check from curl with the same line. If curl fails too, the problem lives in the credentials or the route rather than in your code.

curl -x socks5h://USER:PASS@proxynade.net:2555 https://example.com -I
ErrorLikely causeFix
Missing dependencies for SOCKS supportPySocks is not installedInstall requests[socks].
407Proxy auth failedCheck account, balance, and encoded credentials.
DNS leakUsed socks5://Use socks5h://.
Works in curl, fails in appEnvironment proxy overrideSet session.trust_env = False.

Encode passwords with special characters

If the password contains @, :, #, ?, or spaces, encode it before building the proxy URL. Otherwise the URL parser can split the credential into the wrong fields.

from urllib.parse import quote
                        
                        user = quote(os.environ['PROXY_USER'], safe='')
                        password = quote(os.environ['PROXY_PASS'], safe='')
                        proxy = f'socks5h://{user}:{password}@proxynade.net:2555'

Bandwidth does not match response.content

len(response.content) is not the billed bandwidth. The proxy also counts request headers, connection setup, redirects, the difference between compressed and uncompressed transfer, failed requests, and retries, while your app only credits itself for the final useful payload. The gap between those two views is normal accounting, not the meter lying.

Cap retries, log status codes, and store the URL that caused each retry. Most wasted gigabytes come from one bad loop.

A safe Python session wrapper

Wrap proxy creation instead of rebuilding strings across the codebase, so encoding, DNS choice, timeouts, and environment isolation all live in one place. The Requests proxies docs cover the full session.proxies shape.

from urllib.parse import quote
                        import requests
                        
                        def proxied_session(user, password, host='proxynade.net', port=2555):
                            safe_user = quote(user, safe='')
                            safe_password = quote(password, safe='')
                            proxy = f'socks5h://{safe_user}:{safe_password}@{host}:{port}'
                        
                            session = requests.Session()
                            session.trust_env = False
                            session.proxies = {'http': proxy, 'https': proxy}
                            return session
                        
                        session = proxied_session(PROXY_USER, PROXY_PASS)
                        response = session.get('https://example.com', timeout=(10, 30))

The tuple timeout matters more than it looks: the first value caps connection setup and the second caps read time. Without both, one bad route can hold a worker until the queue looks dead.

What to log from Python

Log the proxy label, requested URL, final URL, status code, exception class, elapsed time, retry number, and response size, and keep raw credentials out of all of it. When a provider bill looks wrong later, this log is what tells you whether the app loop or the proxy meter created the gap.

Python SOCKS5 FAQ

Should I use socks5 or socks5h? Use socks5h when the proxy should resolve target DNS. That is the safer default for scraping.

Why does Requests ignore my proxy? Environment variables can override behavior. Set session.trust_env = False during controlled tests.

Can I use the same proxy for HTTP and HTTPS? Yes. Put the same SOCKS URL under both http and https keys.

Why does the bill exceed downloaded bytes? Requests only shows what your code receives. The proxy also sees setup, retries, redirects, and failed traffic.