protox-gatekeeper 0.1.2__tar.gz → 0.2.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {protox_gatekeeper-0.1.2 → protox_gatekeeper-0.2.1}/PKG-INFO +58 -15
- {protox_gatekeeper-0.1.2 → protox_gatekeeper-0.2.1}/README.md +56 -14
- {protox_gatekeeper-0.1.2 → protox_gatekeeper-0.2.1}/protox_gatekeeper/core.py +36 -2
- {protox_gatekeeper-0.1.2 → protox_gatekeeper-0.2.1}/protox_gatekeeper/geo.py +1 -1
- {protox_gatekeeper-0.1.2 → protox_gatekeeper-0.2.1}/protox_gatekeeper.egg-info/PKG-INFO +58 -15
- {protox_gatekeeper-0.1.2 → protox_gatekeeper-0.2.1}/pyproject.toml +7 -1
- {protox_gatekeeper-0.1.2 → protox_gatekeeper-0.2.1}/LICENSE +0 -0
- {protox_gatekeeper-0.1.2 → protox_gatekeeper-0.2.1}/protox_gatekeeper/__init__.py +0 -0
- {protox_gatekeeper-0.1.2 → protox_gatekeeper-0.2.1}/protox_gatekeeper/ops.py +0 -0
- {protox_gatekeeper-0.1.2 → protox_gatekeeper-0.2.1}/protox_gatekeeper/session.py +0 -0
- {protox_gatekeeper-0.1.2 → protox_gatekeeper-0.2.1}/protox_gatekeeper/verify.py +0 -0
- {protox_gatekeeper-0.1.2 → protox_gatekeeper-0.2.1}/protox_gatekeeper.egg-info/SOURCES.txt +0 -0
- {protox_gatekeeper-0.1.2 → protox_gatekeeper-0.2.1}/protox_gatekeeper.egg-info/dependency_links.txt +0 -0
- {protox_gatekeeper-0.1.2 → protox_gatekeeper-0.2.1}/protox_gatekeeper.egg-info/requires.txt +0 -0
- {protox_gatekeeper-0.1.2 → protox_gatekeeper-0.2.1}/protox_gatekeeper.egg-info/top_level.txt +0 -0
- {protox_gatekeeper-0.1.2 → protox_gatekeeper-0.2.1}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: protox-gatekeeper
|
|
3
|
-
Version: 0.1
|
|
3
|
+
Version: 0.2.1
|
|
4
4
|
Summary: Fail-closed Tor session enforcement for Python HTTP(S) traffic
|
|
5
5
|
Author: Tom Erik Harnes
|
|
6
6
|
License: MIT License
|
|
@@ -33,6 +33,7 @@ Classifier: Programming Language :: Python :: 3
|
|
|
33
33
|
Classifier: Programming Language :: Python :: 3.10
|
|
34
34
|
Classifier: Programming Language :: Python :: 3.11
|
|
35
35
|
Classifier: Programming Language :: Python :: 3.12
|
|
36
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
36
37
|
Classifier: License :: OSI Approved :: MIT License
|
|
37
38
|
Classifier: Operating System :: OS Independent
|
|
38
39
|
Requires-Python: >=3.10
|
|
@@ -46,25 +47,24 @@ Dynamic: license-file
|
|
|
46
47
|
[](https://pypi.org/project/protox-gatekeeper/)
|
|
47
48
|
[](https://pypi.org/project/protox-gatekeeper/)
|
|
48
49
|
|
|
49
|
-
|
|
50
50
|
# ProtoX GateKeeper
|
|
51
51
|
|
|
52
52
|
**ProtoX GateKeeper** is a small, opinionated Python library that enforces
|
|
53
|
-
**fail
|
|
53
|
+
**fail-closed Tor routing** for HTTP(S) traffic.
|
|
54
54
|
|
|
55
55
|
The goal is simple:
|
|
56
56
|
|
|
57
57
|
> If Tor is not active and verified, **nothing runs**.
|
|
58
58
|
|
|
59
|
-
GateKeeper is designed to be *fire
|
|
59
|
+
GateKeeper is designed to be *fire-and-forget*: create a client once, then perform network operations with a hard guarantee that traffic exits through the Tor network.
|
|
60
60
|
|
|
61
61
|
---
|
|
62
62
|
|
|
63
63
|
## What GateKeeper Is
|
|
64
64
|
|
|
65
|
-
- A **Tor
|
|
66
|
-
- A thin wrapper around `requests.Session`
|
|
67
|
-
- Fail
|
|
65
|
+
- A **Tor-verified HTTP client**
|
|
66
|
+
- A thin wrapper around `requests.Session` with safe helpers
|
|
67
|
+
- Fail-closed by default (no silent clearnet fallback)
|
|
68
68
|
- Observable (exit IP, optional geo info)
|
|
69
69
|
- Suitable for scripts, tooling, and automation
|
|
70
70
|
|
|
@@ -92,6 +92,12 @@ On Windows this usually means **Tor Browser** running in the background.
|
|
|
92
92
|
|
|
93
93
|
## Installation
|
|
94
94
|
|
|
95
|
+
### From PyPI
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
pip install protox-gatekeeper
|
|
99
|
+
```
|
|
100
|
+
|
|
95
101
|
### From source (development)
|
|
96
102
|
|
|
97
103
|
```bash
|
|
@@ -136,6 +142,20 @@ This confirms:
|
|
|
136
142
|
|
|
137
143
|
---
|
|
138
144
|
|
|
145
|
+
### HTTP requests
|
|
146
|
+
|
|
147
|
+
GateKeeper can also be used as a Tor-verified HTTP client:
|
|
148
|
+
|
|
149
|
+
```python
|
|
150
|
+
with GateKeeper() as gk:
|
|
151
|
+
response = gk.get("https://httpbin.org/ip")
|
|
152
|
+
print(response.json())
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
All requests are guaranteed to use the verified Tor session.
|
|
156
|
+
|
|
157
|
+
---
|
|
158
|
+
|
|
139
159
|
## API Overview
|
|
140
160
|
|
|
141
161
|
### `GateKeeper(...)`
|
|
@@ -149,7 +169,7 @@ gk = GateKeeper(
|
|
|
149
169
|
|
|
150
170
|
**Parameters**:
|
|
151
171
|
- `socks_port` *(int)* – Tor SOCKS port (default: `9150`)
|
|
152
|
-
- `geo` *(bool)* – Enable best
|
|
172
|
+
- `geo` *(bool)* – Enable best-effort Tor exit geolocation (optional)
|
|
153
173
|
|
|
154
174
|
Raises `RuntimeError` if Tor routing cannot be verified.
|
|
155
175
|
|
|
@@ -168,13 +188,37 @@ gk.download(url, target_path)
|
|
|
168
188
|
|
|
169
189
|
---
|
|
170
190
|
|
|
191
|
+
### `get(url, **kwargs)`
|
|
192
|
+
|
|
193
|
+
Performs a Tor-verified HTTP GET request.
|
|
194
|
+
|
|
195
|
+
```python
|
|
196
|
+
response = gk.get(url, timeout=10)
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
Returns a standard `requests.Response`.
|
|
200
|
+
|
|
201
|
+
---
|
|
202
|
+
|
|
203
|
+
### `post(url, data=None, json=None, **kwargs)`
|
|
204
|
+
|
|
205
|
+
Performs a Tor-verified HTTP POST request.
|
|
206
|
+
|
|
207
|
+
```python
|
|
208
|
+
response = gk.post(url, json={"key": "value"})
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
Returns a standard `requests.Response`.
|
|
212
|
+
|
|
213
|
+
---
|
|
214
|
+
|
|
171
215
|
## Design Principles
|
|
172
216
|
|
|
173
217
|
- **Fail closed**: no Tor → no execution
|
|
174
218
|
- **Single verification point** (during construction)
|
|
175
219
|
- **No global state**
|
|
176
220
|
- **No logging configuration inside the library**
|
|
177
|
-
- **Session reuse without re
|
|
221
|
+
- **Session reuse without re-verification**
|
|
178
222
|
|
|
179
223
|
Logging is emitted by the library, but **configured by the application**.
|
|
180
224
|
|
|
@@ -196,8 +240,8 @@ The library does **not** call `logging.basicConfig()` internally.
|
|
|
196
240
|
## Security Notes
|
|
197
241
|
|
|
198
242
|
- Tor exit IPs may rotate over time
|
|
199
|
-
- Geo information is best
|
|
200
|
-
- GateKeeper guarantees routing, not anonymity
|
|
243
|
+
- Geo information is best-effort and may be unavailable (rate-limits, CAPTCHAs)
|
|
244
|
+
- GateKeeper guarantees transport routing, not anonymity
|
|
201
245
|
|
|
202
246
|
---
|
|
203
247
|
|
|
@@ -209,14 +253,13 @@ MIT License
|
|
|
209
253
|
|
|
210
254
|
## Status
|
|
211
255
|
|
|
212
|
-
- Version: **v0.1
|
|
213
|
-
- Phase
|
|
256
|
+
- Version: **v0.2.1**
|
|
257
|
+
- Phase 2 in progress
|
|
214
258
|
- API intentionally minimal
|
|
215
259
|
|
|
216
260
|
Future versions may add optional features such as:
|
|
217
261
|
- circuit rotation
|
|
218
262
|
- ControlPort support
|
|
219
|
-
- higher
|
|
263
|
+
- higher-level request helpers
|
|
220
264
|
|
|
221
265
|
Without breaking the core contract.
|
|
222
|
-
|
|
@@ -2,25 +2,24 @@
|
|
|
2
2
|
[](https://pypi.org/project/protox-gatekeeper/)
|
|
3
3
|
[](https://pypi.org/project/protox-gatekeeper/)
|
|
4
4
|
|
|
5
|
-
|
|
6
5
|
# ProtoX GateKeeper
|
|
7
6
|
|
|
8
7
|
**ProtoX GateKeeper** is a small, opinionated Python library that enforces
|
|
9
|
-
**fail
|
|
8
|
+
**fail-closed Tor routing** for HTTP(S) traffic.
|
|
10
9
|
|
|
11
10
|
The goal is simple:
|
|
12
11
|
|
|
13
12
|
> If Tor is not active and verified, **nothing runs**.
|
|
14
13
|
|
|
15
|
-
GateKeeper is designed to be *fire
|
|
14
|
+
GateKeeper is designed to be *fire-and-forget*: create a client once, then perform network operations with a hard guarantee that traffic exits through the Tor network.
|
|
16
15
|
|
|
17
16
|
---
|
|
18
17
|
|
|
19
18
|
## What GateKeeper Is
|
|
20
19
|
|
|
21
|
-
- A **Tor
|
|
22
|
-
- A thin wrapper around `requests.Session`
|
|
23
|
-
- Fail
|
|
20
|
+
- A **Tor-verified HTTP client**
|
|
21
|
+
- A thin wrapper around `requests.Session` with safe helpers
|
|
22
|
+
- Fail-closed by default (no silent clearnet fallback)
|
|
24
23
|
- Observable (exit IP, optional geo info)
|
|
25
24
|
- Suitable for scripts, tooling, and automation
|
|
26
25
|
|
|
@@ -48,6 +47,12 @@ On Windows this usually means **Tor Browser** running in the background.
|
|
|
48
47
|
|
|
49
48
|
## Installation
|
|
50
49
|
|
|
50
|
+
### From PyPI
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
pip install protox-gatekeeper
|
|
54
|
+
```
|
|
55
|
+
|
|
51
56
|
### From source (development)
|
|
52
57
|
|
|
53
58
|
```bash
|
|
@@ -92,6 +97,20 @@ This confirms:
|
|
|
92
97
|
|
|
93
98
|
---
|
|
94
99
|
|
|
100
|
+
### HTTP requests
|
|
101
|
+
|
|
102
|
+
GateKeeper can also be used as a Tor-verified HTTP client:
|
|
103
|
+
|
|
104
|
+
```python
|
|
105
|
+
with GateKeeper() as gk:
|
|
106
|
+
response = gk.get("https://httpbin.org/ip")
|
|
107
|
+
print(response.json())
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
All requests are guaranteed to use the verified Tor session.
|
|
111
|
+
|
|
112
|
+
---
|
|
113
|
+
|
|
95
114
|
## API Overview
|
|
96
115
|
|
|
97
116
|
### `GateKeeper(...)`
|
|
@@ -105,7 +124,7 @@ gk = GateKeeper(
|
|
|
105
124
|
|
|
106
125
|
**Parameters**:
|
|
107
126
|
- `socks_port` *(int)* – Tor SOCKS port (default: `9150`)
|
|
108
|
-
- `geo` *(bool)* – Enable best
|
|
127
|
+
- `geo` *(bool)* – Enable best-effort Tor exit geolocation (optional)
|
|
109
128
|
|
|
110
129
|
Raises `RuntimeError` if Tor routing cannot be verified.
|
|
111
130
|
|
|
@@ -124,13 +143,37 @@ gk.download(url, target_path)
|
|
|
124
143
|
|
|
125
144
|
---
|
|
126
145
|
|
|
146
|
+
### `get(url, **kwargs)`
|
|
147
|
+
|
|
148
|
+
Performs a Tor-verified HTTP GET request.
|
|
149
|
+
|
|
150
|
+
```python
|
|
151
|
+
response = gk.get(url, timeout=10)
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
Returns a standard `requests.Response`.
|
|
155
|
+
|
|
156
|
+
---
|
|
157
|
+
|
|
158
|
+
### `post(url, data=None, json=None, **kwargs)`
|
|
159
|
+
|
|
160
|
+
Performs a Tor-verified HTTP POST request.
|
|
161
|
+
|
|
162
|
+
```python
|
|
163
|
+
response = gk.post(url, json={"key": "value"})
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
Returns a standard `requests.Response`.
|
|
167
|
+
|
|
168
|
+
---
|
|
169
|
+
|
|
127
170
|
## Design Principles
|
|
128
171
|
|
|
129
172
|
- **Fail closed**: no Tor → no execution
|
|
130
173
|
- **Single verification point** (during construction)
|
|
131
174
|
- **No global state**
|
|
132
175
|
- **No logging configuration inside the library**
|
|
133
|
-
- **Session reuse without re
|
|
176
|
+
- **Session reuse without re-verification**
|
|
134
177
|
|
|
135
178
|
Logging is emitted by the library, but **configured by the application**.
|
|
136
179
|
|
|
@@ -152,8 +195,8 @@ The library does **not** call `logging.basicConfig()` internally.
|
|
|
152
195
|
## Security Notes
|
|
153
196
|
|
|
154
197
|
- Tor exit IPs may rotate over time
|
|
155
|
-
- Geo information is best
|
|
156
|
-
- GateKeeper guarantees routing, not anonymity
|
|
198
|
+
- Geo information is best-effort and may be unavailable (rate-limits, CAPTCHAs)
|
|
199
|
+
- GateKeeper guarantees transport routing, not anonymity
|
|
157
200
|
|
|
158
201
|
---
|
|
159
202
|
|
|
@@ -165,14 +208,13 @@ MIT License
|
|
|
165
208
|
|
|
166
209
|
## Status
|
|
167
210
|
|
|
168
|
-
- Version: **v0.1
|
|
169
|
-
- Phase
|
|
211
|
+
- Version: **v0.2.1**
|
|
212
|
+
- Phase 2 in progress
|
|
170
213
|
- API intentionally minimal
|
|
171
214
|
|
|
172
215
|
Future versions may add optional features such as:
|
|
173
216
|
- circuit rotation
|
|
174
217
|
- ControlPort support
|
|
175
|
-
- higher
|
|
218
|
+
- higher-level request helpers
|
|
176
219
|
|
|
177
220
|
Without breaking the core contract.
|
|
178
|
-
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import logging
|
|
2
2
|
|
|
3
3
|
import requests
|
|
4
|
+
from requests.exceptions import RequestException
|
|
4
5
|
|
|
5
6
|
from protox_gatekeeper.session import make_tor_session
|
|
6
7
|
from protox_gatekeeper.verify import is_tor_exit, get_public_ip
|
|
@@ -33,8 +34,16 @@ class GateKeeper:
|
|
|
33
34
|
self._session = make_tor_session(port=socks_port)
|
|
34
35
|
|
|
35
36
|
# 3) Verify Tor routing
|
|
36
|
-
|
|
37
|
-
|
|
37
|
+
try:
|
|
38
|
+
if not is_tor_exit(session=self._session, timeout=timeout):
|
|
39
|
+
raise RuntimeError(
|
|
40
|
+
'Tor verification failed. Execution aborted.')
|
|
41
|
+
except RequestException as e:
|
|
42
|
+
logger.debug('Underlying Tor connection error', exc_info=e)
|
|
43
|
+
raise RuntimeError(
|
|
44
|
+
f'Tor SOCKS proxy is not reachable on 127.0.0.1:{socks_port}. '
|
|
45
|
+
'Start Tor or Tor Browser and try again.'
|
|
46
|
+
) from None
|
|
38
47
|
|
|
39
48
|
# 4) Measure Tor exit IP
|
|
40
49
|
self.exit_ip = get_public_ip(session=self._session, timeout=timeout)
|
|
@@ -69,6 +78,31 @@ class GateKeeper:
|
|
|
69
78
|
""" Returns the Tor exit IP address. """
|
|
70
79
|
return self.exit_ip
|
|
71
80
|
|
|
81
|
+
def get(self, url: str, **kwargs) -> requests.Response:
|
|
82
|
+
"""
|
|
83
|
+
Passes a GET request to the Tor Gatekeeper.
|
|
84
|
+
|
|
85
|
+
Args:
|
|
86
|
+
url (str): The url to request.
|
|
87
|
+
**kwargs: Additional parameters to pass to the GET request.
|
|
88
|
+
"""
|
|
89
|
+
logger.info(f'[Tor {self.tor_exit}] GET {url}')
|
|
90
|
+
return self._session.get(url=url, **kwargs)
|
|
91
|
+
|
|
92
|
+
def post(self, url: str, data=None, json=None,
|
|
93
|
+
**kwargs) -> requests.Response:
|
|
94
|
+
"""
|
|
95
|
+
Passes a POST request to the Tor Gatekeeper.
|
|
96
|
+
|
|
97
|
+
Args:
|
|
98
|
+
url (str): The url to post to.
|
|
99
|
+
data (dict, optional): The data to post.
|
|
100
|
+
json (dict, optional): The json data to post.
|
|
101
|
+
**kwargs: Additional parameters to pass to the POST request.
|
|
102
|
+
"""
|
|
103
|
+
logger.info(f'[Tor {self.tor_exit}] POST {url}')
|
|
104
|
+
return self._session.post(url=url, data=data, json=json, **kwargs)
|
|
105
|
+
|
|
72
106
|
def download(self, url: str, target_path: str, timeout: int = 30,
|
|
73
107
|
chunk_size: int = 8192):
|
|
74
108
|
"""
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: protox-gatekeeper
|
|
3
|
-
Version: 0.1
|
|
3
|
+
Version: 0.2.1
|
|
4
4
|
Summary: Fail-closed Tor session enforcement for Python HTTP(S) traffic
|
|
5
5
|
Author: Tom Erik Harnes
|
|
6
6
|
License: MIT License
|
|
@@ -33,6 +33,7 @@ Classifier: Programming Language :: Python :: 3
|
|
|
33
33
|
Classifier: Programming Language :: Python :: 3.10
|
|
34
34
|
Classifier: Programming Language :: Python :: 3.11
|
|
35
35
|
Classifier: Programming Language :: Python :: 3.12
|
|
36
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
36
37
|
Classifier: License :: OSI Approved :: MIT License
|
|
37
38
|
Classifier: Operating System :: OS Independent
|
|
38
39
|
Requires-Python: >=3.10
|
|
@@ -46,25 +47,24 @@ Dynamic: license-file
|
|
|
46
47
|
[](https://pypi.org/project/protox-gatekeeper/)
|
|
47
48
|
[](https://pypi.org/project/protox-gatekeeper/)
|
|
48
49
|
|
|
49
|
-
|
|
50
50
|
# ProtoX GateKeeper
|
|
51
51
|
|
|
52
52
|
**ProtoX GateKeeper** is a small, opinionated Python library that enforces
|
|
53
|
-
**fail
|
|
53
|
+
**fail-closed Tor routing** for HTTP(S) traffic.
|
|
54
54
|
|
|
55
55
|
The goal is simple:
|
|
56
56
|
|
|
57
57
|
> If Tor is not active and verified, **nothing runs**.
|
|
58
58
|
|
|
59
|
-
GateKeeper is designed to be *fire
|
|
59
|
+
GateKeeper is designed to be *fire-and-forget*: create a client once, then perform network operations with a hard guarantee that traffic exits through the Tor network.
|
|
60
60
|
|
|
61
61
|
---
|
|
62
62
|
|
|
63
63
|
## What GateKeeper Is
|
|
64
64
|
|
|
65
|
-
- A **Tor
|
|
66
|
-
- A thin wrapper around `requests.Session`
|
|
67
|
-
- Fail
|
|
65
|
+
- A **Tor-verified HTTP client**
|
|
66
|
+
- A thin wrapper around `requests.Session` with safe helpers
|
|
67
|
+
- Fail-closed by default (no silent clearnet fallback)
|
|
68
68
|
- Observable (exit IP, optional geo info)
|
|
69
69
|
- Suitable for scripts, tooling, and automation
|
|
70
70
|
|
|
@@ -92,6 +92,12 @@ On Windows this usually means **Tor Browser** running in the background.
|
|
|
92
92
|
|
|
93
93
|
## Installation
|
|
94
94
|
|
|
95
|
+
### From PyPI
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
pip install protox-gatekeeper
|
|
99
|
+
```
|
|
100
|
+
|
|
95
101
|
### From source (development)
|
|
96
102
|
|
|
97
103
|
```bash
|
|
@@ -136,6 +142,20 @@ This confirms:
|
|
|
136
142
|
|
|
137
143
|
---
|
|
138
144
|
|
|
145
|
+
### HTTP requests
|
|
146
|
+
|
|
147
|
+
GateKeeper can also be used as a Tor-verified HTTP client:
|
|
148
|
+
|
|
149
|
+
```python
|
|
150
|
+
with GateKeeper() as gk:
|
|
151
|
+
response = gk.get("https://httpbin.org/ip")
|
|
152
|
+
print(response.json())
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
All requests are guaranteed to use the verified Tor session.
|
|
156
|
+
|
|
157
|
+
---
|
|
158
|
+
|
|
139
159
|
## API Overview
|
|
140
160
|
|
|
141
161
|
### `GateKeeper(...)`
|
|
@@ -149,7 +169,7 @@ gk = GateKeeper(
|
|
|
149
169
|
|
|
150
170
|
**Parameters**:
|
|
151
171
|
- `socks_port` *(int)* – Tor SOCKS port (default: `9150`)
|
|
152
|
-
- `geo` *(bool)* – Enable best
|
|
172
|
+
- `geo` *(bool)* – Enable best-effort Tor exit geolocation (optional)
|
|
153
173
|
|
|
154
174
|
Raises `RuntimeError` if Tor routing cannot be verified.
|
|
155
175
|
|
|
@@ -168,13 +188,37 @@ gk.download(url, target_path)
|
|
|
168
188
|
|
|
169
189
|
---
|
|
170
190
|
|
|
191
|
+
### `get(url, **kwargs)`
|
|
192
|
+
|
|
193
|
+
Performs a Tor-verified HTTP GET request.
|
|
194
|
+
|
|
195
|
+
```python
|
|
196
|
+
response = gk.get(url, timeout=10)
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
Returns a standard `requests.Response`.
|
|
200
|
+
|
|
201
|
+
---
|
|
202
|
+
|
|
203
|
+
### `post(url, data=None, json=None, **kwargs)`
|
|
204
|
+
|
|
205
|
+
Performs a Tor-verified HTTP POST request.
|
|
206
|
+
|
|
207
|
+
```python
|
|
208
|
+
response = gk.post(url, json={"key": "value"})
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
Returns a standard `requests.Response`.
|
|
212
|
+
|
|
213
|
+
---
|
|
214
|
+
|
|
171
215
|
## Design Principles
|
|
172
216
|
|
|
173
217
|
- **Fail closed**: no Tor → no execution
|
|
174
218
|
- **Single verification point** (during construction)
|
|
175
219
|
- **No global state**
|
|
176
220
|
- **No logging configuration inside the library**
|
|
177
|
-
- **Session reuse without re
|
|
221
|
+
- **Session reuse without re-verification**
|
|
178
222
|
|
|
179
223
|
Logging is emitted by the library, but **configured by the application**.
|
|
180
224
|
|
|
@@ -196,8 +240,8 @@ The library does **not** call `logging.basicConfig()` internally.
|
|
|
196
240
|
## Security Notes
|
|
197
241
|
|
|
198
242
|
- Tor exit IPs may rotate over time
|
|
199
|
-
- Geo information is best
|
|
200
|
-
- GateKeeper guarantees routing, not anonymity
|
|
243
|
+
- Geo information is best-effort and may be unavailable (rate-limits, CAPTCHAs)
|
|
244
|
+
- GateKeeper guarantees transport routing, not anonymity
|
|
201
245
|
|
|
202
246
|
---
|
|
203
247
|
|
|
@@ -209,14 +253,13 @@ MIT License
|
|
|
209
253
|
|
|
210
254
|
## Status
|
|
211
255
|
|
|
212
|
-
- Version: **v0.1
|
|
213
|
-
- Phase
|
|
256
|
+
- Version: **v0.2.1**
|
|
257
|
+
- Phase 2 in progress
|
|
214
258
|
- API intentionally minimal
|
|
215
259
|
|
|
216
260
|
Future versions may add optional features such as:
|
|
217
261
|
- circuit rotation
|
|
218
262
|
- ControlPort support
|
|
219
|
-
- higher
|
|
263
|
+
- higher-level request helpers
|
|
220
264
|
|
|
221
265
|
Without breaking the core contract.
|
|
222
|
-
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "protox-gatekeeper"
|
|
7
|
-
version = "0.1
|
|
7
|
+
version = "0.2.1"
|
|
8
8
|
description = "Fail-closed Tor session enforcement for Python HTTP(S) traffic"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = { file = "LICENSE" }
|
|
@@ -20,6 +20,7 @@ classifiers = [
|
|
|
20
20
|
"Programming Language :: Python :: 3.10",
|
|
21
21
|
"Programming Language :: Python :: 3.11",
|
|
22
22
|
"Programming Language :: Python :: 3.12",
|
|
23
|
+
"Programming Language :: Python :: 3.13",
|
|
23
24
|
"License :: OSI Approved :: MIT License",
|
|
24
25
|
"Operating System :: OS Independent",
|
|
25
26
|
]
|
|
@@ -34,3 +35,8 @@ authors = [
|
|
|
34
35
|
Homepage = "https://github.com/ProtoXCode/protox-gatekeeper"
|
|
35
36
|
Repository = "https://github.com/ProtoXCode/protox-gatekeeper"
|
|
36
37
|
Issues = "https://github.com/ProtoXCode/protox-gatekeeper/issues"
|
|
38
|
+
|
|
39
|
+
[tool.pytest.ini_options]
|
|
40
|
+
markers = [
|
|
41
|
+
"integration: requires Tor running locally"
|
|
42
|
+
]
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{protox_gatekeeper-0.1.2 → protox_gatekeeper-0.2.1}/protox_gatekeeper.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
{protox_gatekeeper-0.1.2 → protox_gatekeeper-0.2.1}/protox_gatekeeper.egg-info/top_level.txt
RENAMED
|
File without changes
|
|
File without changes
|