CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-python-socks

Proxy (SOCKS4, SOCKS5, HTTP CONNECT) client for Python

Pending
Overview
Eval results
Files

sync-api.mddocs/

Synchronous API

Blocking proxy implementations that return standard Python sockets. The synchronous API provides traditional socket-based proxy connectivity for threading-based applications and scripts that don't require asynchronous I/O.

Capabilities

Proxy Class

Main synchronous proxy client supporting SOCKS4, SOCKS5, and HTTP CONNECT protocols.

import socket
from typing import Optional

class Proxy:
    def __init__(
        self,
        proxy_type: ProxyType,
        host: str,
        port: int,
        username: Optional[str] = None,
        password: Optional[str] = None,
        rdns: Optional[bool] = None
    ): ...
    
    def connect(
        self,
        dest_host: str,
        dest_port: int,
        timeout: Optional[float] = None,
        **kwargs
    ) -> socket.socket: ...
    
    @property
    def proxy_host(self) -> str:
        """Get proxy host address."""
        ...
        
    @property  
    def proxy_port(self) -> int:
        """Get proxy port number."""
        ...
    
    @classmethod
    def create(cls, *args, **kwargs) -> 'Proxy':
        """Create proxy instance (deprecated, use __init__ directly)."""
        ...
        
    @classmethod
    def from_url(cls, url: str, **kwargs) -> 'Proxy':
        """Create proxy instance from URL."""
        ...
    
    @property
    def proxy_host(self) -> str: ...
    
    @property
    def proxy_port(self) -> int: ...
    
    @classmethod
    def create(cls, *args, **kwargs) -> 'Proxy': ...
    
    @classmethod
    def from_url(cls, url: str, **kwargs) -> 'Proxy': ...

Constructor Parameters:

  • proxy_type: Protocol type (ProxyType.SOCKS4, SOCKS5, or HTTP)
  • host: Proxy server hostname or IP address
  • port: Proxy server port number
  • username: Optional username for proxy authentication
  • password: Optional password for proxy authentication
  • rdns: Optional remote DNS resolution flag (SOCKS5 only)

Connect Parameters:

  • dest_host: Destination hostname or IP address to connect to
  • dest_port: Destination port number
  • timeout: Connection timeout in seconds (default: 60)
  • local_addr: Optional local address to bind to
  • _socket: Existing socket to use (deprecated)

Usage:

from python_socks import ProxyType
from python_socks.sync import Proxy
import socket

# Create proxy instance
proxy = Proxy(
    proxy_type=ProxyType.SOCKS5,
    host='127.0.0.1',
    port=1080,
    username='user',
    password='pass'
)

# Connect through proxy
sock = proxy.connect(
    dest_host='example.com',
    dest_port=80,
    timeout=30
)

# Use the socket normally
sock.send(b'GET / HTTP/1.1\r\nHost: example.com\r\n\r\n')
response = sock.recv(4096)
print(response.decode())
sock.close()

URL-Based Proxy Creation

Create proxy instances from URL strings.

from python_socks.sync import Proxy

# Various URL formats
proxy1 = Proxy.from_url('socks5://127.0.0.1:1080')
proxy2 = Proxy.from_url('socks4://user:pass@proxy.example.com:1080')
proxy3 = Proxy.from_url('http://proxy-server:8080')

# Connect through URL-created proxy
sock = proxy1.connect('httpbin.org', 443)

Proxy Properties

Access proxy server information.

from python_socks.sync import Proxy

proxy = Proxy.from_url('socks5://proxy.example.com:1080')

print(f"Proxy host: {proxy.proxy_host}")  # proxy.example.com
print(f"Proxy port: {proxy.proxy_port}")  # 1080

ProxyChain Class (Deprecated)

Chain multiple proxies together for layered connections.

class ProxyChain:
    def __init__(self, proxies: Iterable[Proxy]): ...
    
    def connect(
        self,
        dest_host: str,
        dest_port: int,
        timeout: Optional[float] = None
    ) -> socket.socket: ...

Note: ProxyChain is deprecated and will be removed in future versions. Use V2 API for enhanced proxy chaining.

Usage:

import warnings
from python_socks.sync import Proxy, ProxyChain

# Suppress deprecation warning for example
warnings.filterwarnings('ignore', category=DeprecationWarning)

# Create proxy chain
proxy1 = Proxy.from_url('socks5://first-proxy:1080')
proxy2 = Proxy.from_url('http://second-proxy:8080')

chain = ProxyChain([proxy1, proxy2])

# Connect through proxy chain
sock = chain.connect('example.com', 80)

Advanced Usage Examples

SSL/TLS Connections Through Proxy

import ssl
from python_socks.sync import Proxy

# Create proxy and connect
proxy = Proxy.from_url('socks5://proxy.example.com:1080')
sock = proxy.connect('secure-api.example.com', 443)

