telemt-sdk
Асинхронный типизированный Python SDK для Telemt Control API.
Быстрый старт · Справочник API · Участие в разработке · Сообщить об ошибке
🤝 Спонсор проекта — Peakora VPN
Защищённый доступ в интернет и к AI-сервисам с подключением через Telegram.
Подробнее о Peakora →
Управляйте пользователями прокси, квотами, конфигурацией, диагностикой и WEB-сессиями из Python.
TelemtClient объединяет операции в ресурсные объекты, переиспользует HTTP-соединения
и возвращает Pydantic-модели с конкретными аннотациями типов, включая вложенные данные.
- 48 операций API: пользователи, состояние сервиса, статистика, перезагрузка и управление WEB runtime.
- Полностью асинхронный интерфейс:
async with,awaitи параллельное чтение черезasyncio.gather. - Типизированные запросы и ответы: валидация входных данных, подсказки IDE и маркер
py.typed. - Контроль конкурентных изменений: передача ревизии ответа для защиты обновлений конфигурации.
- Понятные ошибки: отдельные классы исключений сохраняют HTTP-статус, код Telemt и идентификатор запроса.
SDK работает с HTTP API управления Telemt. Передачу MTProto-трафика и подключения клиентов Telegram обеспечивает сам Telemt.
Установка
Требуется Python 3.13, 3.14 или 3.15. Имя пакета — telemt-sdk, имя импорта — telemt.
После появления релиза в PyPI:
uv add telemt-sdk
Или через pip:
python -m pip install telemt-sdk
До первого релиза можно работать из клонированного репозитория: выполните uv sync --locked
в его каталоге. Зависимости SDK — HTTPX
и Pydantic.
Быстрый старт
Включите Control API в конфигурации Telemt и задайте TELEMT_AUTH_HEADER равным точному
значению server.api.auth_header. Этот пример читает состояние сервера:
import asyncio
import os
from telemt import TelemtClient
async def main() -> None:
async with TelemtClient(
"http://127.0.0.1:9091",
auth_header=os.environ["TELEMT_AUTH_HEADER"],
) as client:
health = await client.health.get()
print(health.data.status)
users = await client.users.list()
for user in users.data:
print(user.username, user.enabled, user.current_connections)
asyncio.run(main())
SDK передаёт auth_header в заголовке Authorization без изменений и не добавляет Bearer.
Если на сервере настроено значение Bearer ..., передавайте строку целиком.
Если авторизация не настроена, аргумент можно опустить. Используйте адрес слушателя
Control API, а не порт MTProto или WEB ingress.
Настройка клиента
| Аргумент | По умолчанию | Назначение |
|---|---|---|
base_url |
Обязателен | Абсолютный HTTP(S) URL. /v1 добавляется, если отсутствует. Префикс reverse proxy сохраняется. |
auth_header |
None |
Точное значение заголовка Authorization, настроенного на сервере. |
timeout |
30.0 |
Тайм-аут HTTPX в секундах или httpx.Timeout с отдельными лимитами подключения, чтения, записи и ожидания соединения. |
http_client |
None |
Необязательный httpx.AsyncClient для настройки TLS, прокси, транспорта и пула соединений. |
Адреса https://proxy.example.com/control и https://proxy.example.com/control/v1
оба направляют запросы в /control/v1/.... Учётные данные, query-параметры и фрагменты
в base_url не допускаются.
Используйте один клиент для нескольких запросов в пределах одного event loop:
health, stats = await asyncio.gather(client.health.get(), client.stats.summary())
print(stats.data.connections_total)
Закрывайте соединения через async with или await client.aclose(). Закрытый клиент
нельзя использовать повторно. Если вы передаёте собственный HTTPX-клиент, его временем
жизни управляете вы:
import httpx
async with httpx.AsyncClient(limits=httpx.Limits(max_connections=20)) as http:
async with TelemtClient(
"https://proxy.example.com",
auth_header=auth_header,
timeout=httpx.Timeout(30.0, connect=5.0),
http_client=http,
) as client:
info = await client.system.info()
Параметры SDK и явно переданная авторизация имеют приоритет над настройками HTTPX. Редиректы и автоматические повторы запросов отключены: изменение могло дойти до сервера до истечения тайм-аута.
Пользователи и квоты
from telemt.models import CreateUserRequest, PatchUserRequest, RotateSecretRequest
created = await client.users.create(
CreateUserRequest(
username="alice",
max_tcp_conns=10,
data_quota_bytes=10_000_000_000,
quota_period="monthly",
)
)
# created.data.secret содержит сгенерированный секрет; не записывайте его в логи.
print(created.data.user.username)
updated = await client.users.update(
"alice",
PatchUserRequest(max_tcp_conns=20, expiration_rfc3339="2027-01-01T00:00:00Z"),
revision=created.revision,
)
rotated = await client.users.rotate_secret("alice", RotateSecretRequest())
await client.users.reset_quota("alice")
await client.users.disable("alice")
await client.users.enable("alice")
# Удаляйте пользователя явно, когда учётная запись больше не нужна:
# await client.users.delete("alice")
Секреты и рекламные теги состоят из 32 шестнадцатеричных символов. Имя пользователя
содержит от 1 до 64 латинских букв, цифр, точек, дефисов или подчёркиваний. Имена .
и .. отклоняются, поскольку HTTPX нормализует такие сегменты пути. Для периодического
сброса квоты доступны daily, weekly и monthly; при создании пользователя требуется
положительное значение data_quota_bytes.
Семантика PATCH
Пропущенное поле, None и ноль имеют разное значение:
| Запрос | Результат |
|---|---|
PatchUserRequest() |
Оставить настройки без изменений. |
PatchUserRequest(max_tcp_conns=None) |
Удалить индивидуальное ограничение пользователя. |
PatchUserRequest(max_tcp_conns=0) |
Передать явный ноль; его смысл для этой настройки определяет Telemt. |
PatchUserRequest(enabled=False) |
Отключить пользователя. |
PatchUserRequest(secret=None) |
Оставить секрет без изменений, как это делает Telemt. |
Для генерации нового секрета используйте rotate_secret(). Модели запросов отклоняют
неизвестные поля и недопустимые значения. Проверки, зависящие от состояния сервера,
например существование пользователя, выполняет Telemt и возвращает соответствующую ошибку API.
Ответы и ревизии
Каждый метод возвращает APIResponse[T]:
| Поле | Тип | Назначение |
|---|---|---|
data |
T |
Типизированный результат операции, например UserInfo или list[UserInfo]. |
revision |
str |
Ревизия конфигурации сервера для этого ответа. |
status_code |
int |
Фактический HTTP-статус ответа. |
ok |
Literal[True] |
Успешно разобранный ответ API. |
Вложенные данные тоже представлены моделями: user.links.tls_domains[0].domain
и status.runtime.manager.issuance_enabled доступны проверке типов после проверки
nullable-полей на None. Модели импортируются из telemt.models.
current = await client.users.get("alice")
await client.users.update(
"alice",
PatchUserRequest(max_tcp_conns=30),
revision=current.revision,
)
Аргумент revision= передаётся в заголовок If-Match. Устаревшая ревизия вызывает
ConflictError. Перечитайте состояние и проверьте, остаётся ли изменение актуальным,
прежде чем повторять запрос. Клиент не хранит общую ревизию и не подставляет её автоматически,
поэтому параллельные ответы независимы. WEB-операции используют runtime_instance.
Новые поля сервера сохраняются в model_extra. Для представления, совместимого с JSON,
используйте model_dump(mode="json", by_alias=True). Разделы конфигурации остаются
dict[str, JsonValue], поскольку это расширяемые конфигурационные данные;
известные структуры телеметрии и WEB описаны отдельными моделями.
Конфигурация и перезагрузка
from telemt.models import PatchConfigRequest, ReloadRequest
current = await client.config.get()
changed = await client.config.update(
PatchConfigRequest(censorship={"tls_domain": "front.example.com"}),
revision=current.revision,
reload=ReloadRequest(mode="drain", timeout_secs=30, failure_policy="rollback"),
)
if changed.data.reload is not None:
progress = await client.system.reload_status(changed.data.reload.reload_id)
print(progress.data.state)
Для изменения доступны general, timeouts, censorship, upstreams, dc_overrides,
web и server.listeners. Проверка на стороне сервера определяет, какие вложенные
параметры можно изменить и каким требуется перезапуск процесса.
HTTP 202 означает принятие операции, а не её завершение. Опрашивайте
system.reload_status(id) с интервалом и общим тайм-аутом, подходящими вашему приложению,
до состояния succeeded, rolled_back или failed. Проверяйте warnings,
deferred_process_fields и error в результате. Для отдельной перезагрузки вызовите
system.reload(ReloadRequest(...)). Режим drain требует timeout_secs от 1 до 3600;
режим instant не принимает этот параметр.
WEB-сессии и жизненный цикл
from telemt.models import CloseRequest, RefsSelector, SessionQuery
status = await client.runtime.web.status()
if status.data.runtime is not None:
page = await client.runtime.web.sessions(SessionQuery(user="alice", limit=50))
if page.data.sessions:
accepted = await client.runtime.web.close_sessions(
CloseRequest(
runtime_instance=status.data.runtime.runtime_instance,
selector=RefsSelector(session_refs=[row.session_ref for row in page.data.sessions]),
)
)
progress = await client.runtime.web.operation(accepted.data.operation_id)
print(progress.data.state)
Страница сессий содержит до 200 записей. Для следующей страницы передайте
SessionQuery(cursor=page.data.next_cursor, ...) с теми же фильтрами. Завершайте обход,
когда next_cursor равен None. Поля scan_truncated, partial_sessions и partial
описывают ограничения снимка состояния.
Для pause, resume, clear_debug и reset_carrier_learning используется
RuntimeInstanceRequest, для drain — DrainRequest. FilterSelector выбирает сессии
по фильтрам. AllSelector требует, чтобы runtime.manager.issuance_enabled был равен
False; операторский pause() управляет отдельным механизмом допуска. Перед выбором
всех сессий проверьте состояние runtime. Для управляемого завершения текущей работы
используйте drain().
Ссылки на сессии и операции действуют в пределах текущего процесса сервера. Опрашивайте возвращённый идентификатор операции, чтобы узнать результат: принятие запроса само по себе не означает завершения.
Обработка ошибок
from telemt import APIError, ConflictError, TransportError
try:
await client.users.disable("alice", revision=known_revision)
except ConflictError as error:
print(error.code, error.request_id)
except APIError as error:
print(error.status_code, error.code, error.message)
except TransportError:
# Перечитайте состояние сервера перед решением о повторном изменении.
raise
| Исключение | Значение |
|---|---|
AuthenticationError |
HTTP 401. |
PermissionDeniedError |
HTTP 403, включая режим read-only. |
NotFoundError |
HTTP 404. |
ConflictError |
HTTP 409, включая конфликт ревизий. |
APIError |
Другие ошибки сервера; доступны status_code, code, message, request_id. |
RequestTimeoutError |
Тайм-аут HTTPX; наследуется от TransportError. |
TransportError |
Ошибка сети или транспорта; исходное исключение доступно в __cause__. |
InvalidResponseError |
Некорректный JSON, формат ответа или структура данных. |
Все исключения SDK наследуются от TelemtError. Ошибки моделей запросов вызывают
pydantic.ValidationError; недопустимые аргументы маршрутов — ValueError, включая
его подкласс ValidationError. Отмена асинхронной задачи распространяется без обёртки.
Два HTTP-статуса могут содержать штатный результат: health.ready() возвращает данные
готовности при HTTP 503, а runtime.web.session() — GoneSessionData при HTTP 410.
Ответ с ошибкой API на этих маршрутах по-прежнему вызывает исключение. Используйте
isinstance(result.data, GoneSessionData), чтобы отличить закрытую сессию от SessionRow.
Совместимость
SDK следует проекту Telemt и его
Control API.
Модели сверяются со спецификацией API и типами сериализации в Rust-коде сервера.
Клиент охватывает 48 основных операций Control API. HTML-страница /web-status
и транспортные WEB-эндпоинты находятся за пределами этого API-клиента.
Python 3.13, 3.14 и 3.15 входят в обязательную матрицу CI под Linux и Windows. Необязательные
возможности Telemt могут возвращать данные об отключённой или недоступной функции:
проверяйте enabled, reason, data и partial, когда они присутствуют. Сохранение
новых полей помогает при расширении ответов сервера, но не означает гарантированную
совместимость со всеми прошлыми и будущими изменениями API.
Полный перечень методов, типов запросов и ответов доступен в справочнике API.
Участие в разработке и поддержка
Сообщения об ошибках и pull request приветствуются. В issue укажите версии Python, SDK и Telemt, минимальный пример и тип исключения или код ошибки Telemt. Удалите заголовки авторизации, секреты и приватные настройки из публикуемых материалов.
Настройка окружения uv, линтер, проверка типов и тесты описаны в CONTRIBUTING.md.
Лицензия
MIT © 2026 Peakora-VPN.
Metadata
Release files for telemt-sdk 1.0.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| telemt_sdk-1.0.0.tar.gz | 119.5 kB | Without provenance | Details for telemt_sdk-1.0.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| telemt_sdk-1.0.0-py3-none-any.whl | Python 3 | none | any | Details for telemt_sdk-1.0.0-py3-none-any.whl |
Total release size: 148.2 kB
Release files / telemt_sdk-1.0.0.tar.gz
| Download URL | telemt_sdk-1.0.0.tar.gz |
|---|---|
| Size | 119.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
99ed2c14425c670192338c31bc80966209ae8dc13798433ea17d9bf36fe819ea
|
|
BLAKE2b-256 checksum How to use checksums |
dc5b4da9ebf7fa21f4827e5a83b26d452daf03ac62b42ec8494cbb598d41aee7
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.13.7 {"installer":{"name":"uv","version":"0.13.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"26.04","id":"resolute","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / telemt_sdk-1.0.0-py3-none-any.whl
| Download URL | telemt_sdk-1.0.0-py3-none-any.whl |
|---|---|
| Size | 28.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
84ff867846083eb9382b25dd83229cc20f27056a1fe7a4778b1bf8dfe435df91
|
|
BLAKE2b-256 checksum How to use checksums |
e71a16f63cf9985a5bce8c84e214210581da18e85b03ce6ebd9f509db52aed12
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.13.7 {"installer":{"name":"uv","version":"0.13.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"26.04","id":"resolute","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Security for telemt-sdk 1.0.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.