Python — mekong-tunnel
mekong-tunnel is the official PyPI package for MekongTunnel. It provides:
- Drop-in CLI wrappers for popular Python web frameworks (
mekong-fastapi,mekong-flask, etc.) - A Python SDK (
import mekong_tunnel as mekong) for programmatic use - Auth helpers that read your saved login token automatically
PyPI: pypi.org/project/mekong-tunnel (opens in a new tab)
Installation
pip install mekong-tunnel
# or
uv add mekong-tunnel
# or
poetry add mekong-tunnelThe
mekongbinary (Go) is required separately. See Installation.
How It Works
Instead of running your server directly, use a mekong-* wrapper command. It:
- Starts your Python server (passing through all your arguments)
- Launches a MekongTunnel in the background
- Prints the public URL — and optionally opens it in your browser
mekong-fastapi → uvicorn main:app + tunnel
mekong-flask → flask run + tunnel
mekong-django → manage.py runserver + tunnel
mekong-uvicorn → uvicorn + tunnel
mekong-gunicorn → gunicorn + tunnel
mekong-hypercorn → hypercorn + tunnel
mekong-granian → granian + tunnelModes
All commands support two modes:
| Flag | Description |
|---|---|
--local | Start server on localhost, open browser at http://localhost:PORT |
--domain | Start server + tunnel, open browser at public tunnel URL |
| (no flag) | Start server + tunnel, print URL only |
Authentication
All commands and the SDK pick up your token automatically once you run mekong login:
mekong login
# Opens browser → approve → saved to ~/.mekong/config.json
# Every subsequent tunnel uses your reserved subdomainToken resolution order:
--token <tok>flag (CLI wrappers) ortoken=argument (SDK)MEKONG_TOKENenvironment variable~/.mekong/config.json(written bymekong login)- (none — anonymous mode, random subdomain)
Pass a token explicitly on any wrapper command:
mekong-fastapi --token mkt_xxxxxxxxxxxx main:app --port 8000Or use an environment variable (great for CI/CD):
MEKONG_TOKEN=mkt_xxx mekong-fastapi main:app --port 8000Get a token: Dashboard → API Tokens
Python SDK
Use the SDK to control tunnels programmatically — great for test setups, integration tests, or custom tooling.
import mekong_tunnel as mekongexpose(port, **opts) → Tunnel
Start a tunnel and get the public URL:
tunnel = mekong.expose(8000)
print(tunnel.url) # https://myapp.mekongtunnel.dev
tunnel.stop()With options:
tunnel = mekong.expose(8000,
token='mkt_xxx', # override saved token
expire='2h',
no_qr=True,
)Token resolution:
token=argument →MEKONG_TOKENenv →~/.mekong/config.json.
Context manager
Use with to automatically stop the tunnel when you're done:
with mekong.expose(8000) as t:
print(t.url) # tunnel is live inside the block
# tunnel stopped automaticallylogin(open_browser=True) → str
Authenticate via the browser device flow — same as mekong login in the terminal:
token = mekong.login()
# Opens mekongtunnel.dev/cli-auth in the browser,
# polls until you approve, then saves ~/.mekong/config.json.
print('Token:', token)logout()
Remove saved credentials:
mekong.logout()whoami() → dict | None
Return saved auth config:
info = mekong.whoami()
# {'token': 'mkt_xxx', 'email': 'you@example.com'} or Noneget_token() → str | None
Read the token from env or saved config without starting anything:
token = mekong.get_token()pytest integration example
import pytest
import mekong_tunnel as mekong
@pytest.fixture(scope='session')
def public_url():
with mekong.expose(8000) as t:
yield t.url
def test_home(public_url):
import urllib.request
res = urllib.request.urlopen(public_url)
assert res.status == 200Framework Guides
Choose your framework from the sidebar:
- FastAPI — async ASGI with automatic docs
- Flask — lightweight WSGI microframework
- Django — full-stack web framework
- Uvicorn / Gunicorn — raw ASGI/WSGI servers
- Starlette / Granian — minimal ASGI + modern server
Version
Current version: v2.1.0 — pypi.org/project/mekong-tunnel (opens in a new tab)
Requirements
- Python 3.8+
mekongbinary installed — see Installation- macOS, Linux, or Windows (WSL recommended)