telemt-sdk 1.0.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- telemt_sdk-1.0.0/.gitignore +11 -0
- telemt_sdk-1.0.0/.python-version +1 -0
- telemt_sdk-1.0.0/CONTRIBUTING.md +63 -0
- telemt_sdk-1.0.0/LICENSE +21 -0
- telemt_sdk-1.0.0/PKG-INFO +377 -0
- telemt_sdk-1.0.0/README.en.md +346 -0
- telemt_sdk-1.0.0/README.md +355 -0
- telemt_sdk-1.0.0/docs/api-reference.md +170 -0
- telemt_sdk-1.0.0/docs/maintaining.md +110 -0
- telemt_sdk-1.0.0/docs/testing.md +79 -0
- telemt_sdk-1.0.0/pyproject.toml +74 -0
- telemt_sdk-1.0.0/scripts/__init__.py +1 -0
- telemt_sdk-1.0.0/scripts/check_release.py +40 -0
- telemt_sdk-1.0.0/scripts/release_notes.py +129 -0
- telemt_sdk-1.0.0/src/telemt/__init__.py +34 -0
- telemt_sdk-1.0.0/src/telemt/client.py +177 -0
- telemt_sdk-1.0.0/src/telemt/exceptions.py +50 -0
- telemt_sdk-1.0.0/src/telemt/models/__init__.py +345 -0
- telemt_sdk-1.0.0/src/telemt/models/base.py +39 -0
- telemt_sdk-1.0.0/src/telemt/models/operations.py +39 -0
- telemt_sdk-1.0.0/src/telemt/models/requests.py +216 -0
- telemt_sdk-1.0.0/src/telemt/models/responses.py +972 -0
- telemt_sdk-1.0.0/src/telemt/models/web.py +469 -0
- telemt_sdk-1.0.0/src/telemt/py.typed +0 -0
- telemt_sdk-1.0.0/src/telemt/resources.py +416 -0
- telemt_sdk-1.0.0/tests/__init__.py +0 -0
- telemt_sdk-1.0.0/tests/conftest.py +42 -0
- telemt_sdk-1.0.0/tests/fixtures/live-responses.json +3533 -0
- telemt_sdk-1.0.0/tests/fixtures/source-contracts.json +5700 -0
- telemt_sdk-1.0.0/tests/integration/__init__.py +0 -0
- telemt_sdk-1.0.0/tests/integration/telemt.toml +46 -0
- telemt_sdk-1.0.0/tests/integration/test_live.py +196 -0
- telemt_sdk-1.0.0/tests/test_client.py +325 -0
- telemt_sdk-1.0.0/tests/test_models.py +96 -0
- telemt_sdk-1.0.0/tests/test_recorded_responses.py +42 -0
- telemt_sdk-1.0.0/tests/test_regressions.py +188 -0
- telemt_sdk-1.0.0/tests/test_release.py +51 -0
- telemt_sdk-1.0.0/tests/test_release_notes.py +89 -0
- telemt_sdk-1.0.0/tests/test_resources.py +267 -0
- telemt_sdk-1.0.0/tests/test_source_contracts.py +56 -0
- telemt_sdk-1.0.0/tests/typing/public_api.py +43 -0
- telemt_sdk-1.0.0/uv.lock +663 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
3.14
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# Contributing
|
|
2
|
+
|
|
3
|
+
Use a separate branch for changes. For a bug report, include a minimal reproduction,
|
|
4
|
+
the Python/SDK/Telemt versions and the relevant API error code. Remove secrets and
|
|
5
|
+
private configuration before opening an issue.
|
|
6
|
+
|
|
7
|
+
## Development setup
|
|
8
|
+
|
|
9
|
+
Install [uv](https://docs.astral.sh/uv/getting-started/installation/), then:
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
git clone https://github.com/Peakora-VPN/telemt-sdk.git
|
|
13
|
+
cd telemt-sdk
|
|
14
|
+
uv python install 3.13 3.14 3.15
|
|
15
|
+
uv sync --locked
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
If an older uv installation does not recognize a Python version, update uv first.
|
|
19
|
+
Dependencies belong in `pyproject.toml`; commit `uv.lock` when changing them.
|
|
20
|
+
|
|
21
|
+
## Checks
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
uv run ruff check .
|
|
25
|
+
uv run ruff format --check .
|
|
26
|
+
uv run mypy
|
|
27
|
+
uv run pytest --cov=telemt --cov-report=term-missing
|
|
28
|
+
uv run --isolated --python 3.13 pytest
|
|
29
|
+
uv run --isolated --python 3.15 pytest
|
|
30
|
+
uv build
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
Run `uv run ruff format .` to apply formatting. Mypy uses strict mode for the SDK,
|
|
34
|
+
release verification script and consumer examples in `tests/typing`.
|
|
35
|
+
|
|
36
|
+
The default test suite is offline. It checks transport/error behavior, request validation,
|
|
37
|
+
all resource routes, recorded real-server responses and response contracts extracted from
|
|
38
|
+
Telemt's Rust types. Optional tests against a disposable server are described in
|
|
39
|
+
[Testing against Telemt](docs/testing.md).
|
|
40
|
+
|
|
41
|
+
CI runs Ruff and mypy, then tests on Python 3.13, 3.14 and 3.15 under Linux and Windows, and builds
|
|
42
|
+
the wheel and source distribution. Do not remove a supported interpreter from the matrix
|
|
43
|
+
to make a failing check pass.
|
|
44
|
+
|
|
45
|
+
## Changing the API
|
|
46
|
+
|
|
47
|
+
Check both Telemt's API documentation and its handlers/serialization types. Update the
|
|
48
|
+
request or response model, the resource method, public exports, tests and the method
|
|
49
|
+
reference together. Preserve the difference between an omitted PATCH field and explicit
|
|
50
|
+
JSON `null`. Keep configuration revisions attached to individual responses.
|
|
51
|
+
|
|
52
|
+
When updating compatibility fixtures, record the upstream commit and how the responses
|
|
53
|
+
were obtained. Add a focused regression test for a behavioral fix; route existence alone
|
|
54
|
+
does not prove the result is decoded correctly. Include a consumer type assertion when
|
|
55
|
+
changing a public return type.
|
|
56
|
+
|
|
57
|
+
## Pull requests
|
|
58
|
+
|
|
59
|
+
Explain the observed problem, the new behavior and the checks you ran. Note any API change
|
|
60
|
+
that requires callers to update. Contributions are provided under the repository's
|
|
61
|
+
[MIT license](LICENSE).
|
|
62
|
+
|
|
63
|
+
Publishing setup is documented separately in [Maintaining](docs/maintaining.md).
|
telemt_sdk-1.0.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Peakora-VPN
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,377 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: telemt-sdk
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Typed asynchronous Python SDK for the Telemt Control API
|
|
5
|
+
Project-URL: Homepage, https://github.com/Peakora-VPN/telemt-sdk
|
|
6
|
+
Project-URL: Issues, https://github.com/Peakora-VPN/telemt-sdk/issues
|
|
7
|
+
Project-URL: Documentation, https://github.com/Peakora-VPN/telemt-sdk#readme
|
|
8
|
+
License-Expression: MIT
|
|
9
|
+
License-File: LICENSE
|
|
10
|
+
Classifier: Development Status :: 3 - Alpha
|
|
11
|
+
Classifier: Framework :: AsyncIO
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.15
|
|
17
|
+
Classifier: Typing :: Typed
|
|
18
|
+
Requires-Python: >=3.13
|
|
19
|
+
Requires-Dist: httpx<1,>=0.28.1
|
|
20
|
+
Requires-Dist: pydantic<3,>=2.12
|
|
21
|
+
Description-Content-Type: text/markdown
|
|
22
|
+
|
|
23
|
+
<p align="center">
|
|
24
|
+
<a href="https://github.com/Peakora-VPN/telemt-sdk/actions/workflows/ci.yml"><img src="https://img.shields.io/github/actions/workflow/status/Peakora-VPN/telemt-sdk/ci.yml?style=for-the-badge&logo=githubactions&logoColor=white&label=CI" alt="CI status"></a>
|
|
25
|
+
<a href="https://pypi.org/project/telemt-sdk/"><img src="https://img.shields.io/pypi/v/telemt-sdk?style=for-the-badge&logo=pypi&logoColor=white&color=3776AB" alt="PyPI version"></a>
|
|
26
|
+
<a href="#совместимость"><img src="https://img.shields.io/badge/Python-3.13%20%7C%203.14%20%7C%203.15-3776AB?style=for-the-badge&logo=python&logoColor=white" alt="Python 3.13, 3.14 and 3.15"></a>
|
|
27
|
+
<a href="https://github.com/Peakora-VPN/telemt-sdk/blob/main/LICENSE"><img src="https://img.shields.io/badge/License-MIT-22C55E?style=for-the-badge" alt="MIT license"></a>
|
|
28
|
+
</p>
|
|
29
|
+
<p align="center">
|
|
30
|
+
<a href="https://docs.astral.sh/uv/"><img src="https://img.shields.io/badge/managed%20with-uv-DE5FE9?style=flat-square&logo=uv" alt="Managed with uv"></a>
|
|
31
|
+
<a href="https://docs.astral.sh/ruff/"><img src="https://img.shields.io/badge/code%20style-Ruff-D7FF64?style=flat-square&logo=ruff&logoColor=black" alt="Code style: Ruff"></a>
|
|
32
|
+
<a href="https://typing.python.org/"><img src="https://img.shields.io/badge/typing-PEP%20561-6366F1?style=flat-square" alt="Typed Python package"></a>
|
|
33
|
+
</p>
|
|
34
|
+
|
|
35
|
+
<p align="center"><a href="https://github.com/Peakora-VPN/telemt-sdk/blob/main/README.md">Русский</a> · <a href="https://github.com/Peakora-VPN/telemt-sdk/blob/main/README.en.md">English</a></p>
|
|
36
|
+
|
|
37
|
+
<h1 align="center">telemt-sdk</h1>
|
|
38
|
+
<p align="center">Асинхронный типизированный Python SDK для Telemt Control API.</p>
|
|
39
|
+
<p align="center">
|
|
40
|
+
<a href="#быстрый-старт">Быстрый старт</a> ·
|
|
41
|
+
<a href="https://github.com/Peakora-VPN/telemt-sdk/blob/main/docs/api-reference.md">Справочник API</a> ·
|
|
42
|
+
<a href="https://github.com/Peakora-VPN/telemt-sdk/blob/main/CONTRIBUTING.md">Участие в разработке</a> ·
|
|
43
|
+
<a href="https://github.com/Peakora-VPN/telemt-sdk/issues">Сообщить об ошибке</a>
|
|
44
|
+
</p>
|
|
45
|
+
|
|
46
|
+
<p align="center"><strong>🤝 Спонсор проекта — Peakora VPN</strong></p>
|
|
47
|
+
<p align="center">
|
|
48
|
+
<a href="https://peakora.network/">
|
|
49
|
+
<img src="https://peakora.network/social-preview.png" width="600" alt="Peakora VPN — интернет в вашем ритме">
|
|
50
|
+
</a>
|
|
51
|
+
</p>
|
|
52
|
+
<p align="center">
|
|
53
|
+
Защищённый доступ в интернет и к AI-сервисам с подключением через Telegram.<br>
|
|
54
|
+
<a href="https://peakora.network/">Подробнее о Peakora →</a>
|
|
55
|
+
</p>
|
|
56
|
+
|
|
57
|
+
Управляйте пользователями прокси, квотами, конфигурацией, диагностикой и WEB-сессиями из Python.
|
|
58
|
+
`TelemtClient` объединяет операции в ресурсные объекты, переиспользует HTTP-соединения
|
|
59
|
+
и возвращает Pydantic-модели с конкретными аннотациями типов, включая вложенные данные.
|
|
60
|
+
|
|
61
|
+
- **48 операций API:** пользователи, состояние сервиса, статистика, перезагрузка и управление WEB runtime.
|
|
62
|
+
- **Полностью асинхронный интерфейс:** `async with`, `await` и параллельное чтение через `asyncio.gather`.
|
|
63
|
+
- **Типизированные запросы и ответы:** валидация входных данных, подсказки IDE и маркер `py.typed`.
|
|
64
|
+
- **Контроль конкурентных изменений:** передача ревизии ответа для защиты обновлений конфигурации.
|
|
65
|
+
- **Понятные ошибки:** отдельные классы исключений сохраняют HTTP-статус, код Telemt и идентификатор запроса.
|
|
66
|
+
|
|
67
|
+
SDK работает с HTTP API управления [Telemt](https://github.com/telemt/telemt).
|
|
68
|
+
Передачу MTProto-трафика и подключения клиентов Telegram обеспечивает сам Telemt.
|
|
69
|
+
|
|
70
|
+
## Установка
|
|
71
|
+
|
|
72
|
+
Требуется Python **3.13, 3.14 или 3.15**. Имя пакета — `telemt-sdk`, имя импорта — `telemt`.
|
|
73
|
+
|
|
74
|
+
После появления релиза в [PyPI](https://pypi.org/project/telemt-sdk/):
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
uv add telemt-sdk
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
Или через pip:
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
python -m pip install telemt-sdk
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
До первого релиза можно работать из клонированного репозитория: выполните `uv sync --locked`
|
|
87
|
+
в его каталоге. Зависимости SDK — [HTTPX](https://www.python-httpx.org/)
|
|
88
|
+
и [Pydantic](https://docs.pydantic.dev/latest/).
|
|
89
|
+
|
|
90
|
+
## Быстрый старт
|
|
91
|
+
|
|
92
|
+
Включите Control API в конфигурации Telemt и задайте `TELEMT_AUTH_HEADER` равным точному
|
|
93
|
+
значению `server.api.auth_header`. Этот пример читает состояние сервера:
|
|
94
|
+
|
|
95
|
+
```python
|
|
96
|
+
import asyncio
|
|
97
|
+
import os
|
|
98
|
+
|
|
99
|
+
from telemt import TelemtClient
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
async def main() -> None:
|
|
103
|
+
async with TelemtClient(
|
|
104
|
+
"http://127.0.0.1:9091",
|
|
105
|
+
auth_header=os.environ["TELEMT_AUTH_HEADER"],
|
|
106
|
+
) as client:
|
|
107
|
+
health = await client.health.get()
|
|
108
|
+
print(health.data.status)
|
|
109
|
+
|
|
110
|
+
users = await client.users.list()
|
|
111
|
+
for user in users.data:
|
|
112
|
+
print(user.username, user.enabled, user.current_connections)
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
asyncio.run(main())
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
SDK передаёт `auth_header` в заголовке `Authorization` без изменений и не добавляет `Bearer`.
|
|
119
|
+
Если на сервере настроено значение `Bearer ...`, передавайте строку целиком.
|
|
120
|
+
Если авторизация не настроена, аргумент можно опустить. Используйте адрес слушателя
|
|
121
|
+
Control API, а не порт MTProto или WEB ingress.
|
|
122
|
+
|
|
123
|
+
## Настройка клиента
|
|
124
|
+
|
|
125
|
+
| Аргумент | По умолчанию | Назначение |
|
|
126
|
+
| --- | --- | --- |
|
|
127
|
+
| `base_url` | Обязателен | Абсолютный HTTP(S) URL. `/v1` добавляется, если отсутствует. Префикс reverse proxy сохраняется. |
|
|
128
|
+
| `auth_header` | `None` | Точное значение заголовка `Authorization`, настроенного на сервере. |
|
|
129
|
+
| `timeout` | `30.0` | Тайм-аут HTTPX в секундах или `httpx.Timeout` с отдельными лимитами подключения, чтения, записи и ожидания соединения. |
|
|
130
|
+
| `http_client` | `None` | Необязательный `httpx.AsyncClient` для настройки TLS, прокси, транспорта и пула соединений. |
|
|
131
|
+
|
|
132
|
+
Адреса `https://proxy.example.com/control` и `https://proxy.example.com/control/v1`
|
|
133
|
+
оба направляют запросы в `/control/v1/...`. Учётные данные, query-параметры и фрагменты
|
|
134
|
+
в `base_url` не допускаются.
|
|
135
|
+
|
|
136
|
+
Используйте один клиент для нескольких запросов в пределах одного event loop:
|
|
137
|
+
|
|
138
|
+
```python
|
|
139
|
+
health, stats = await asyncio.gather(client.health.get(), client.stats.summary())
|
|
140
|
+
print(stats.data.connections_total)
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
Закрывайте соединения через `async with` или `await client.aclose()`. Закрытый клиент
|
|
144
|
+
нельзя использовать повторно. Если вы передаёте собственный HTTPX-клиент, его временем
|
|
145
|
+
жизни управляете вы:
|
|
146
|
+
|
|
147
|
+
```python
|
|
148
|
+
import httpx
|
|
149
|
+
|
|
150
|
+
async with httpx.AsyncClient(limits=httpx.Limits(max_connections=20)) as http:
|
|
151
|
+
async with TelemtClient(
|
|
152
|
+
"https://proxy.example.com",
|
|
153
|
+
auth_header=auth_header,
|
|
154
|
+
timeout=httpx.Timeout(30.0, connect=5.0),
|
|
155
|
+
http_client=http,
|
|
156
|
+
) as client:
|
|
157
|
+
info = await client.system.info()
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
Параметры SDK и явно переданная авторизация имеют приоритет над настройками HTTPX.
|
|
161
|
+
Редиректы и автоматические повторы запросов отключены: изменение могло дойти до сервера
|
|
162
|
+
до истечения тайм-аута.
|
|
163
|
+
|
|
164
|
+
## Пользователи и квоты
|
|
165
|
+
|
|
166
|
+
```python
|
|
167
|
+
from telemt.models import CreateUserRequest, PatchUserRequest, RotateSecretRequest
|
|
168
|
+
|
|
169
|
+
created = await client.users.create(
|
|
170
|
+
CreateUserRequest(
|
|
171
|
+
username="alice",
|
|
172
|
+
max_tcp_conns=10,
|
|
173
|
+
data_quota_bytes=10_000_000_000,
|
|
174
|
+
quota_period="monthly",
|
|
175
|
+
)
|
|
176
|
+
)
|
|
177
|
+
# created.data.secret содержит сгенерированный секрет; не записывайте его в логи.
|
|
178
|
+
print(created.data.user.username)
|
|
179
|
+
|
|
180
|
+
updated = await client.users.update(
|
|
181
|
+
"alice",
|
|
182
|
+
PatchUserRequest(max_tcp_conns=20, expiration_rfc3339="2027-01-01T00:00:00Z"),
|
|
183
|
+
revision=created.revision,
|
|
184
|
+
)
|
|
185
|
+
|
|
186
|
+
rotated = await client.users.rotate_secret("alice", RotateSecretRequest())
|
|
187
|
+
await client.users.reset_quota("alice")
|
|
188
|
+
await client.users.disable("alice")
|
|
189
|
+
await client.users.enable("alice")
|
|
190
|
+
# Удаляйте пользователя явно, когда учётная запись больше не нужна:
|
|
191
|
+
# await client.users.delete("alice")
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
Секреты и рекламные теги состоят из 32 шестнадцатеричных символов. Имя пользователя
|
|
195
|
+
содержит от 1 до 64 латинских букв, цифр, точек, дефисов или подчёркиваний. Имена `.`
|
|
196
|
+
и `..` отклоняются, поскольку HTTPX нормализует такие сегменты пути. Для периодического
|
|
197
|
+
сброса квоты доступны `daily`, `weekly` и `monthly`; при создании пользователя требуется
|
|
198
|
+
положительное значение `data_quota_bytes`.
|
|
199
|
+
|
|
200
|
+
### Семантика PATCH
|
|
201
|
+
|
|
202
|
+
Пропущенное поле, `None` и ноль имеют разное значение:
|
|
203
|
+
|
|
204
|
+
| Запрос | Результат |
|
|
205
|
+
| --- | --- |
|
|
206
|
+
| `PatchUserRequest()` | Оставить настройки без изменений. |
|
|
207
|
+
| `PatchUserRequest(max_tcp_conns=None)` | Удалить индивидуальное ограничение пользователя. |
|
|
208
|
+
| `PatchUserRequest(max_tcp_conns=0)` | Передать явный ноль; его смысл для этой настройки определяет Telemt. |
|
|
209
|
+
| `PatchUserRequest(enabled=False)` | Отключить пользователя. |
|
|
210
|
+
| `PatchUserRequest(secret=None)` | Оставить секрет без изменений, как это делает Telemt. |
|
|
211
|
+
|
|
212
|
+
Для генерации нового секрета используйте `rotate_secret()`. Модели запросов отклоняют
|
|
213
|
+
неизвестные поля и недопустимые значения. Проверки, зависящие от состояния сервера,
|
|
214
|
+
например существование пользователя, выполняет Telemt и возвращает соответствующую ошибку API.
|
|
215
|
+
|
|
216
|
+
## Ответы и ревизии
|
|
217
|
+
|
|
218
|
+
Каждый метод возвращает `APIResponse[T]`:
|
|
219
|
+
|
|
220
|
+
| Поле | Тип | Назначение |
|
|
221
|
+
| --- | --- | --- |
|
|
222
|
+
| `data` | `T` | Типизированный результат операции, например `UserInfo` или `list[UserInfo]`. |
|
|
223
|
+
| `revision` | `str` | Ревизия конфигурации сервера для этого ответа. |
|
|
224
|
+
| `status_code` | `int` | Фактический HTTP-статус ответа. |
|
|
225
|
+
| `ok` | `Literal[True]` | Успешно разобранный ответ API. |
|
|
226
|
+
|
|
227
|
+
Вложенные данные тоже представлены моделями: `user.links.tls_domains[0].domain`
|
|
228
|
+
и `status.runtime.manager.issuance_enabled` доступны проверке типов после проверки
|
|
229
|
+
nullable-полей на `None`. Модели импортируются из `telemt.models`.
|
|
230
|
+
|
|
231
|
+
```python
|
|
232
|
+
current = await client.users.get("alice")
|
|
233
|
+
await client.users.update(
|
|
234
|
+
"alice",
|
|
235
|
+
PatchUserRequest(max_tcp_conns=30),
|
|
236
|
+
revision=current.revision,
|
|
237
|
+
)
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
Аргумент `revision=` передаётся в заголовок `If-Match`. Устаревшая ревизия вызывает
|
|
241
|
+
`ConflictError`. Перечитайте состояние и проверьте, остаётся ли изменение актуальным,
|
|
242
|
+
прежде чем повторять запрос. Клиент не хранит общую ревизию и не подставляет её автоматически,
|
|
243
|
+
поэтому параллельные ответы независимы. WEB-операции используют `runtime_instance`.
|
|
244
|
+
|
|
245
|
+
Новые поля сервера сохраняются в `model_extra`. Для представления, совместимого с JSON,
|
|
246
|
+
используйте `model_dump(mode="json", by_alias=True)`. Разделы конфигурации остаются
|
|
247
|
+
`dict[str, JsonValue]`, поскольку это расширяемые конфигурационные данные;
|
|
248
|
+
известные структуры телеметрии и WEB описаны отдельными моделями.
|
|
249
|
+
|
|
250
|
+
## Конфигурация и перезагрузка
|
|
251
|
+
|
|
252
|
+
```python
|
|
253
|
+
from telemt.models import PatchConfigRequest, ReloadRequest
|
|
254
|
+
|
|
255
|
+
current = await client.config.get()
|
|
256
|
+
changed = await client.config.update(
|
|
257
|
+
PatchConfigRequest(censorship={"tls_domain": "front.example.com"}),
|
|
258
|
+
revision=current.revision,
|
|
259
|
+
reload=ReloadRequest(mode="drain", timeout_secs=30, failure_policy="rollback"),
|
|
260
|
+
)
|
|
261
|
+
if changed.data.reload is not None:
|
|
262
|
+
progress = await client.system.reload_status(changed.data.reload.reload_id)
|
|
263
|
+
print(progress.data.state)
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
Для изменения доступны `general`, `timeouts`, `censorship`, `upstreams`, `dc_overrides`,
|
|
267
|
+
`web` и `server.listeners`. Проверка на стороне сервера определяет, какие вложенные
|
|
268
|
+
параметры можно изменить и каким требуется перезапуск процесса.
|
|
269
|
+
|
|
270
|
+
HTTP `202` означает принятие операции, а не её завершение. Опрашивайте
|
|
271
|
+
`system.reload_status(id)` с интервалом и общим тайм-аутом, подходящими вашему приложению,
|
|
272
|
+
до состояния `succeeded`, `rolled_back` или `failed`. Проверяйте `warnings`,
|
|
273
|
+
`deferred_process_fields` и `error` в результате. Для отдельной перезагрузки вызовите
|
|
274
|
+
`system.reload(ReloadRequest(...))`. Режим `drain` требует `timeout_secs` от 1 до 3600;
|
|
275
|
+
режим `instant` не принимает этот параметр.
|
|
276
|
+
|
|
277
|
+
## WEB-сессии и жизненный цикл
|
|
278
|
+
|
|
279
|
+
```python
|
|
280
|
+
from telemt.models import CloseRequest, RefsSelector, SessionQuery
|
|
281
|
+
|
|
282
|
+
status = await client.runtime.web.status()
|
|
283
|
+
if status.data.runtime is not None:
|
|
284
|
+
page = await client.runtime.web.sessions(SessionQuery(user="alice", limit=50))
|
|
285
|
+
if page.data.sessions:
|
|
286
|
+
accepted = await client.runtime.web.close_sessions(
|
|
287
|
+
CloseRequest(
|
|
288
|
+
runtime_instance=status.data.runtime.runtime_instance,
|
|
289
|
+
selector=RefsSelector(session_refs=[row.session_ref for row in page.data.sessions]),
|
|
290
|
+
)
|
|
291
|
+
)
|
|
292
|
+
progress = await client.runtime.web.operation(accepted.data.operation_id)
|
|
293
|
+
print(progress.data.state)
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
Страница сессий содержит до 200 записей. Для следующей страницы передайте
|
|
297
|
+
`SessionQuery(cursor=page.data.next_cursor, ...)` с теми же фильтрами. Завершайте обход,
|
|
298
|
+
когда `next_cursor` равен `None`. Поля `scan_truncated`, `partial_sessions` и `partial`
|
|
299
|
+
описывают ограничения снимка состояния.
|
|
300
|
+
|
|
301
|
+
Для `pause`, `resume`, `clear_debug` и `reset_carrier_learning` используется
|
|
302
|
+
`RuntimeInstanceRequest`, для `drain` — `DrainRequest`. `FilterSelector` выбирает сессии
|
|
303
|
+
по фильтрам. `AllSelector` требует, чтобы `runtime.manager.issuance_enabled` был равен
|
|
304
|
+
`False`; операторский `pause()` управляет отдельным механизмом допуска. Перед выбором
|
|
305
|
+
всех сессий проверьте состояние runtime. Для управляемого завершения текущей работы
|
|
306
|
+
используйте `drain()`.
|
|
307
|
+
|
|
308
|
+
Ссылки на сессии и операции действуют в пределах текущего процесса сервера.
|
|
309
|
+
Опрашивайте возвращённый идентификатор операции, чтобы узнать результат:
|
|
310
|
+
принятие запроса само по себе не означает завершения.
|
|
311
|
+
|
|
312
|
+
## Обработка ошибок
|
|
313
|
+
|
|
314
|
+
```python
|
|
315
|
+
from telemt import APIError, ConflictError, TransportError
|
|
316
|
+
|
|
317
|
+
try:
|
|
318
|
+
await client.users.disable("alice", revision=known_revision)
|
|
319
|
+
except ConflictError as error:
|
|
320
|
+
print(error.code, error.request_id)
|
|
321
|
+
except APIError as error:
|
|
322
|
+
print(error.status_code, error.code, error.message)
|
|
323
|
+
except TransportError:
|
|
324
|
+
# Перечитайте состояние сервера перед решением о повторном изменении.
|
|
325
|
+
raise
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
| Исключение | Значение |
|
|
329
|
+
| --- | --- |
|
|
330
|
+
| `AuthenticationError` | HTTP 401. |
|
|
331
|
+
| `PermissionDeniedError` | HTTP 403, включая режим read-only. |
|
|
332
|
+
| `NotFoundError` | HTTP 404. |
|
|
333
|
+
| `ConflictError` | HTTP 409, включая конфликт ревизий. |
|
|
334
|
+
| `APIError` | Другие ошибки сервера; доступны `status_code`, `code`, `message`, `request_id`. |
|
|
335
|
+
| `RequestTimeoutError` | Тайм-аут HTTPX; наследуется от `TransportError`. |
|
|
336
|
+
| `TransportError` | Ошибка сети или транспорта; исходное исключение доступно в `__cause__`. |
|
|
337
|
+
| `InvalidResponseError` | Некорректный JSON, формат ответа или структура данных. |
|
|
338
|
+
|
|
339
|
+
Все исключения SDK наследуются от `TelemtError`. Ошибки моделей запросов вызывают
|
|
340
|
+
`pydantic.ValidationError`; недопустимые аргументы маршрутов — `ValueError`, включая
|
|
341
|
+
его подкласс `ValidationError`. Отмена асинхронной задачи распространяется без обёртки.
|
|
342
|
+
|
|
343
|
+
Два HTTP-статуса могут содержать штатный результат: `health.ready()` возвращает данные
|
|
344
|
+
готовности при HTTP 503, а `runtime.web.session()` — `GoneSessionData` при HTTP 410.
|
|
345
|
+
Ответ с ошибкой API на этих маршрутах по-прежнему вызывает исключение. Используйте
|
|
346
|
+
`isinstance(result.data, GoneSessionData)`, чтобы отличить закрытую сессию от `SessionRow`.
|
|
347
|
+
|
|
348
|
+
## Совместимость
|
|
349
|
+
|
|
350
|
+
SDK следует [проекту Telemt](https://github.com/telemt/telemt) и его
|
|
351
|
+
[Control API](https://github.com/telemt/telemt/blob/main/docs/Architecture/API/API.md).
|
|
352
|
+
Модели сверяются со спецификацией API и типами сериализации в Rust-коде сервера.
|
|
353
|
+
Клиент охватывает 48 основных операций Control API. HTML-страница `/web-status`
|
|
354
|
+
и транспортные WEB-эндпоинты находятся за пределами этого API-клиента.
|
|
355
|
+
|
|
356
|
+
Python 3.13, 3.14 и 3.15 входят в обязательную матрицу CI под Linux и Windows. Необязательные
|
|
357
|
+
возможности Telemt могут возвращать данные об отключённой или недоступной функции:
|
|
358
|
+
проверяйте `enabled`, `reason`, `data` и `partial`, когда они присутствуют. Сохранение
|
|
359
|
+
новых полей помогает при расширении ответов сервера, но не означает гарантированную
|
|
360
|
+
совместимость со всеми прошлыми и будущими изменениями API.
|
|
361
|
+
|
|
362
|
+
Полный перечень методов, типов запросов и ответов доступен в
|
|
363
|
+
[справочнике API](https://github.com/Peakora-VPN/telemt-sdk/blob/main/docs/api-reference.md).
|
|
364
|
+
|
|
365
|
+
## Участие в разработке и поддержка
|
|
366
|
+
|
|
367
|
+
Сообщения об ошибках и pull request приветствуются. В
|
|
368
|
+
[issue](https://github.com/Peakora-VPN/telemt-sdk/issues) укажите версии Python, SDK и Telemt,
|
|
369
|
+
минимальный пример и тип исключения или код ошибки Telemt. Удалите заголовки авторизации,
|
|
370
|
+
секреты и приватные настройки из публикуемых материалов.
|
|
371
|
+
|
|
372
|
+
Настройка окружения uv, линтер, проверка типов и тесты описаны в
|
|
373
|
+
[CONTRIBUTING.md](https://github.com/Peakora-VPN/telemt-sdk/blob/main/CONTRIBUTING.md).
|
|
374
|
+
|
|
375
|
+
## Лицензия
|
|
376
|
+
|
|
377
|
+
[MIT](https://github.com/Peakora-VPN/telemt-sdk/blob/main/LICENSE) © 2026 Peakora-VPN.
|