# Wrap socket with SSL
context = ssl.create_default_context()
secure_sock = context.wrap_socket(
    sock,
    server_hostname='secure-api.example.com'
)

# Make HTTPS request
request = (
    b'GET /api/data HTTP/1.1\r\n'
    b'Host: secure-api.example.com\r\n'
    b'Connection: close\r\n\r\n'
)
secure_sock.send(request)
response = secure_sock.recv(4096)
secure_sock.close()

Custom Socket Configuration

import socket
from python_socks.sync import Proxy

proxy = Proxy.from_url('socks5://proxy.example.com:1080')

# Connect with local address binding
sock = proxy.connect(
    dest_host='example.com',
    dest_port=80,
    local_addr=('192.168.1.100', 0)  # Bind to specific local IP
)

# Configure socket options
sock.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)
sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)

Error Handling and Retry Logic

import time
from python_socks import ProxyError, ProxyTimeoutError, ProxyConnectionError
from python_socks.sync import Proxy

def robust_proxy_connect(proxy_url, dest_host, dest_port, max_retries=3):
    """Connect with comprehensive error handling."""
    
    for attempt in range(max_retries):
        try:
            proxy = Proxy.from_url(proxy_url)
            return proxy.connect(dest_host, dest_port, timeout=30)
            
        except ProxyConnectionError as e:
            print(f"Connection failed (attempt {attempt + 1}): {e}")
            if attempt < max_retries - 1:
                time.sleep(2 ** attempt)  # Exponential backoff
            else:
                raise
                
        except ProxyTimeoutError:
            print(f"Timeout (attempt {attempt + 1})")
            if attempt < max_retries - 1:
                continue
            else:
                raise
                
        except ProxyError as e:
            # Don't retry authentication or protocol errors
            print(f"Proxy error: {e} (code: {e.error_code})")
            raise

# Usage
try:
    sock = robust_proxy_connect(
        'socks5://user:pass@proxy.example.com:1080',
        'api.example.com',
        443
    )
    print("Connected successfully!")
    sock.close()
except Exception as e:
    print(f"All connection attempts failed: {e}")

Multiple Proxy Protocols

from python_socks import ProxyType
from python_socks.sync import Proxy

def try_multiple_proxies(proxy_configs, dest_host, dest_port):
    """Try multiple proxy configurations until one succeeds."""
    
    for config in proxy_configs:
        try:
            if isinstance(config, str):
                proxy = Proxy.from_url(config)
            else:
                proxy = Proxy(**config)
                
            sock = proxy.connect(dest_host, dest_port)
            return sock, config
            
        except Exception as e:
            print(f"Failed with {config}: {e}")
            continue
    
    raise ConnectionError("All proxy configurations failed")

# Configuration list
proxy_configs = [
    'socks5://primary-proxy:1080',
    'http://backup-proxy:8080',
    {
        'proxy_type': ProxyType.SOCKS4,
        'host': 'legacy-proxy.example.com',
        'port': 1080
    }
]

try:
    sock, used_config = try_multiple_proxies(
        proxy_configs,
        'example.com',
        80
    )
    print(f"Connected using: {used_config}")
    sock.close()
except ConnectionError as e:
    print(f"Could not connect: {e}")

Context Manager Pattern

from contextlib import contextmanager
from python_socks.sync import Proxy

@contextmanager
def proxy_connection(proxy_url, dest_host, dest_port, **kwargs):
    """Context manager for proxy connections."""
    proxy = Proxy.from_url(proxy_url)
    sock = None
    try:
        sock = proxy.connect(dest_host, dest_port, **kwargs)
        yield sock
    finally:
        if sock:
            sock.close()

# Usage
with proxy_connection('socks5://proxy:1080', 'example.com', 80) as sock:
    sock.send(b'GET / HTTP/1.1\r\nHost: example.com\r\n\r\n')
    response = sock.recv(4096)
    print(response.decode())

Protocol-Specific Notes

SOCKS4 Protocol

  • Supports IPv4 addresses only
  • No authentication (username/password ignored)
  • Optional userid field (passed as username)
  • SOCKS4a variant supports domain names

SOCKS5 Protocol

  • Supports IPv4, IPv6, and domain names
  • Multiple authentication methods (no auth, username/password)
  • Remote DNS resolution controlled by rdns parameter
  • Full RFC 1928 compliance

HTTP CONNECT Protocol

  • Tunneling through HTTP proxies
  • Basic authentication support
  • Works with any TCP protocol over the tunnel
  • Supports both HTTP and HTTPS proxy servers

Install with Tessl CLI

npx tessl i tessl/pypi-python-socks

docs

async-api.md

core-api.md

index.md

sync-api.md

v2-api.md

tile.json