suxitunnel 0.1.2__py3-none-any.whl → 0.1.3__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.
- PKG-INFO +60 -4
- README.md +59 -3
- __init__.py +1 -1
- pyproject.toml +5 -1
- {suxitunnel-0.1.2.dist-info → suxitunnel-0.1.3.dist-info}/METADATA +60 -4
- suxitunnel-0.1.3.dist-info/RECORD +17 -0
- suxitunnel-0.1.3.dist-info/entry_points.txt +2 -0
- suxitunnel.py +92 -13
- suxitunnel-0.1.2.dist-info/RECORD +0 -16
- {suxitunnel-0.1.2.dist-info → suxitunnel-0.1.3.dist-info}/WHEEL +0 -0
- {suxitunnel-0.1.2.dist-info → suxitunnel-0.1.3.dist-info}/licenses/LICENSE +0 -0
PKG-INFO
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: suxitunnel
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.3
|
|
4
4
|
Summary: A simple Python library to expose local servers using Cloudflare Tunnel
|
|
5
5
|
Project-URL: Homepage, https://github.com/sadwx/suxitunnel
|
|
6
6
|
Project-URL: Repository, https://github.com/sadwx/suxitunnel
|
|
@@ -35,6 +35,21 @@ pip install suxitunnel
|
|
|
35
35
|
|
|
36
36
|
## Quick Start
|
|
37
37
|
|
|
38
|
+
### Command Line
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
# Expose local port 8000 (random URL)
|
|
42
|
+
suxitunnel --port 8000
|
|
43
|
+
|
|
44
|
+
# Or use short form
|
|
45
|
+
suxitunnel -p 8000
|
|
46
|
+
|
|
47
|
+
# Use a named tunnel with dedicated URL (requires Cloudflare account)
|
|
48
|
+
suxitunnel --port 8000 --tunnel-token YOUR_TOKEN
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### Python API
|
|
52
|
+
|
|
38
53
|
```python
|
|
39
54
|
from suxitunnel import Tunnel
|
|
40
55
|
|
|
@@ -57,6 +72,8 @@ That's it! No configuration, no authentication, no manual setup.
|
|
|
57
72
|
- 🌍 **Global CDN** - Fast access from anywhere in the world
|
|
58
73
|
- 📦 **Auto-install** - Automatically downloads cloudflared if needed
|
|
59
74
|
- 🐍 **Simple API** - Clean, Pythonic interface
|
|
75
|
+
- 💻 **CLI Support** - Use from command line or as a library
|
|
76
|
+
- 🏷️ **Named Tunnels** - Support for dedicated URLs with tunnel tokens
|
|
60
77
|
|
|
61
78
|
## Usage
|
|
62
79
|
|
|
@@ -162,7 +179,31 @@ tunnel = Tunnel(8000, auto_download=False)
|
|
|
162
179
|
|
|
163
180
|
## API Reference
|
|
164
181
|
|
|
165
|
-
###
|
|
182
|
+
### Command Line Interface
|
|
183
|
+
|
|
184
|
+
```bash
|
|
185
|
+
suxitunnel [-h] -p PORT [--tunnel-token TUNNEL_TOKEN] [--local-https]
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
**Arguments:**
|
|
189
|
+
- `-p, --port PORT`: Local port to expose (required)
|
|
190
|
+
- `--tunnel-token TOKEN`: Cloudflare tunnel token for named tunnels (optional)
|
|
191
|
+
- `--local-https`: Connect to local server via HTTPS (for self-signed certs)
|
|
192
|
+
- `-h, --help`: Show help message
|
|
193
|
+
|
|
194
|
+
**Examples:**
|
|
195
|
+
```bash
|
|
196
|
+
# Quick tunnel with random URL
|
|
197
|
+
suxitunnel --port 8000
|
|
198
|
+
|
|
199
|
+
# Named tunnel with dedicated URL
|
|
200
|
+
suxitunnel --port 8000 --tunnel-token eyJhIjoiNz...
|
|
201
|
+
|
|
202
|
+
# Local HTTPS server (e.g., .NET Core with HTTPS)
|
|
203
|
+
suxitunnel --port 5001 --local-https
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
### `Tunnel(port, host="localhost", cloudflared_path=None, auto_download=True, tunnel_token=None, local_https=False)`
|
|
166
207
|
|
|
167
208
|
Create a tunnel to expose a local port.
|
|
168
209
|
|
|
@@ -171,19 +212,28 @@ Create a tunnel to expose a local port.
|
|
|
171
212
|
- `host` (str): Local hostname (default: "localhost")
|
|
172
213
|
- `cloudflared_path` (str): Path to cloudflared binary (auto-detected if None)
|
|
173
214
|
- `auto_download` (bool): Auto-download cloudflared if not found (default: True)
|
|
215
|
+
- `tunnel_token` (str): Cloudflare tunnel token for named tunnels (optional)
|
|
216
|
+
- `local_https` (bool): Set to True if local server uses HTTPS (default: False)
|
|
174
217
|
|
|
175
218
|
**Attributes:**
|
|
176
219
|
- `url` (str): Public HTTPS URL for the tunnel
|
|
177
220
|
- `port` (int): Local port being exposed
|
|
178
221
|
- `host` (str): Local hostname
|
|
222
|
+
- `tunnel_token` (str): Tunnel token if using named tunnel
|
|
179
223
|
- `is_alive()` (bool): Check if tunnel is running
|
|
180
224
|
- `close()`: Close the tunnel
|
|
181
225
|
|
|
182
226
|
**Example:**
|
|
183
227
|
```python
|
|
228
|
+
# Quick tunnel (random URL)
|
|
184
229
|
tunnel = Tunnel(8000)
|
|
185
230
|
print(tunnel.url) # https://abc123.trycloudflare.com
|
|
186
231
|
tunnel.close()
|
|
232
|
+
|
|
233
|
+
# Named tunnel (dedicated URL)
|
|
234
|
+
tunnel = Tunnel(8000, tunnel_token="your-token")
|
|
235
|
+
print(tunnel.url) # https://your-configured-domain.com
|
|
236
|
+
tunnel.close()
|
|
187
237
|
```
|
|
188
238
|
|
|
189
239
|
### `open_tunnel(port, host="localhost")`
|
|
@@ -237,12 +287,18 @@ Supported platforms:
|
|
|
237
287
|
|
|
238
288
|
## Limitations
|
|
239
289
|
|
|
240
|
-
|
|
290
|
+
**Quick Tunnels (default):**
|
|
291
|
+
1. **Random URLs**: Each tunnel gets a random `*.trycloudflare.com` URL
|
|
241
292
|
2. **Temporary**: Tunnels are meant for development/testing, not production
|
|
242
293
|
3. **No persistence**: URL changes each time you create a new tunnel
|
|
243
294
|
4. **Rate limits**: Subject to Cloudflare's fair use policy
|
|
244
295
|
|
|
245
|
-
|
|
296
|
+
**Named Tunnels (with `--tunnel-token`):**
|
|
297
|
+
- Requires a free Cloudflare account
|
|
298
|
+
- Provides persistent, dedicated URLs
|
|
299
|
+
- Better suited for staging/production environments
|
|
300
|
+
|
|
301
|
+
For setting up named tunnels, see the [Cloudflare Tunnel documentation](https://developers.cloudflare.com/cloudflare-one/connections/connect-apps/).
|
|
246
302
|
|
|
247
303
|
## Security Considerations
|
|
248
304
|
|
README.md
CHANGED
|
@@ -12,6 +12,21 @@ pip install suxitunnel
|
|
|
12
12
|
|
|
13
13
|
## Quick Start
|
|
14
14
|
|
|
15
|
+
### Command Line
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
# Expose local port 8000 (random URL)
|
|
19
|
+
suxitunnel --port 8000
|
|
20
|
+
|
|
21
|
+
# Or use short form
|
|
22
|
+
suxitunnel -p 8000
|
|
23
|
+
|
|
24
|
+
# Use a named tunnel with dedicated URL (requires Cloudflare account)
|
|
25
|
+
suxitunnel --port 8000 --tunnel-token YOUR_TOKEN
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
### Python API
|
|
29
|
+
|
|
15
30
|
```python
|
|
16
31
|
from suxitunnel import Tunnel
|
|
17
32
|
|
|
@@ -34,6 +49,8 @@ That's it! No configuration, no authentication, no manual setup.
|
|
|
34
49
|
- 🌍 **Global CDN** - Fast access from anywhere in the world
|
|
35
50
|
- 📦 **Auto-install** - Automatically downloads cloudflared if needed
|
|
36
51
|
- 🐍 **Simple API** - Clean, Pythonic interface
|
|
52
|
+
- 💻 **CLI Support** - Use from command line or as a library
|
|
53
|
+
- 🏷️ **Named Tunnels** - Support for dedicated URLs with tunnel tokens
|
|
37
54
|
|
|
38
55
|
## Usage
|
|
39
56
|
|
|
@@ -139,7 +156,31 @@ tunnel = Tunnel(8000, auto_download=False)
|
|
|
139
156
|
|
|
140
157
|
## API Reference
|
|
141
158
|
|
|
142
|
-
###
|
|
159
|
+
### Command Line Interface
|
|
160
|
+
|
|
161
|
+
```bash
|
|
162
|
+
suxitunnel [-h] -p PORT [--tunnel-token TUNNEL_TOKEN] [--local-https]
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
**Arguments:**
|
|
166
|
+
- `-p, --port PORT`: Local port to expose (required)
|
|
167
|
+
- `--tunnel-token TOKEN`: Cloudflare tunnel token for named tunnels (optional)
|
|
168
|
+
- `--local-https`: Connect to local server via HTTPS (for self-signed certs)
|
|
169
|
+
- `-h, --help`: Show help message
|
|
170
|
+
|
|
171
|
+
**Examples:**
|
|
172
|
+
```bash
|
|
173
|
+
# Quick tunnel with random URL
|
|
174
|
+
suxitunnel --port 8000
|
|
175
|
+
|
|
176
|
+
# Named tunnel with dedicated URL
|
|
177
|
+
suxitunnel --port 8000 --tunnel-token eyJhIjoiNz...
|
|
178
|
+
|
|
179
|
+
# Local HTTPS server (e.g., .NET Core with HTTPS)
|
|
180
|
+
suxitunnel --port 5001 --local-https
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
### `Tunnel(port, host="localhost", cloudflared_path=None, auto_download=True, tunnel_token=None, local_https=False)`
|
|
143
184
|
|
|
144
185
|
Create a tunnel to expose a local port.
|
|
145
186
|
|
|
@@ -148,19 +189,28 @@ Create a tunnel to expose a local port.
|
|
|
148
189
|
- `host` (str): Local hostname (default: "localhost")
|
|
149
190
|
- `cloudflared_path` (str): Path to cloudflared binary (auto-detected if None)
|
|
150
191
|
- `auto_download` (bool): Auto-download cloudflared if not found (default: True)
|
|
192
|
+
- `tunnel_token` (str): Cloudflare tunnel token for named tunnels (optional)
|
|
193
|
+
- `local_https` (bool): Set to True if local server uses HTTPS (default: False)
|
|
151
194
|
|
|
152
195
|
**Attributes:**
|
|
153
196
|
- `url` (str): Public HTTPS URL for the tunnel
|
|
154
197
|
- `port` (int): Local port being exposed
|
|
155
198
|
- `host` (str): Local hostname
|
|
199
|
+
- `tunnel_token` (str): Tunnel token if using named tunnel
|
|
156
200
|
- `is_alive()` (bool): Check if tunnel is running
|
|
157
201
|
- `close()`: Close the tunnel
|
|
158
202
|
|
|
159
203
|
**Example:**
|
|
160
204
|
```python
|
|
205
|
+
# Quick tunnel (random URL)
|
|
161
206
|
tunnel = Tunnel(8000)
|
|
162
207
|
print(tunnel.url) # https://abc123.trycloudflare.com
|
|
163
208
|
tunnel.close()
|
|
209
|
+
|
|
210
|
+
# Named tunnel (dedicated URL)
|
|
211
|
+
tunnel = Tunnel(8000, tunnel_token="your-token")
|
|
212
|
+
print(tunnel.url) # https://your-configured-domain.com
|
|
213
|
+
tunnel.close()
|
|
164
214
|
```
|
|
165
215
|
|
|
166
216
|
### `open_tunnel(port, host="localhost")`
|
|
@@ -214,12 +264,18 @@ Supported platforms:
|
|
|
214
264
|
|
|
215
265
|
## Limitations
|
|
216
266
|
|
|
217
|
-
|
|
267
|
+
**Quick Tunnels (default):**
|
|
268
|
+
1. **Random URLs**: Each tunnel gets a random `*.trycloudflare.com` URL
|
|
218
269
|
2. **Temporary**: Tunnels are meant for development/testing, not production
|
|
219
270
|
3. **No persistence**: URL changes each time you create a new tunnel
|
|
220
271
|
4. **Rate limits**: Subject to Cloudflare's fair use policy
|
|
221
272
|
|
|
222
|
-
|
|
273
|
+
**Named Tunnels (with `--tunnel-token`):**
|
|
274
|
+
- Requires a free Cloudflare account
|
|
275
|
+
- Provides persistent, dedicated URLs
|
|
276
|
+
- Better suited for staging/production environments
|
|
277
|
+
|
|
278
|
+
For setting up named tunnels, see the [Cloudflare Tunnel documentation](https://developers.cloudflare.com/cloudflare-one/connections/connect-apps/).
|
|
223
279
|
|
|
224
280
|
## Security Considerations
|
|
225
281
|
|
__init__.py
CHANGED
|
@@ -3,7 +3,7 @@ suxitunnel
|
|
|
3
3
|
A simple Python library to expose local servers using Cloudflare Tunnel
|
|
4
4
|
"""
|
|
5
5
|
|
|
6
|
-
from
|
|
6
|
+
from suxitunnel import Tunnel, TunnelError, open_tunnel
|
|
7
7
|
|
|
8
8
|
__version__ = "0.1.0"
|
|
9
9
|
__all__ = ["Tunnel", "TunnelError", "open_tunnel"]
|
pyproject.toml
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "suxitunnel"
|
|
3
|
-
version = "0.1.
|
|
3
|
+
version = "0.1.3"
|
|
4
4
|
description = "A simple Python library to expose local servers using Cloudflare Tunnel"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
license = "MIT"
|
|
@@ -22,6 +22,9 @@ dependencies = [
|
|
|
22
22
|
"requests>=2.32.0",
|
|
23
23
|
]
|
|
24
24
|
|
|
25
|
+
[project.scripts]
|
|
26
|
+
suxitunnel = "suxitunnel:main"
|
|
27
|
+
|
|
25
28
|
[project.urls]
|
|
26
29
|
Homepage = "https://github.com/sadwx/suxitunnel"
|
|
27
30
|
Repository = "https://github.com/sadwx/suxitunnel"
|
|
@@ -49,6 +52,7 @@ dev = [
|
|
|
49
52
|
"build>=1.4.0",
|
|
50
53
|
"fastapi>=0.128.0",
|
|
51
54
|
"flask>=3.1.2",
|
|
55
|
+
"pytest>=9.0.2",
|
|
52
56
|
"twine>=6.2.0",
|
|
53
57
|
"uvicorn>=0.40.0",
|
|
54
58
|
]
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: suxitunnel
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.3
|
|
4
4
|
Summary: A simple Python library to expose local servers using Cloudflare Tunnel
|
|
5
5
|
Project-URL: Homepage, https://github.com/sadwx/suxitunnel
|
|
6
6
|
Project-URL: Repository, https://github.com/sadwx/suxitunnel
|
|
@@ -35,6 +35,21 @@ pip install suxitunnel
|
|
|
35
35
|
|
|
36
36
|
## Quick Start
|
|
37
37
|
|
|
38
|
+
### Command Line
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
# Expose local port 8000 (random URL)
|
|
42
|
+
suxitunnel --port 8000
|
|
43
|
+
|
|
44
|
+
# Or use short form
|
|
45
|
+
suxitunnel -p 8000
|
|
46
|
+
|
|
47
|
+
# Use a named tunnel with dedicated URL (requires Cloudflare account)
|
|
48
|
+
suxitunnel --port 8000 --tunnel-token YOUR_TOKEN
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### Python API
|
|
52
|
+
|
|
38
53
|
```python
|
|
39
54
|
from suxitunnel import Tunnel
|
|
40
55
|
|
|
@@ -57,6 +72,8 @@ That's it! No configuration, no authentication, no manual setup.
|
|
|
57
72
|
- 🌍 **Global CDN** - Fast access from anywhere in the world
|
|
58
73
|
- 📦 **Auto-install** - Automatically downloads cloudflared if needed
|
|
59
74
|
- 🐍 **Simple API** - Clean, Pythonic interface
|
|
75
|
+
- 💻 **CLI Support** - Use from command line or as a library
|
|
76
|
+
- 🏷️ **Named Tunnels** - Support for dedicated URLs with tunnel tokens
|
|
60
77
|
|
|
61
78
|
## Usage
|
|
62
79
|
|
|
@@ -162,7 +179,31 @@ tunnel = Tunnel(8000, auto_download=False)
|
|
|
162
179
|
|
|
163
180
|
## API Reference
|
|
164
181
|
|
|
165
|
-
###
|
|
182
|
+
### Command Line Interface
|
|
183
|
+
|
|
184
|
+
```bash
|
|
185
|
+
suxitunnel [-h] -p PORT [--tunnel-token TUNNEL_TOKEN] [--local-https]
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
**Arguments:**
|
|
189
|
+
- `-p, --port PORT`: Local port to expose (required)
|
|
190
|
+
- `--tunnel-token TOKEN`: Cloudflare tunnel token for named tunnels (optional)
|
|
191
|
+
- `--local-https`: Connect to local server via HTTPS (for self-signed certs)
|
|
192
|
+
- `-h, --help`: Show help message
|
|
193
|
+
|
|
194
|
+
**Examples:**
|
|
195
|
+
```bash
|
|
196
|
+
# Quick tunnel with random URL
|
|
197
|
+
suxitunnel --port 8000
|
|
198
|
+
|
|
199
|
+
# Named tunnel with dedicated URL
|
|
200
|
+
suxitunnel --port 8000 --tunnel-token eyJhIjoiNz...
|
|
201
|
+
|
|
202
|
+
# Local HTTPS server (e.g., .NET Core with HTTPS)
|
|
203
|
+
suxitunnel --port 5001 --local-https
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
### `Tunnel(port, host="localhost", cloudflared_path=None, auto_download=True, tunnel_token=None, local_https=False)`
|
|
166
207
|
|
|
167
208
|
Create a tunnel to expose a local port.
|
|
168
209
|
|
|
@@ -171,19 +212,28 @@ Create a tunnel to expose a local port.
|
|
|
171
212
|
- `host` (str): Local hostname (default: "localhost")
|
|
172
213
|
- `cloudflared_path` (str): Path to cloudflared binary (auto-detected if None)
|
|
173
214
|
- `auto_download` (bool): Auto-download cloudflared if not found (default: True)
|
|
215
|
+
- `tunnel_token` (str): Cloudflare tunnel token for named tunnels (optional)
|
|
216
|
+
- `local_https` (bool): Set to True if local server uses HTTPS (default: False)
|
|
174
217
|
|
|
175
218
|
**Attributes:**
|
|
176
219
|
- `url` (str): Public HTTPS URL for the tunnel
|
|
177
220
|
- `port` (int): Local port being exposed
|
|
178
221
|
- `host` (str): Local hostname
|
|
222
|
+
- `tunnel_token` (str): Tunnel token if using named tunnel
|
|
179
223
|
- `is_alive()` (bool): Check if tunnel is running
|
|
180
224
|
- `close()`: Close the tunnel
|
|
181
225
|
|
|
182
226
|
**Example:**
|
|
183
227
|
```python
|
|
228
|
+
# Quick tunnel (random URL)
|
|
184
229
|
tunnel = Tunnel(8000)
|
|
185
230
|
print(tunnel.url) # https://abc123.trycloudflare.com
|
|
186
231
|
tunnel.close()
|
|
232
|
+
|
|
233
|
+
# Named tunnel (dedicated URL)
|
|
234
|
+
tunnel = Tunnel(8000, tunnel_token="your-token")
|
|
235
|
+
print(tunnel.url) # https://your-configured-domain.com
|
|
236
|
+
tunnel.close()
|
|
187
237
|
```
|
|
188
238
|
|
|
189
239
|
### `open_tunnel(port, host="localhost")`
|
|
@@ -237,12 +287,18 @@ Supported platforms:
|
|
|
237
287
|
|
|
238
288
|
## Limitations
|
|
239
289
|
|
|
240
|
-
|
|
290
|
+
**Quick Tunnels (default):**
|
|
291
|
+
1. **Random URLs**: Each tunnel gets a random `*.trycloudflare.com` URL
|
|
241
292
|
2. **Temporary**: Tunnels are meant for development/testing, not production
|
|
242
293
|
3. **No persistence**: URL changes each time you create a new tunnel
|
|
243
294
|
4. **Rate limits**: Subject to Cloudflare's fair use policy
|
|
244
295
|
|
|
245
|
-
|
|
296
|
+
**Named Tunnels (with `--tunnel-token`):**
|
|
297
|
+
- Requires a free Cloudflare account
|
|
298
|
+
- Provides persistent, dedicated URLs
|
|
299
|
+
- Better suited for staging/production environments
|
|
300
|
+
|
|
301
|
+
For setting up named tunnels, see the [Cloudflare Tunnel documentation](https://developers.cloudflare.com/cloudflare-one/connections/connect-apps/).
|
|
246
302
|
|
|
247
303
|
## Security Considerations
|
|
248
304
|
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
./.gitignore,sha256=Zj2M7GCQqPm6hifX5LW6RkR6DYgZUaz9a4oYrGtoqWM,477
|
|
2
|
+
./LICENSE,sha256=1QbfFX4K5Hc9fT1l8GK3N8RQEXz4L9HfZKdd8HKthPQ,1053
|
|
3
|
+
./PKG-INFO,sha256=vVIi4gqQVz5UOjTDily1X35GfJzutQZMkiH4ZLMLW8Y,11976
|
|
4
|
+
./README.md,sha256=8bFGdLIP9zXOtRoF2kU7VJ3OXqcUDAu18GloEsje0OI,10979
|
|
5
|
+
./__init__.py,sha256=kdD8ohA_FzNpfe3tH_afXQZmCs4XPE8Z4-0sTbIL1as,222
|
|
6
|
+
./pyproject.toml,sha256=GG2AVGsbo6CQaXv3vawscZoP0kPoCf_kF7dg5VIkMRk,1436
|
|
7
|
+
./suxitunnel.py,sha256=QJNgxPnefV90Lk2LYxMDxmcRiAnhE6c_NC8yTj_NSS4,12267
|
|
8
|
+
./examples/basic_example.py,sha256=H3pYsBoliHwevU07Pgd91mZXEQRII2mwoSzTAso3LXo,1025
|
|
9
|
+
./examples/context_manager.py,sha256=0uWx04VN_7kPwOiMnMuhWA3MCl5kIW-cAV4c7cJov1o,2808
|
|
10
|
+
./examples/fastapi_example.py,sha256=zG4dN7O4DgZr9KLs-xP2PWE1vCBQDd7CRWlaioa85Fw,1353
|
|
11
|
+
./examples/flask_example.py,sha256=aRmfRqGxzp41scbIgRQb3BOj3oa1KKarSYsSHLJCgms,1243
|
|
12
|
+
./examples/multiple_tunnels.py,sha256=6lamM7g0nYKvxwWD5bTcnvVfXg_19eZ_np0bYt5neZA,3228
|
|
13
|
+
suxitunnel-0.1.3.dist-info/METADATA,sha256=vVIi4gqQVz5UOjTDily1X35GfJzutQZMkiH4ZLMLW8Y,11976
|
|
14
|
+
suxitunnel-0.1.3.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
|
|
15
|
+
suxitunnel-0.1.3.dist-info/entry_points.txt,sha256=Y4OF_5gQ2TtS7cJuxBUa04uTb1JGvT7jHsRXARLZKXU,47
|
|
16
|
+
suxitunnel-0.1.3.dist-info/licenses/LICENSE,sha256=1QbfFX4K5Hc9fT1l8GK3N8RQEXz4L9HfZKdd8HKthPQ,1053
|
|
17
|
+
suxitunnel-0.1.3.dist-info/RECORD,,
|
suxitunnel.py
CHANGED
|
@@ -51,19 +51,25 @@ class Tunnel:
|
|
|
51
51
|
port: int,
|
|
52
52
|
host: str = "localhost",
|
|
53
53
|
cloudflared_path: Optional[str] = None,
|
|
54
|
-
auto_download: bool = True
|
|
54
|
+
auto_download: bool = True,
|
|
55
|
+
tunnel_token: Optional[str] = None,
|
|
56
|
+
local_https: bool = False
|
|
55
57
|
):
|
|
56
58
|
"""
|
|
57
59
|
Create a tunnel to expose a local port.
|
|
58
|
-
|
|
60
|
+
|
|
59
61
|
Args:
|
|
60
62
|
port: Local port to expose (e.g., 8000)
|
|
61
63
|
host: Local host (default: "localhost")
|
|
62
64
|
cloudflared_path: Path to cloudflared binary (auto-detected if None)
|
|
63
65
|
auto_download: Automatically download cloudflared if not found
|
|
66
|
+
tunnel_token: Cloudflare tunnel token for named tunnels (optional)
|
|
67
|
+
local_https: Set to True if local server uses HTTPS (default: False)
|
|
64
68
|
"""
|
|
65
69
|
self.port = port
|
|
66
70
|
self.host = host
|
|
71
|
+
self.tunnel_token = tunnel_token
|
|
72
|
+
self.local_https = local_https
|
|
67
73
|
self.url: Optional[str] = None
|
|
68
74
|
self._process: Optional[subprocess.Popen] = None
|
|
69
75
|
self._ready = threading.Event()
|
|
@@ -203,14 +209,29 @@ class Tunnel:
|
|
|
203
209
|
|
|
204
210
|
def _start(self):
|
|
205
211
|
"""Start the cloudflared tunnel"""
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
212
|
+
protocol = "https" if self.local_https else "http"
|
|
213
|
+
local_url = f"{protocol}://{self.host}:{self.port}"
|
|
214
|
+
|
|
215
|
+
if self.tunnel_token:
|
|
216
|
+
# Named tunnel with token
|
|
217
|
+
cmd = [
|
|
218
|
+
self.cloudflared_path,
|
|
219
|
+
"tunnel",
|
|
220
|
+
"--url", local_url,
|
|
221
|
+
"run",
|
|
222
|
+
"--token", self.tunnel_token
|
|
223
|
+
]
|
|
224
|
+
else:
|
|
225
|
+
# Quick tunnel (no authentication required)
|
|
226
|
+
cmd = [
|
|
227
|
+
self.cloudflared_path,
|
|
228
|
+
"tunnel",
|
|
229
|
+
"--url", local_url
|
|
230
|
+
]
|
|
231
|
+
|
|
232
|
+
# Add --no-tls-verify for local HTTPS servers with self-signed certs
|
|
233
|
+
if self.local_https:
|
|
234
|
+
cmd.append("--no-tls-verify")
|
|
214
235
|
|
|
215
236
|
try:
|
|
216
237
|
self._process = subprocess.Popen(
|
|
@@ -291,19 +312,77 @@ class Tunnel:
|
|
|
291
312
|
return f"<Tunnel port={self.port} url={self.url} status={status}>"
|
|
292
313
|
|
|
293
314
|
|
|
315
|
+
def parse_args(args: list[str] | None = None):
|
|
316
|
+
"""Parse command line arguments for the CLI."""
|
|
317
|
+
import argparse
|
|
318
|
+
|
|
319
|
+
parser = argparse.ArgumentParser(
|
|
320
|
+
prog="suxitunnel",
|
|
321
|
+
description="Expose local servers via Cloudflare Tunnel"
|
|
322
|
+
)
|
|
323
|
+
parser.add_argument(
|
|
324
|
+
"-p", "--port",
|
|
325
|
+
type=int,
|
|
326
|
+
required=True,
|
|
327
|
+
help="Local port to expose"
|
|
328
|
+
)
|
|
329
|
+
parser.add_argument(
|
|
330
|
+
"--tunnel-token",
|
|
331
|
+
type=str,
|
|
332
|
+
default=None,
|
|
333
|
+
help="Cloudflare tunnel token for named tunnels (optional)"
|
|
334
|
+
)
|
|
335
|
+
parser.add_argument(
|
|
336
|
+
"--local-https",
|
|
337
|
+
action="store_true",
|
|
338
|
+
default=False,
|
|
339
|
+
help="Use HTTPS to connect to local server (for servers with self-signed certs)"
|
|
340
|
+
)
|
|
341
|
+
|
|
342
|
+
return parser.parse_args(args)
|
|
343
|
+
|
|
344
|
+
|
|
294
345
|
def open_tunnel(port: int, host: str = "localhost") -> Tunnel:
|
|
295
346
|
"""
|
|
296
347
|
Convenience function to create a tunnel.
|
|
297
|
-
|
|
348
|
+
|
|
298
349
|
Args:
|
|
299
350
|
port: Local port to expose
|
|
300
351
|
host: Local host (default: "localhost")
|
|
301
|
-
|
|
352
|
+
|
|
302
353
|
Returns:
|
|
303
354
|
Tunnel instance
|
|
304
|
-
|
|
355
|
+
|
|
305
356
|
Example:
|
|
306
357
|
tunnel = open_tunnel(8000)
|
|
307
358
|
print(f"Public URL: {tunnel.url}")
|
|
308
359
|
"""
|
|
309
360
|
return Tunnel(port=port, host=host)
|
|
361
|
+
|
|
362
|
+
|
|
363
|
+
def main(args: list[str] | None = None) -> None:
|
|
364
|
+
"""CLI entry point for suxitunnel."""
|
|
365
|
+
parsed = parse_args(args)
|
|
366
|
+
|
|
367
|
+
tunnel = Tunnel(
|
|
368
|
+
port=parsed.port,
|
|
369
|
+
tunnel_token=parsed.tunnel_token,
|
|
370
|
+
local_https=parsed.local_https
|
|
371
|
+
)
|
|
372
|
+
|
|
373
|
+
print(f"Tunnel URL: {tunnel.url}")
|
|
374
|
+
print("Press Ctrl+C to stop the tunnel")
|
|
375
|
+
|
|
376
|
+
try:
|
|
377
|
+
while tunnel.is_alive():
|
|
378
|
+
time.sleep(1)
|
|
379
|
+
except KeyboardInterrupt:
|
|
380
|
+
pass
|
|
381
|
+
finally:
|
|
382
|
+
tunnel.close()
|
|
383
|
+
|
|
384
|
+
raise SystemExit(0)
|
|
385
|
+
|
|
386
|
+
|
|
387
|
+
if __name__ == "__main__":
|
|
388
|
+
main()
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
./.gitignore,sha256=Zj2M7GCQqPm6hifX5LW6RkR6DYgZUaz9a4oYrGtoqWM,477
|
|
2
|
-
./LICENSE,sha256=1QbfFX4K5Hc9fT1l8GK3N8RQEXz4L9HfZKdd8HKthPQ,1053
|
|
3
|
-
./PKG-INFO,sha256=-VEXmZc6Fp7x2KoA2Al1Z4GDUgs20zBLH49NaW8R7z4,10338
|
|
4
|
-
./README.md,sha256=OCBSHbI1lbi9uAPzoejKcGpj6QEw8Y9CqLfHFp8D328,9341
|
|
5
|
-
./__init__.py,sha256=b37S0Mt7B88CPV2j_xJ5VLSqrvMvF-_K-vuSpdmGWFo,223
|
|
6
|
-
./pyproject.toml,sha256=VEOdkiwYsvv2PDvKScFRyyIFhRIcKfapA__OGeceX38,1365
|
|
7
|
-
./suxitunnel.py,sha256=a5pULsz7kBz1nclGoz9fchL6xABLcg3BJ_f1ZgwU0zo,10126
|
|
8
|
-
./examples/basic_example.py,sha256=H3pYsBoliHwevU07Pgd91mZXEQRII2mwoSzTAso3LXo,1025
|
|
9
|
-
./examples/context_manager.py,sha256=0uWx04VN_7kPwOiMnMuhWA3MCl5kIW-cAV4c7cJov1o,2808
|
|
10
|
-
./examples/fastapi_example.py,sha256=zG4dN7O4DgZr9KLs-xP2PWE1vCBQDd7CRWlaioa85Fw,1353
|
|
11
|
-
./examples/flask_example.py,sha256=aRmfRqGxzp41scbIgRQb3BOj3oa1KKarSYsSHLJCgms,1243
|
|
12
|
-
./examples/multiple_tunnels.py,sha256=6lamM7g0nYKvxwWD5bTcnvVfXg_19eZ_np0bYt5neZA,3228
|
|
13
|
-
suxitunnel-0.1.2.dist-info/METADATA,sha256=-VEXmZc6Fp7x2KoA2Al1Z4GDUgs20zBLH49NaW8R7z4,10338
|
|
14
|
-
suxitunnel-0.1.2.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
|
|
15
|
-
suxitunnel-0.1.2.dist-info/licenses/LICENSE,sha256=1QbfFX4K5Hc9fT1l8GK3N8RQEXz4L9HfZKdd8HKthPQ,1053
|
|
16
|
-
suxitunnel-0.1.2.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|