Python-Socks
The python-socks package provides a core proxy client functionality for Python. It supports SOCKS4(a), SOCKS5(h), and HTTP CONNECT proxies, offering both synchronous and asynchronous (asyncio, trio, curio, anyio) APIs. It's often used internally by other HTTP client libraries like `aiohttp-socks` and `httpx-socks` rather than directly. The current version is 2.8.1, and it maintains an active release cadence.
Warnings
- gotcha Many users might try to use `python-socks` directly for HTTP/HTTPS proxying when higher-level libraries like `aiohttp-socks` or `httpx-socks` (which use `python-socks` internally) offer a more convenient and integrated API for common use cases.
- gotcha Using `socks5://` (local DNS resolution) instead of `socks5h://` (remote DNS resolution on the proxy) can lead to DNS leaks or failures if the proxy network requires remote DNS for hostname resolution.
- breaking Attempting to use `python-socks` with an async backend (e.g., asyncio, trio) without installing the corresponding optional dependency (e.g., `pip install python-socks[asyncio]`) will result in `ImportError` or `ModuleNotFoundError`.
- breaking This library explicitly requires Python 3.8 or newer. Using it with older Python versions will lead to syntax errors or compatibility issues.
Install
-
pip install python-socks -
pip install python-socks[asyncio] -
pip install python-socks[trio] -
pip install python-socks[curio] -
pip install python-socks[anyio]
Imports
- Proxy (sync)
from python_socks.sync import Proxy
- Proxy (asyncio)
from python_socks.async_.asyncio import Proxy
Quickstart
import ssl
import os
from python_socks.sync import Proxy
# Get proxy URL from environment variable, e.g., "socks5://user:password@127.0.0.1:1080"
proxy_url = os.environ.get('PYTHON_SOCKS_PROXY_URL', 'socks5://127.0.0.1:1080')
try:
proxy = Proxy.from_url(proxy_url)
# `connect` returns standard Python socket in blocking mode
sock = proxy.connect(dest_host='check-host.net', dest_port=443)
# Wrap socket for SSL/TLS if connecting to HTTPS
sock = ssl.create_default_context().wrap_socket(
sock=sock,
server_hostname='check-host.net'
)
request = (
b'GET /ip HTTP/1.1\r\n'
b'Host: check-host.net\r\n'
b'Connection: close\r\n\r\n'
)
sock.sendall(request)
response_parts = []
while True:
data = sock.recv(4096)
if not data:
break
response_parts.append(data)
full_response = b"".join(response_parts)
print("Received response through proxy:")
print(full_response.decode('utf-8', errors='ignore'))
except Exception as e:
print(f"An error occurred: {e}")
print("Ensure a SOCKS proxy is running and PYTHON_SOCKS_PROXY_URL environment variable is set correctly.")
print("Example: export PYTHON_SOCKS_PROXY_URL=\"socks5://user:pass@127.0.0.1:1080\"")
finally:
if 'sock' in locals() and sock:
sock.close()