Skip to main content

CI status PyPI version Python 3.13, 3.14 and 3.15 MIT license

Managed with uv Code style: Ruff Typed Python package

Русский · English

telemt-sdk

Асинхронный типизированный Python SDK для Telemt Control API.

Быстрый старт · Справочник API · Участие в разработке · Сообщить об ошибке

🤝 Спонсор проекта — Peakora VPN

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)

Source distribution for telemt-sdk 1.0.0
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)

Table of built distributions (wheels) for telemt-sdk 1.0.0
File Interpreter ABI Platform Actions
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.

Release history Release notifications | RSS feed

This release

1.0.0 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page