suxitunnel 0.1.0__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.
@@ -0,0 +1,50 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+ *.so
6
+ .Python
7
+ build/
8
+ develop-eggs/
9
+ dist/
10
+ downloads/
11
+ eggs/
12
+ .eggs/
13
+ lib/
14
+ lib64/
15
+ parts/
16
+ sdist/
17
+ var/
18
+ wheels/
19
+ *.egg-info/
20
+ .installed.cfg
21
+ *.egg
22
+ MANIFEST
23
+
24
+ # Virtual Environment
25
+ venv/
26
+ env/
27
+ ENV/
28
+ .venv
29
+
30
+ # IDE
31
+ .vscode/
32
+ .idea/
33
+ *.swp
34
+ *.swo
35
+ *~
36
+ .DS_Store
37
+
38
+ # Testing
39
+ .pytest_cache/
40
+ .coverage
41
+ htmlcov/
42
+ .tox/
43
+ *.cover
44
+
45
+ # Distribution
46
+ dist/
47
+ build/
48
+
49
+ # Local cloudflared downloads
50
+ .cloudflare-tunnel/
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,370 @@
1
+ Metadata-Version: 2.4
2
+ Name: suxitunnel
3
+ Version: 0.1.0
4
+ Summary: A simple Python library to expose local servers using Cloudflare Tunnel
5
+ Project-URL: Homepage, https://github.com/sadwx/cloudflare-tunnel
6
+ Project-URL: Repository, https://github.com/sadwx/cloudflare-tunnel
7
+ Project-URL: Issues, https://github.com/sadwx/cloudflare-tunnel/issues
8
+ Project-URL: Documentation, https://github.com/sadwx/cloudflare-tunnel#readme
9
+ Author-email: Simon <simon@suxi.world>
10
+ License-Expression: MIT
11
+ License-File: LICENSE
12
+ Keywords: cloudflare,development,expose,localhost,tunnel
13
+ Classifier: Development Status :: 4 - Beta
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: License :: OSI Approved :: MIT License
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3.14
18
+ Classifier: Topic :: Internet :: WWW/HTTP :: HTTP Servers
19
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
20
+ Requires-Python: >=3.14
21
+ Requires-Dist: requests>=2.32.0
22
+ Description-Content-Type: text/markdown
23
+
24
+ # cloudflare-tunnel
25
+
26
+ A simple Python library to expose your local server to the internet using Cloudflare's infrastructure.
27
+
28
+ Inspired by [localtunnel-py](https://github.com/gweidart/localtunnel-py) but using Cloudflare's global network for better performance and DDoS protection.
29
+
30
+ ## Installation
31
+
32
+ ```bash
33
+ pip install cloudflare-tunnel
34
+ ```
35
+
36
+ ## Quick Start
37
+
38
+ ```python
39
+ from cloudflare_tunnel import Tunnel
40
+
41
+ # Expose local port 8000
42
+ tunnel = Tunnel(8000)
43
+ print(f"Your URL: {tunnel.url}")
44
+
45
+ # Keep your app running...
46
+ input("Press Enter to close tunnel...")
47
+
48
+ tunnel.close()
49
+ ```
50
+
51
+ That's it! No configuration, no authentication, no manual setup.
52
+
53
+ ## Features
54
+
55
+ - 🚀 **Zero Configuration** - Just pass a port number
56
+ - 🔒 **Secure** - Uses Cloudflare's infrastructure with DDoS protection
57
+ - 🌍 **Global CDN** - Fast access from anywhere in the world
58
+ - 📦 **Auto-install** - Automatically downloads cloudflared if needed
59
+ - 🐍 **Simple API** - Clean, Pythonic interface
60
+
61
+ ## Usage
62
+
63
+ ### Basic Usage
64
+
65
+ ```python
66
+ from cloudflare_tunnel import Tunnel
67
+
68
+ tunnel = Tunnel(8000)
69
+ print(tunnel.url) # https://random-name.trycloudflare.com
70
+
71
+ # Your local server is now public!
72
+ # Keep tunnel alive...
73
+ tunnel.close() # Close when done
74
+ ```
75
+
76
+ ### Context Manager (Recommended)
77
+
78
+ ```python
79
+ from cloudflare_tunnel import Tunnel
80
+
81
+ with Tunnel(8000) as tunnel:
82
+ print(f"Public URL: {tunnel.url}")
83
+ # Do your work...
84
+ # Tunnel automatically closes when exiting the block
85
+ ```
86
+
87
+ ### With Flask
88
+
89
+ ```python
90
+ from flask import Flask
91
+ from cloudflare_tunnel import Tunnel
92
+ import threading
93
+
94
+ app = Flask(__name__)
95
+
96
+ @app.route('/')
97
+ def index():
98
+ return "Hello from Flask!"
99
+
100
+ if __name__ == '__main__':
101
+ # Start tunnel in background
102
+ tunnel = Tunnel(5000)
103
+ print(f"🌐 Public URL: {tunnel.url}")
104
+
105
+ # Start Flask
106
+ app.run(port=5000)
107
+ ```
108
+
109
+ ### With FastAPI
110
+
111
+ ```python
112
+ from fastapi import FastAPI
113
+ from cloudflare_tunnel import Tunnel
114
+ import uvicorn
115
+
116
+ app = FastAPI()
117
+
118
+ @app.get("/")
119
+ def read_root():
120
+ return {"message": "Hello from FastAPI!"}
121
+
122
+ if __name__ == "__main__":
123
+ # Start tunnel
124
+ tunnel = Tunnel(8000)
125
+ print(f"🌐 Public URL: {tunnel.url}")
126
+
127
+ # Start FastAPI
128
+ uvicorn.run(app, host="0.0.0.0", port=8000)
129
+ ```
130
+
131
+ ### Check Tunnel Status
132
+
133
+ ```python
134
+ tunnel = Tunnel(8000)
135
+
136
+ print(tunnel.url) # Public URL
137
+ print(tunnel.is_alive()) # True if tunnel is running
138
+ print(tunnel.port) # 8000
139
+ print(tunnel) # <Tunnel port=8000 url=https://... status=active>
140
+ ```
141
+
142
+ ### Custom Host
143
+
144
+ ```python
145
+ # Tunnel a service running on a different host
146
+ tunnel = Tunnel(8000, host="192.168.1.100")
147
+ ```
148
+
149
+ ### Manual cloudflared Path
150
+
151
+ ```python
152
+ # Use specific cloudflared binary
153
+ tunnel = Tunnel(8000, cloudflared_path="/usr/local/bin/cloudflared")
154
+ ```
155
+
156
+ ### Disable Auto-download
157
+
158
+ ```python
159
+ # Don't automatically download cloudflared
160
+ tunnel = Tunnel(8000, auto_download=False)
161
+ ```
162
+
163
+ ## API Reference
164
+
165
+ ### `Tunnel(port, host="localhost", cloudflared_path=None, auto_download=True)`
166
+
167
+ Create a tunnel to expose a local port.
168
+
169
+ **Parameters:**
170
+ - `port` (int): Local port to expose (required)
171
+ - `host` (str): Local hostname (default: "localhost")
172
+ - `cloudflared_path` (str): Path to cloudflared binary (auto-detected if None)
173
+ - `auto_download` (bool): Auto-download cloudflared if not found (default: True)
174
+
175
+ **Attributes:**
176
+ - `url` (str): Public HTTPS URL for the tunnel
177
+ - `port` (int): Local port being exposed
178
+ - `host` (str): Local hostname
179
+ - `is_alive()` (bool): Check if tunnel is running
180
+ - `close()`: Close the tunnel
181
+
182
+ **Example:**
183
+ ```python
184
+ tunnel = Tunnel(8000)
185
+ print(tunnel.url) # https://abc123.trycloudflare.com
186
+ tunnel.close()
187
+ ```
188
+
189
+ ### `open_tunnel(port, host="localhost")`
190
+
191
+ Convenience function to create a tunnel.
192
+
193
+ ```python
194
+ from cloudflare_tunnel import open_tunnel
195
+
196
+ tunnel = open_tunnel(8000)
197
+ ```
198
+
199
+ ## How It Works
200
+
201
+ ### Technical Overview
202
+
203
+ This library uses **Cloudflare Quick Tunnels** (also called TryCloudflare), which:
204
+
205
+ 1. Creates an outbound HTTP/2 connection from your machine to Cloudflare's edge
206
+ 2. No inbound ports are opened on your machine (firewall-friendly!)
207
+ 3. No authentication or account required
208
+ 4. Traffic is routed through Cloudflare's global network
209
+ 5. Automatic HTTPS with valid certificate
210
+
211
+ **Architecture:**
212
+ ```
213
+ Your App (localhost:8000) → cloudflared → Cloudflare Edge → Internet
214
+ (HTTP/2) (Global CDN) (HTTPS)
215
+ ```
216
+
217
+ ### Cloudflared Binary
218
+
219
+ The library automatically downloads the `cloudflared` binary on first use if it's not already installed. The binary is saved to `~/.cloudflare-tunnel/`.
220
+
221
+ Supported platforms:
222
+ - Linux (x64, ARM64)
223
+ - macOS (x64, ARM64/M1)
224
+ - Windows (x64)
225
+
226
+ ## Comparison with Alternatives
227
+
228
+ | Feature | cloudflare-tunnel | localtunnel | ngrok |
229
+ |---------|------------------|-------------|-------|
230
+ | Free tier | ✅ Unlimited | ✅ Yes | ⚠️ Limited |
231
+ | Custom domains | ❌ Random | ❌ Random | 💰 Paid |
232
+ | DDoS protection | ✅ Included | ❌ No | ⚠️ Limited |
233
+ | Global CDN | ✅ Yes | ❌ No | ⚠️ Limited |
234
+ | Auth required | ✅ No | ✅ No | ⚠️ Yes |
235
+ | Connection limits | ✅ None | ⚠️ Yes | ⚠️ Yes |
236
+ | Rate limits | ✅ Generous | ⚠️ Yes | ⚠️ Yes |
237
+
238
+ ## Limitations
239
+
240
+ 1. **Random URLs**: Each tunnel gets a random `*.trycloudflare.com` URL (no custom domains)
241
+ 2. **Temporary**: Tunnels are meant for development/testing, not production
242
+ 3. **No persistence**: URL changes each time you create a new tunnel
243
+ 4. **Rate limits**: Subject to Cloudflare's fair use policy
244
+
245
+ For production use with custom domains, see the full [cloudflared documentation](https://developers.cloudflare.com/cloudflare-one/connections/connect-apps/).
246
+
247
+ ## Security Considerations
248
+
249
+ ### What This Tunnel Provides
250
+
251
+ ✅ **DDoS protection** - Cloudflare's network absorbs attacks
252
+ ✅ **HTTPS encryption** - Valid SSL certificate included
253
+ ✅ **No exposed ports** - Outbound connection only
254
+ ✅ **Firewall-friendly** - Works behind NAT/firewalls
255
+
256
+ ### What You Still Need
257
+
258
+ ⚠️ **Application security** - Implement authentication/authorization
259
+ ⚠️ **Input validation** - Protect against malicious input
260
+ ⚠️ **Rate limiting** - Prevent abuse of your endpoints
261
+ ⚠️ **Access control** - Not everyone should access your tunnel
262
+
263
+ **Important:** Once your local server is exposed via a tunnel, anyone with the URL can access it. Make sure your application has proper authentication!
264
+
265
+ ### Best Practices
266
+
267
+ ```python
268
+ # ❌ DON'T: Expose services without authentication
269
+ tunnel = Tunnel(8000) # If port 8000 has no auth, anyone can access it!
270
+
271
+ # ✅ DO: Use authentication in your application
272
+ from flask import Flask, request, abort
273
+ from functools import wraps
274
+
275
+ def require_auth(f):
276
+ @wraps(f)
277
+ def decorated(*args, **kwargs):
278
+ auth = request.headers.get('Authorization')
279
+ if auth != 'Bearer YOUR_SECRET_TOKEN':
280
+ abort(401)
281
+ return f(*args, **kwargs)
282
+ return decorated
283
+
284
+ @app.route('/api/data')
285
+ @require_auth # Protected!
286
+ def get_data():
287
+ return {"data": "sensitive"}
288
+ ```
289
+
290
+ ## Troubleshooting
291
+
292
+ ### "cloudflared not found"
293
+
294
+ The library should auto-download cloudflared. If it fails:
295
+
296
+ ```bash
297
+ # Manual install
298
+ # macOS
299
+ brew install cloudflare/cloudflare/cloudflared
300
+
301
+ # Linux
302
+ wget https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64
303
+ chmod +x cloudflared-linux-amd64
304
+ sudo mv cloudflared-linux-amd64 /usr/local/bin/cloudflared
305
+
306
+ # Or disable auto-download and specify path
307
+ tunnel = Tunnel(8000, cloudflared_path="/path/to/cloudflared", auto_download=False)
308
+ ```
309
+
310
+ ### "Tunnel failed to start"
311
+
312
+ Check that:
313
+ 1. Your local service is running: `curl http://localhost:8000`
314
+ 2. The port is not already in use
315
+ 3. You have internet connectivity
316
+ 4. Firewall allows outbound HTTPS (port 443)
317
+
318
+ ### Tunnel URL not appearing
319
+
320
+ The library waits up to 30 seconds for the URL. If it times out:
321
+ 1. Check your internet connection
322
+ 2. Verify cloudflared is working: `cloudflared --version`
323
+ 3. Try running manually: `cloudflared tunnel --url http://localhost:8000`
324
+
325
+ ### Random disconnections
326
+
327
+ Quick Tunnels are designed for temporary use. For stable connections:
328
+ 1. Restart the tunnel when disconnected
329
+ 2. For production, use authenticated Cloudflare Tunnels with named tunnels
330
+ 3. Implement automatic reconnection logic
331
+
332
+ ## Examples
333
+
334
+ See the `examples/` directory for complete working examples:
335
+
336
+ - `basic_example.py` - Simplest usage
337
+ - `flask_example.py` - Flask integration
338
+ - `fastapi_example.py` - FastAPI integration
339
+ - `context_manager.py` - Using with context manager
340
+ - `multiple_tunnels.py` - Running multiple tunnels
341
+
342
+ ## Development
343
+
344
+ ```bash
345
+ # Clone the repo
346
+ git clone https://github.com/sadwx/cloudflare-tunnel.git
347
+ cd cloudflare-tunnel
348
+
349
+ # Install in development mode
350
+ pip install -e .
351
+
352
+ # Run tests
353
+ python -m pytest tests/
354
+ ```
355
+
356
+ ## License
357
+
358
+ MIT License - see LICENSE file for details.
359
+
360
+ ## Related Projects
361
+
362
+ - [cloudflared](https://github.com/cloudflare/cloudflared) - Official Cloudflare Tunnel client
363
+ - [localtunnel-py](https://github.com/gweidart/localtunnel-py) - Similar library using localtunnel
364
+ - [pyngrok](https://github.com/alexdlaird/pyngrok) - Python wrapper for ngrok
365
+
366
+ ## Credits
367
+
368
+ This library is a Python wrapper around [cloudflared](https://github.com/cloudflare/cloudflared), the official Cloudflare Tunnel client.
369
+
370
+ Inspired by the simplicity of [localtunnel-py](https://github.com/gweidart/localtunnel-py).