# colab-tunnel Библиотека для публичного туннелирования локальных портов в Google Colab. Поддерживает в настоящий момент 15 провайдеров, работает молча — выдаёт ссылку без лишних действий со стороны пользователя. ![example](https://github.com/user-attachments/assets/20c8b870-2295-49d1-bd78-1f68b274df6e) ```python from colab_tunnel import get_share_link link = get_share_link('srvus', 7860) print(link) ``` --- ## Установка ```bash uv pip install colab-tunnel ``` ```bash pip install colab-tunnel ``` ```bash uv add colab-tunnel ``` --- ## Быстрый старт ```python from colab_tunnel import get_share_link # Один провайдер link = get_share_link('gradio', 7860) # Все провайдеры параллельно links = get_share_link('all', 7860) ``` --- ## Провайдеры | Имя | Старт | RTT | Примечания | |----------------|-------|--------|--------------------------------------------| | `srvus` | ~0.4с | ~200мс | Один из быстрейших | | `bore` | ~0.5с | ~150мс | Минимальная задержка | | `localt` | ~0.3с | ~300мс | | | `localhostrun` | ~0.7с | ~200мс | | | `gradio` | ~0.5с | ~200мс | | | `tmole` | ~1.5с | ~350мс | | | `beeceptor` | ~2с | ~400мс | | | `optimistix` | ~1.5с | ~500мс | | | `mmar` | ~1с | ~600мс | | | `serveo` | ~1.5с | ~700мс | | | `boredigital` | ~1.5с | ~900мс | | | `cloudflared` | ~4с | ~400мс | Warmup ~15с после старта | | `tunnelite` | ~4с | ~300мс | | | `native` | ~2с | — | Только в Colab, требует Google-авторизации | | `tunwg` | — | — | Отключён: сервис временно недоступен | SSH-провайдеры (`srvus`, `serveo`, `localhostrun`, `optimistix`) используют стандартный SSH-ключ системы, при необходимости генерируется автоматически. --- ## API ### `get_share_link(host, port)` Получить публичную ссылку через указанный провайдер. ```python from colab_tunnel import get_share_link link = get_share_link('gradio', 7860) # host='all' — запустить всех параллельно, вернуть все ссылки links = get_share_link('all', 7860) ``` --- ### `try_all(port)` Параллельно запускает всех активных провайдеров, возвращает все полученные ссылки. ```python from colab_tunnel import try_all print(try_all(7860)) # gradio: https://...gradio.live # bore: http://bore.pub:XXXXX/ # srvus: https://...srv.us # ... ``` --- ### `benchmark(providers, timeout_per_provider, latency_timeout, print_report)` Последовательно тестирует провайдеров с замером времени старта и RTT. Требует бинарник `test_server` из папки проекта. ```python from colab_tunnel import benchmark results = benchmark() # Бенчмарк: 14 провайдеров, порт XXXXX. # [srvus ] OK (0.43с). Проверка... RTT 174мс # [bore ] OK (0.81с). Проверка... RTT 125мс # ... # Итого: 14/14 провайдеров работают. # Минимальная задержка: bore (125мс) # Выборочно results = benchmark(providers=['cloudflared', 'bore', 'gradio']) # Результаты — список TunnelBenchmarkResult for r in results: print(r.name, r.tunnel_time, r.latency, r.url) ``` Путь к `test_server` определяется автоматически: 1. Переменная окружения `TEST_SERVER_PATH` 2. `../test_server/test_server` относительно пакета 3. `./test_server/test_server` относительно CWD --- ### Управление провайдерами ```python from colab_tunnel import list_providers, disable_provider, enable_provider # Статус всех провайдеров list_providers() # {'tmole': True, 'tunwg': False, 'cloudflared': True, ...} # Отключить нерабочий disable_provider('tunwg') # Включить обратно enable_provider('tunwg') ``` Отключённый провайдер не попадает в `get_share_link('all', ...)`, `try_all()` и `benchmark()`, но его функция (`get_tunwg_url`) остаётся доступна напрямую. --- ### Утилиты ```python from colab_tunnel import download, run, WORK_FOLDER # Скачать файл с прогрессом path = download('https://example.com/file.tar.gz', save_path='/tmp') # Выполнить shell-команду result = run('echo hello', timeout=10) print(result['status_code'], result['output']) # Рабочая папка (по умолчанию /content/.config) print(WORK_FOLDER) ``` --- ## Конфигурация | Переменная окружения | По умолчанию | Описание | |----------------------|--------------------|------------------------------------| | `TUNNEL_WORK_DIR` | `/content/.config` | Папка для бинарников и кэша | | `TEST_SERVER_PATH` | — | Путь к бинарнику тестового сервера | ```python import os os.environ['TUNNEL_WORK_DIR'] = '/tmp/tunnels' from colab_tunnel import get_share_link # подхватит новый путь ``` > **Важно:** переменная `TUNNEL_WORK_DIR` должна быть установлена **до** первого импорта `colab_tunnel`. --- ## Добавление своего провайдера ```python from colab_tunnel import tunnel_provider, get_share_link @tunnel_provider('myprovider') def get_myprovider_url(port: int) -> str: # Запустить бинарник/SSH и вернуть публичный URL return 'https://...' # Провайдер сразу доступен link = get_share_link('myprovider', 7860) ``` Для провайдеров на основе бинарных утилит удобно использовать `get_revproxy_url`: ```python from colab_tunnel._tunnels import get_revproxy_url from colab_tunnel._config import WORK_FOLDER from colab_tunnel import tunnel_provider @tunnel_provider('myprovider') def get_myprovider_url(port: int) -> str: return get_revproxy_url( bin_url='https://example.com/mytunnel-linux-amd64', need_unpack=False, bin_path=WORK_FOLDER / 'mytunnel', start_commands=[str(WORK_FOLDER / 'mytunnel'), str(port)], read_from_stderr=False, url_pattern=r'https://\S+\.mytunnel\.io', timeout=20.0, ) ``` --- ## Разработка ```bash git clone --depth 1 https://github.com/imbecility/colab-tunnel cd colab-tunnel pip install -e ".[dev]" # Запустить тесты (не требуют сети) pytest tests/ # Тесты регулярных выражений провайдеров pytest tests/test_regex.py -v # Тесты утилит (требуют Unix) pytest tests/test_utils.py -v ``` ### Структура проекта ``` colab_tunnel/ ├── __init__.py # Публичный API ├── _config.py # Пути и HTTP-заголовки ├── _logger.py # Логгер (по умолчанию WARNING) ├── _registry.py # Реестр провайдеров (@tunnel_provider) ├── _utils.py # Утилиты: процессы, сеть, архивы ├── _tunnels.py # Провайдеры на основе бинарников ├── _ssh.py # SSH-провайдеры └── _diagnostics.py # Бенчмарк tests/ ├── test_regex.py # Валидация regex-паттернов провайдеров └── test_utils.py # Тесты утилитарных функций ``` ### Детальный лог ```python import logging logging.getLogger('colab_tunnel').setLevel(logging.DEBUG) ``` --- ## Лицензия MIT