Skip to content

Commit a250698

Browse files
committed
Merge branch 'dev'
2 parents 18ba822 + cc7f9ea commit a250698

28 files changed

Lines changed: 1870 additions & 84 deletions

README.md

Lines changed: 48 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
[![License](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)
1010
[![Monthly Downloads](https://pepy.tech/badge/flaredantic/month)](https://pepy.tech/project/flaredantic)
1111

12-
Flaredantic is a Python library that simplifies the process of creating tunnels to expose your local services to the internet. It supports both Cloudflare and Serveo tunneling services, making it a user-friendly alternative to ngrok, localtunnel, and similar tools.
12+
Flaredantic is a Python library that simplifies the process of creating tunnels to expose your local services to the internet. It supports Cloudflare, Serveo, and Microsoft Dev Tunnel services, making it a user-friendly alternative to ngrok, localtunnel, and similar tools.
1313

1414
</div>
1515

@@ -20,7 +20,7 @@ Flaredantic is a Python library that simplifies the process of creating tunnels
2020
- 🚀 Easy-to-use Python API
2121
- 💻 Command-line interface (CLI)
2222
- 📦 Automatic binary management
23-
- 🔄 Multiple tunnel providers (Cloudflare, Serveo)
23+
- 🔄 Multiple tunnel providers (Cloudflare, Serveo, Microsoft Dev Tunnels)
2424
- 🌐 TCP forwarding support (Serveo)
2525
- 🎯 Cross-platform support (Windows, macOS, Linux)
2626
- 📱 Android support via Termux
@@ -39,6 +39,8 @@ While tools like ngrok are great, Flaredantic offers several advantages:
3939

4040
Flaredantic makes it dead simple to use tunnels in your Python projects!
4141

42+
> ⚠️ **Warning:** Exposing local services to the internet can be a security risk. Never expose sensitive or unprotected endpoints. Use at your own risk.
43+
4244
## 🚀 Installation
4345

4446
```bash
@@ -60,6 +62,9 @@ flare --port 8080 -v
6062
# Use Serveo tunnel instead
6163
flare --port 8080 --tunnel serveo
6264

65+
# Use Microsoft Dev Tunnels
66+
flare --port 8080 --tunnel microsoft
67+
6368
# TCP forwarding with Serveo
6469
flare --port 5432 --tcp
6570
```
@@ -69,7 +74,7 @@ CLI Options:
6974
-p, --port Local port to expose (required)
7075
-t, --timeout Tunnel start timeout in seconds (default: 30)
7176
-v, --verbose Show detailed progress output
72-
--tunnel Tunnel provider to use [cloudflare, serveo] (default: cloudflare)
77+
--tunnel Tunnel provider to use [cloudflare, serveo, microsoft] (default: cloudflare)
7378
--tcp Use Serveo with TCP forwarding (overrides --tunnel)
7479
```
7580

@@ -101,6 +106,19 @@ with ServeoTunnel(config) as tunnel:
101106
input("Press Enter to stop the tunnel...")
102107
```
103108

109+
#### Basic Usage with Microsoft Dev Tunnels
110+
111+
```python
112+
from flaredantic import MicrosoftTunnel, MicrosoftConfig
113+
114+
# Create a tunnel using Microsoft Dev Tunnels
115+
config = MicrosoftConfig(port=8080)
116+
with MicrosoftTunnel(config) as tunnel:
117+
print(f"Your service is available at: {tunnel.tunnel_url}")
118+
# Your application code here
119+
input("Press Enter to stop the tunnel...")
120+
```
121+
104122
#### TCP Forwarding with Serveo
105123

106124
```python
@@ -119,6 +137,7 @@ with ServeoTunnel(config) as tunnel:
119137
```python
120138
from flaredantic import FlareTunnel, FlareConfig
121139
from flaredantic import ServeoTunnel, ServeoConfig
140+
from flaredantic import MicrosoftTunnel, MicrosoftConfig
122141
from pathlib import Path
123142

124143
# Configure Cloudflare tunnel with custom settings
@@ -137,8 +156,18 @@ serveo_config = ServeoConfig(
137156
verbose=True # Enable detailed logging
138157
)
139158

159+
# Configure Microsoft Dev Tunnels with custom settings
160+
microsoft_config = MicrosoftConfig(
161+
port=8080,
162+
bin_dir=Path.home() / ".my-tunnels",
163+
timeout=60,
164+
verbose=True, # Enable detailed logging
165+
tunnel_id="flaredantic", # Custom tunnel ID
166+
device_login=True # Use device login flow
167+
)
168+
140169
# Create and start tunnel (choose one)
141-
with FlareTunnel(cloudflare_config) as tunnel:
170+
with MicrosoftTunnel(microsoft_config) as tunnel:
142171
print(f"Access your service at: {tunnel.tunnel_url}")
143172
input("Press Enter to stop the tunnel...")
144173
```
@@ -189,10 +218,23 @@ if __name__ == '__main__':
189218
| verbose | bool | False | Show detailed progress and debug output |
190219
| tcp | bool | False | Enable TCP forwarding instead of HTTP |
191220

221+
### Microsoft Dev Tunnels Options
222+
223+
| Option | Type | Default | Description |
224+
|--------|------|---------|-------------|
225+
| port | int | Required | Local port to expose |
226+
| bin_dir | Path | ~/.flaredantic | Directory for devtunnel binary |
227+
| timeout | int | 30 | Tunnel start timeout in seconds |
228+
| verbose | bool | False | Show detailed progress and debug output |
229+
| tunnel_id | str | "flaredantic" | Custom tunnel ID |
230+
| device_login | bool | True | Use device login flow |
231+
192232
## 📦 Requirements
193233

194234
- **Cloudflare tunnel**: No additional requirements (binary auto-downloaded)
195235
- **Serveo tunnel**: Requires SSH client to be installed
236+
- **Microsoft Dev Tunnels**: No additional requirements (binary auto-downloaded)
237+
- **Note**: Currently only supports Linux and macOS.
196238

197239
> **❗️Note:** Serveo servers might occasionally be unavailable as they are a free service. Flaredantic automatically detects when Serveo is down and provides a clear error message. Consider using Cloudflare tunnels if you need guaranteed availability.
198240
@@ -201,5 +243,6 @@ if __name__ == '__main__':
201243
For more detailed examples and use cases, check out our examples:
202244
- [Cloudflare Examples](docs/examples/Cloudflare.md) - HTTP Server, Django, FastAPI, Flask
203245
- [Serveo Examples](docs/examples/Serveo.md) - HTTP, TCP, SSH forwarding, database access
246+
- [Microsoft Examples](docs/examples/Microsoft.md) - HTTP Server, Custom Tunnel ID, Device Login
204247

205-
---
248+
---

docs/examples/Microsoft.md

Lines changed: 182 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,182 @@
1+
# Flaredantic Microsoft Dev Tunnels Examples 📚
2+
3+
This document provides various examples of how to use Flaredantic with Microsoft Dev Tunnelss in different scenarios.
4+
5+
## Basic Examples
6+
7+
### Simple HTTP Server
8+
```python
9+
from http.server import HTTPServer, SimpleHTTPRequestHandler
10+
from flaredantic import MicrosoftTunnel, MicrosoftConfig
11+
import threading
12+
import time
13+
14+
# Create a basic HTTP server
15+
server = HTTPServer(('localhost', 8000), SimpleHTTPRequestHandler)
16+
server_thread = threading.Thread(target=server.serve_forever, daemon=True)
17+
server_thread.start()
18+
19+
# Create and start tunnel
20+
config = MicrosoftConfig(port=8000)
21+
with MicrosoftTunnel(config) as tunnel:
22+
print(f"Server accessible at: {tunnel.tunnel_url}")
23+
try:
24+
while True:
25+
time.sleep(1)
26+
except KeyboardInterrupt:
27+
print("\nStopping server...")
28+
```
29+
30+
### Custom Tunnel ID
31+
You can reuse a specific tunnel ID if available:
32+
```python
33+
from flaredantic import MicrosoftTunnel, MicrosoftConfig
34+
35+
config = MicrosoftConfig(
36+
port=8080,
37+
tunnel_id="my-custom-tunnel-id",
38+
verbose=True
39+
)
40+
41+
with MicrosoftTunnel(config) as tunnel:
42+
print(f"Tunnel URL: {tunnel.tunnel_url}")
43+
input("Press Enter to stop...")
44+
```
45+
46+
## Account Management
47+
48+
### Changing Accounts / Logging Out
49+
If you need to switch accounts or force a re-login, you can manually use the binary that `flaredantic` manages.
50+
51+
The binary is located in `~/.flaredantic/microsoft` (or your custom `bin_dir`).
52+
53+
**To logout:**
54+
```bash
55+
# Navigate to the binary directory
56+
cd ~/.flaredantic/
57+
58+
# Run the logout command
59+
./devtunnel user logout
60+
```
61+
62+
After logging out, the next time you run your Python script with `MicrosoftTunnel`, it will prompt you for a new device login.
63+
64+
**To check current login status:**
65+
```bash
66+
cd ~/.flaredantic/
67+
./devtunnel user show
68+
```
69+
70+
## Advanced Examples
71+
72+
### Device Login Flow
73+
Microsoft Dev Tunnelss support device login authentication (enabled by default):
74+
```python
75+
from flaredantic import MicrosoftTunnel, MicrosoftConfig
76+
77+
config = MicrosoftConfig(
78+
port=8080,
79+
device_login=True, # Enable device login flow
80+
verbose=True # Show login code and instructions
81+
)
82+
83+
# First run will prompt: "Browse to https://github.com/login/device and enter code: XXXX"
84+
with MicrosoftTunnel(config) as tunnel:
85+
print(f"Tunnel URL: {tunnel.tunnel_url}")
86+
input("Press Enter to stop...")
87+
```
88+
89+
### FastAPI Integration
90+
```python
91+
import uvicorn
92+
from fastapi import FastAPI
93+
from flaredantic import MicrosoftTunnel, MicrosoftConfig
94+
import threading
95+
96+
app = FastAPI()
97+
98+
@app.get("/")
99+
def read_root():
100+
return {"status": "online", "provider": "Microsoft Dev Tunnels"}
101+
102+
def start_tunnel():
103+
config = MicrosoftConfig(port=8000)
104+
tunnel = MicrosoftTunnel(config)
105+
url = tunnel.start()
106+
print(f"FastAPI app available at: {url}")
107+
return tunnel
108+
109+
if __name__ == "__main__":
110+
# Start tunnel in background
111+
tunnel = start_tunnel()
112+
113+
try:
114+
uvicorn.run(app, host="127.0.0.1", port=8000)
115+
finally:
116+
tunnel.stop()
117+
```
118+
119+
### Django Integration
120+
```python
121+
import os
122+
import sys
123+
import time
124+
import threading
125+
from flaredantic import MicrosoftTunnel, MicrosoftConfig
126+
from django.core.management import execute_from_command_line
127+
128+
def run_tunnel():
129+
config = MicrosoftConfig(port=8000)
130+
with MicrosoftTunnel(config) as tunnel:
131+
print(f"Django site available at: {tunnel.tunnel_url}")
132+
# Keep tunnel alive
133+
try:
134+
while True:
135+
time.sleep(1)
136+
except KeyboardInterrupt:
137+
pass
138+
139+
if __name__ == "__main__":
140+
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'mysite.settings')
141+
142+
# Start tunnel in background
143+
tunnel_thread = threading.Thread(target=run_tunnel, daemon=True)
144+
tunnel_thread.start()
145+
146+
execute_from_command_line(sys.argv)
147+
```
148+
149+
## Error Handling Examples
150+
151+
### Connection Retry Logic
152+
```python
153+
from flaredantic import MicrosoftTunnel, MicrosoftConfig, TunnelError
154+
import time
155+
156+
def create_tunnel_with_retry(port: int, max_retries: int = 3):
157+
config = MicrosoftConfig(port=port, verbose=True)
158+
159+
for attempt in range(max_retries):
160+
try:
161+
tunnel = MicrosoftTunnel(config)
162+
tunnel.start()
163+
return tunnel
164+
except TunnelError as e:
165+
if attempt == max_retries - 1:
166+
raise
167+
print(f"Attempt {attempt + 1} failed: {e}. Retrying...")
168+
time.sleep(2)
169+
```
170+
171+
## Common Issues and Solutions
172+
173+
### Login Required
174+
If the tunnel fails to start with login errors:
175+
1. Ensure `verbose=True` is set to see the login code.
176+
2. Complete the device login flow at https://github.com/login/device.
177+
3. The token is cached locally, so subsequent runs won't require login.
178+
179+
### Port Conflicts
180+
If you see "hosting port" errors:
181+
- Ensure the local service is running on the specified port.
182+
- Check if another tunnel is already using the same `tunnel_id`.

0 commit comments

Comments
 (0)