protox-gatekeeper 0.1.2__py3-none-any.whl → 0.2.1__py3-none-any.whl

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/core.py CHANGED
@@ -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
- if not is_tor_exit(session=self._session, timeout=timeout):
37
- raise RuntimeError('Tor verification failed. Execution aborted.')
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
  """
protox_gatekeeper/geo.py CHANGED
@@ -10,7 +10,7 @@ def geo_lookup(ip: str) -> str | None:
10
10
  r = requests.get(
11
11
  url=f'https://ipapi.co/{ip}/json',
12
12
  timeout=10,
13
- headers={'User-Agent': 'GateKeeper/0.1.0'}
13
+ headers={'User-Agent': 'GateKeeper/0.2.1'}
14
14
  )
15
15
  if r.status_code != 200:
16
16
  return None
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: protox-gatekeeper
3
- Version: 0.1.2
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
  [![Python versions](https://img.shields.io/pypi/pyversions/protox-gatekeeper.svg)](https://pypi.org/project/protox-gatekeeper/)
47
48
  [![License](https://img.shields.io/pypi/l/protox-gatekeeper.svg)](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
- **failclosed Tor routing** for HTTP(S) traffic.
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 *fireandforget*: create a client once, then perform network operations with a hard guarantee that traffic exits through the Tor network.
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 **Torverified HTTP client**
66
- - A thin wrapper around `requests.Session`
67
- - Failclosed by default (no silent clearnet fallback)
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 besteffort Tor exit geolocation (optional)
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 reverification**
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 besteffort and may be unavailable (ratelimits, CAPTCHAs)
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.2**
213
- - Phase 1 complete
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
- - higherlevel request helpers
263
+ - higher-level request helpers
220
264
 
221
265
  Without breaking the core contract.
222
-
@@ -0,0 +1,11 @@
1
+ protox_gatekeeper/__init__.py,sha256=HisDC-NCbMlkrNkrLRdANILoBqw03ssqFp6BTsXm6Us,75
2
+ protox_gatekeeper/core.py,sha256=oMTTlSbzZ3OxpJ7DFY5sKjbIsffeQhV2bzjt5KLArAM,4414
3
+ protox_gatekeeper/geo.py,sha256=j1TY88OavTx5rqhWd-3hbhZzD51Gjtl726bqvnApA1Q,641
4
+ protox_gatekeeper/ops.py,sha256=Kmr8lU8Ohe81URHHNUlUJ0S71aZ1uGgyiztLBPsOUO4,690
5
+ protox_gatekeeper/session.py,sha256=0qGZF44EHr7CP-bSM0awtq4F-5LWiIb4w87mV7Yocfk,235
6
+ protox_gatekeeper/verify.py,sha256=bsHK3f16sRV8cHo30AY82SB1vb_Svu-US7IhghTSQ6E,452
7
+ protox_gatekeeper-0.2.1.dist-info/licenses/LICENSE,sha256=EE75Vy9_csDDBRXBF4uVQWxYu1YpzXTcmaeuVcPOjl4,1093
8
+ protox_gatekeeper-0.2.1.dist-info/METADATA,sha256=Is8hyTIs6kRhGdhLsRrw86rxI9PCtxMu6ZUetxVNZ6s,6942
9
+ protox_gatekeeper-0.2.1.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
10
+ protox_gatekeeper-0.2.1.dist-info/top_level.txt,sha256=KOVL4YUpiWQLGjCvx2SmP8VSsA6hPcEvKCd4k6kPl8s,18
11
+ protox_gatekeeper-0.2.1.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (80.10.1)
2
+ Generator: setuptools (80.10.2)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1,11 +0,0 @@
1
- protox_gatekeeper/__init__.py,sha256=HisDC-NCbMlkrNkrLRdANILoBqw03ssqFp6BTsXm6Us,75
2
- protox_gatekeeper/core.py,sha256=Z4LEY1WcSbjMDU3OS1rf7kPOTry9NJq5-quzACxPvKg,3062
3
- protox_gatekeeper/geo.py,sha256=AdjHfZqjP0w5ujHFI_WV7c5XWnDTzqkVL32KeJQojYo,641
4
- protox_gatekeeper/ops.py,sha256=Kmr8lU8Ohe81URHHNUlUJ0S71aZ1uGgyiztLBPsOUO4,690
5
- protox_gatekeeper/session.py,sha256=0qGZF44EHr7CP-bSM0awtq4F-5LWiIb4w87mV7Yocfk,235
6
- protox_gatekeeper/verify.py,sha256=bsHK3f16sRV8cHo30AY82SB1vb_Svu-US7IhghTSQ6E,452
7
- protox_gatekeeper-0.1.2.dist-info/licenses/LICENSE,sha256=EE75Vy9_csDDBRXBF4uVQWxYu1YpzXTcmaeuVcPOjl4,1093
8
- protox_gatekeeper-0.1.2.dist-info/METADATA,sha256=MmHERPyR-Jx8UnAM8BhmpIe6IKrgk7-k_44fN7l8Jh8,6154
9
- protox_gatekeeper-0.1.2.dist-info/WHEEL,sha256=qELbo2s1Yzl39ZmrAibXA2jjPLUYfnVhUNTlyF1rq0Y,92
10
- protox_gatekeeper-0.1.2.dist-info/top_level.txt,sha256=KOVL4YUpiWQLGjCvx2SmP8VSsA6hPcEvKCd4k6kPl8s,18
11
- protox_gatekeeper-0.1.2.dist-info/RECORD,,