0
# Synchronous API
1
2
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.
3
4
## Capabilities
5
6
### Proxy Class
7
8
Main synchronous proxy client supporting SOCKS4, SOCKS5, and HTTP CONNECT protocols.
9
10
```python { .api }
11
import socket
12
from typing import Optional
13
14
class Proxy:
15
def __init__(
16
self,
17
proxy_type: ProxyType,
18
host: str,
19
port: int,
20
username: Optional[str] = None,
21
password: Optional[str] = None,
22
rdns: Optional[bool] = None
23
): ...
24
25
def connect(
26
self,
27
dest_host: str,
28
dest_port: int,
29
timeout: Optional[float] = None,
30
**kwargs
31
) -> socket.socket: ...
32
33
@property
34
def proxy_host(self) -> str:
35
"""Get proxy host address."""
36
...
37
38
@property
39
def proxy_port(self) -> int:
40
"""Get proxy port number."""
41
...
42
43
@classmethod
44
def create(cls, *args, **kwargs) -> 'Proxy':
45
"""Create proxy instance (deprecated, use __init__ directly)."""
46
...
47
48
@classmethod
49
def from_url(cls, url: str, **kwargs) -> 'Proxy':
50
"""Create proxy instance from URL."""
51
...
52
53
@property
54
def proxy_host(self) -> str: ...
55
56
@property
57
def proxy_port(self) -> int: ...
58
59
@classmethod
60
def create(cls, *args, **kwargs) -> 'Proxy': ...
61
62
@classmethod
63
def from_url(cls, url: str, **kwargs) -> 'Proxy': ...
64
```
65
66
**Constructor Parameters:**
67
- `proxy_type`: Protocol type (ProxyType.SOCKS4, SOCKS5, or HTTP)
68
- `host`: Proxy server hostname or IP address
69
- `port`: Proxy server port number
70
- `username`: Optional username for proxy authentication
71
- `password`: Optional password for proxy authentication
72
- `rdns`: Optional remote DNS resolution flag (SOCKS5 only)
73
74
**Connect Parameters:**
75
- `dest_host`: Destination hostname or IP address to connect to
76
- `dest_port`: Destination port number
77
- `timeout`: Connection timeout in seconds (default: 60)
78
- `local_addr`: Optional local address to bind to
79
- `_socket`: Existing socket to use (deprecated)
80
81
**Usage:**
82
83
```python
84
from python_socks import ProxyType
85
from python_socks.sync import Proxy
86
import socket
87
88
# Create proxy instance
89
proxy = Proxy(
90
proxy_type=ProxyType.SOCKS5,
91
host='127.0.0.1',
92
port=1080,
93
username='user',
94
password='pass'
95
)
96
97
# Connect through proxy
98
sock = proxy.connect(
99
dest_host='example.com',
100
dest_port=80,
101
timeout=30
102
)
103
104
# Use the socket normally
105
sock.send(b'GET / HTTP/1.1\r\nHost: example.com\r\n\r\n')
106
response = sock.recv(4096)
107
print(response.decode())
108
sock.close()
109
```
110
111
### URL-Based Proxy Creation
112
113
Create proxy instances from URL strings.
114
115
```python
116
from python_socks.sync import Proxy
117
118
# Various URL formats
119
proxy1 = Proxy.from_url('socks5://127.0.0.1:1080')
120
proxy2 = Proxy.from_url('socks4://user:pass@proxy.example.com:1080')
121
proxy3 = Proxy.from_url('http://proxy-server:8080')
122
123
# Connect through URL-created proxy
124
sock = proxy1.connect('httpbin.org', 443)
125
```
126
127
### Proxy Properties
128
129
Access proxy server information.
130
131
```python
132
from python_socks.sync import Proxy
133
134
proxy = Proxy.from_url('socks5://proxy.example.com:1080')
135
136
print(f"Proxy host: {proxy.proxy_host}") # proxy.example.com
137
print(f"Proxy port: {proxy.proxy_port}") # 1080
138
```
139
140
### ProxyChain Class (Deprecated)
141
142
Chain multiple proxies together for layered connections.
143
144
```python { .api }
145
class ProxyChain:
146
def __init__(self, proxies: Iterable[Proxy]): ...
147
148
def connect(
149
self,
150
dest_host: str,
151
dest_port: int,
152
timeout: Optional[float] = None
153
) -> socket.socket: ...
154
```
155
156
**Note:** ProxyChain is deprecated and will be removed in future versions. Use V2 API for enhanced proxy chaining.
157
158
**Usage:**
159
160
```python
161
import warnings
162
from python_socks.sync import Proxy, ProxyChain
163
164
# Suppress deprecation warning for example
165
warnings.filterwarnings('ignore', category=DeprecationWarning)
166
167
# Create proxy chain
168
proxy1 = Proxy.from_url('socks5://first-proxy:1080')
169
proxy2 = Proxy.from_url('http://second-proxy:8080')
170
171
chain = ProxyChain([proxy1, proxy2])
172
173
# Connect through proxy chain
174
sock = chain.connect('example.com', 80)
175
```
176
177
## Advanced Usage Examples
178
179
### SSL/TLS Connections Through Proxy
180
181
```python
182
import ssl
183
from python_socks.sync import Proxy
184
185
# Create proxy and connect
186
proxy = Proxy.from_url('socks5://proxy.example.com:1080')
187
sock = proxy.connect('secure-api.example.com', 443)
188
189
# Wrap socket with SSL
190
context = ssl.create_default_context()
191
secure_sock = context.wrap_socket(
192
sock,
193
server_hostname='secure-api.example.com'
194
)
195
196
# Make HTTPS request
197
request = (
198
b'GET /api/data HTTP/1.1\r\n'
199
b'Host: secure-api.example.com\r\n'
200
b'Connection: close\r\n\r\n'
201
)
202
secure_sock.send(request)
203
response = secure_sock.recv(4096)
204
secure_sock.close()
205
```
206
207
### Custom Socket Configuration
208
209
```python
210
import socket
211
from python_socks.sync import Proxy
212
213
proxy = Proxy.from_url('socks5://proxy.example.com:1080')
214
215
# Connect with local address binding
216
sock = proxy.connect(
217
dest_host='example.com',
218
dest_port=80,
219
local_addr=('192.168.1.100', 0) # Bind to specific local IP
220
)
221
222
# Configure socket options
223
sock.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)
224
sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
225
```
226
227
### Error Handling and Retry Logic
228
229
```python
230
import time
231
from python_socks import ProxyError, ProxyTimeoutError, ProxyConnectionError
232
from python_socks.sync import Proxy
233
234
def robust_proxy_connect(proxy_url, dest_host, dest_port, max_retries=3):
235
"""Connect with comprehensive error handling."""
236
237
for attempt in range(max_retries):
238
try:
239
proxy = Proxy.from_url(proxy_url)
240
return proxy.connect(dest_host, dest_port, timeout=30)
241
242
except ProxyConnectionError as e:
243
print(f"Connection failed (attempt {attempt + 1}): {e}")
244
if attempt < max_retries - 1:
245
time.sleep(2 ** attempt) # Exponential backoff
246
else:
247
raise
248
249
except ProxyTimeoutError:
250
print(f"Timeout (attempt {attempt + 1})")
251
if attempt < max_retries - 1:
252
continue
253
else:
254
raise
255
256
except ProxyError as e:
257
# Don't retry authentication or protocol errors
258
print(f"Proxy error: {e} (code: {e.error_code})")
259
raise
260
261
# Usage
262
try:
263
sock = robust_proxy_connect(
264
'socks5://user:pass@proxy.example.com:1080',
265
'api.example.com',
266
443
267
)
268
print("Connected successfully!")
269
sock.close()
270
except Exception as e:
271
print(f"All connection attempts failed: {e}")
272
```
273
274
### Multiple Proxy Protocols
275
276
```python
277
from python_socks import ProxyType
278
from python_socks.sync import Proxy
279
280
def try_multiple_proxies(proxy_configs, dest_host, dest_port):
281
"""Try multiple proxy configurations until one succeeds."""
282
283
for config in proxy_configs:
284
try:
285
if isinstance(config, str):
286
proxy = Proxy.from_url(config)
287
else:
288
proxy = Proxy(**config)
289
290
sock = proxy.connect(dest_host, dest_port)
291
return sock, config
292
293
except Exception as e:
294
print(f"Failed with {config}: {e}")
295
continue
296
297
raise ConnectionError("All proxy configurations failed")
298
299
# Configuration list
300
proxy_configs = [
301
'socks5://primary-proxy:1080',
302
'http://backup-proxy:8080',
303
{
304
'proxy_type': ProxyType.SOCKS4,
305
'host': 'legacy-proxy.example.com',
306
'port': 1080
307
}
308
]
309
310
try:
311
sock, used_config = try_multiple_proxies(
312
proxy_configs,
313
'example.com',
314
80
315
)
316
print(f"Connected using: {used_config}")
317
sock.close()
318
except ConnectionError as e:
319
print(f"Could not connect: {e}")
320
```
321
322
### Context Manager Pattern
323
324
```python
325
from contextlib import contextmanager
326
from python_socks.sync import Proxy
327
328
@contextmanager
329
def proxy_connection(proxy_url, dest_host, dest_port, **kwargs):
330
"""Context manager for proxy connections."""
331
proxy = Proxy.from_url(proxy_url)
332
sock = None
333
try:
334
sock = proxy.connect(dest_host, dest_port, **kwargs)
335
yield sock
336
finally:
337
if sock:
338
sock.close()
339
340
# Usage
341
with proxy_connection('socks5://proxy:1080', 'example.com', 80) as sock:
342
sock.send(b'GET / HTTP/1.1\r\nHost: example.com\r\n\r\n')
343
response = sock.recv(4096)
344
print(response.decode())
345
```
346
347
## Protocol-Specific Notes
348
349
### SOCKS4 Protocol
350
- Supports IPv4 addresses only
351
- No authentication (username/password ignored)
352
- Optional userid field (passed as username)
353
- SOCKS4a variant supports domain names
354
355
### SOCKS5 Protocol
356
- Supports IPv4, IPv6, and domain names
357
- Multiple authentication methods (no auth, username/password)
358
- Remote DNS resolution controlled by `rdns` parameter
359
- Full RFC 1928 compliance
360
361
### HTTP CONNECT Protocol
362
- Tunneling through HTTP proxies
363
- Basic authentication support
364
- Works with any TCP protocol over the tunnel
365
- Supports both HTTP and HTTPS proxy servers