yavot-py 0.1.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.
@@ -0,0 +1,35 @@
1
+ # Python virtual environment
2
+ .venv/
3
+ venv/
4
+ ENV/
5
+
6
+ # Python cache and compiled files
7
+ __pycache__/
8
+ *.pyc
9
+ *.pyo
10
+ *.pyd
11
+ .pytest_cache/
12
+ .mypy_cache/
13
+ .ruff_cache/
14
+
15
+ # Distribution / Build packages
16
+ build/
17
+ develop-eggs/
18
+ dist/
19
+ downloads/
20
+ eggs/
21
+ .eggs/
22
+ lib/
23
+ lib64/
24
+ parts/
25
+ sdist/
26
+ var/
27
+ wheels/
28
+ share/python-wheels/
29
+ *.egg-info/
30
+ .installed.cfg
31
+ *.egg
32
+
33
+ # OS files
34
+ .DS_Store
35
+ Thumbs.db
@@ -0,0 +1,73 @@
1
+ # Agent Instructions for `yavot-py` Maintenance & Development
2
+
3
+ You are an AI Agent tasked with maintaining, extending, or debugging `yavot-py`, a modern, high-quality Python library for interacting with the Yandex Video Translation API.
4
+
5
+ The initial port from the TypeScript `vot.js` library has been completed. These instructions outline the established architecture, technology stack, and best practices. **Always refer to these guidelines when making modifications.**
6
+
7
+ ---
8
+
9
+ ## 1. Project Overview & Tech Stack
10
+
11
+ `yavot-py` is a fully typed, asynchronous Python package targeting desktop and server environments.
12
+
13
+ ### Established Tech Stack
14
+ - **Python Version**: 3.10+ (Modern typing and language features).
15
+ - **Dependency Management**: `uv` (Use `uv run`, `uv add`, etc.).
16
+ - **HTTP Client**: `httpx` (Asynchronous and synchronous clients).
17
+ - **Protobuf**: `protobuf` (Google's official Python implementation).
18
+ - **Data Validation/Models**: `pydantic` (v2).
19
+ - **Testing**: `pytest` + `pytest-asyncio`.
20
+ - **Linting & Formatting**: `ruff`.
21
+ - **Type Checking**: `mypy`.
22
+
23
+ ---
24
+
25
+ ## 2. Python Library Best Practices
26
+
27
+ All agents contributing to `yavot-py` MUST adhere to the following Python library best practices:
28
+
29
+ 1. **Strict Type Hinting**: Every function signature and class must have proper type hints. Use `typing` features extensively (e.g., `Optional`, `Union`, `Literal`, or new syntax `X | Y`).
30
+ 2. **Docstrings**: Use Google-style or NumPy-style docstrings for all public modules, classes, and functions.
31
+ 3. **Async First, Sync Optional**: The core client uses `httpx.AsyncClient`. A synchronous wrapper (`VOTClientSync`) is provided.
32
+ 4. **Exception Handling**: Do not use bare `except:` clauses. Define custom exceptions (e.g., `VOTError`, `VOTAPIError`, `VideoDataError`) inheriting from Python's standard `Exception`.
33
+ 5. **Clean Imports**: Use absolute imports (`from vot.client import VOTClient`) or explicit relative imports (`from . import utils`).
34
+ 6. **No Global State**: Ensure that instances of the client do not leak state globally. Sessions and configurations should be bound to the client instance.
35
+
36
+ ---
37
+
38
+ ## 3. Project Architecture
39
+
40
+ The repository is structured as a standard Python package:
41
+
42
+ ```text
43
+ yavot-py/
44
+ ├── pyproject.toml # Project metadata, dependencies, and tool configs
45
+ ├── README.md # English documentation
46
+ ├── README.ru.md # Russian documentation
47
+ ├── docs/ # API documentation (English & Russian)
48
+ ├── scripts/
49
+ │ └── generate_proto.sh # Script to recompile protobuf bindings
50
+ ├── src/
51
+ │ └── vot/
52
+ │ ├── __init__.py # Exposes main clients and models
53
+ │ ├── cli.py # CLI implementation & argument parsing
54
+ │ ├── client.py # Core clients (MinimalClient, VOTClient, VOTClientSync, VOTWorkerClient)
55
+ │ ├── config.py # Global configurations and constants
56
+ │ ├── exceptions.py # Custom exception hierarchy
57
+ │ ├── models.py # Pydantic data models
58
+ │ ├── helpers/ # Domain-specific extractors (e.g., youtube.py)
59
+ │ ├── protobuf/ # Yandex Protobuf schemas and compiled python files
60
+ │ └── utils/ # Crypto, URL parsing, subtitles conversion, and language normalization
61
+ ├── tests/ # Comprehensive pytest suite
62
+ └── vot-cli # Bash wrapper for local CLI testing
63
+ ```
64
+
65
+ ---
66
+
67
+ ## 4. Agent Workflow Rules
68
+
69
+ 1. **Test Before Commit**: You must successfully run `uv run pytest`, `uv run mypy src tests`, and `uv run ruff check src tests` before claiming a task is complete or committing changes.
70
+ 2. **Modifying Protobufs**: If you update `src/vot/protobuf/yandex.proto`, you MUST execute `./scripts/generate_proto.sh` to regenerate `yandex_pb2.py`.
71
+ 3. **CLI Updates**: If you add new functionality to the CLI (`src/vot/cli.py`), make sure to write corresponding tests in `tests/test_cli.py` and update the READMEs.
72
+ 4. **Small, Descriptive Commits**: Keep changes atomic and commit messages clear (e.g., `feat: add support for new video host`, `fix: resolve mypy typing error in client`).
73
+ 5. **Bilingual Documentation**: User-facing documentation (`README.md`, `docs/api.md`) must be maintained in both English and Russian (`README.ru.md`, `docs/api.ru.md`).
yavot_py-0.1.0/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 FOSWLY
4
+ Copyright (c) 2026 yamixst
5
+
6
+ Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ of this software and associated documentation files (the "Software"), to deal
8
+ in the Software without restriction, including without limitation the rights
9
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ copies of the Software, and to permit persons to whom the Software is
11
+ furnished to do so, subject to the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be included in all
14
+ copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
+ SOFTWARE.
@@ -0,0 +1,294 @@
1
+ Metadata-Version: 2.4
2
+ Name: yavot-py
3
+ Version: 0.1.0
4
+ Summary: A Python port of the vot.js library for interacting with Yandex Video Translation API
5
+ Project-URL: Homepage, https://github.com/yamixst/yavot-py
6
+ Project-URL: Repository, https://github.com/yamixst/yavot-py
7
+ Project-URL: Issues, https://github.com/yamixst/yavot-py/issues
8
+ Project-URL: Documentation, https://github.com/yamixst/yavot-py/tree/main/docs
9
+ Author: yamixst
10
+ License: MIT License
11
+
12
+ Copyright (c) 2024 FOSWLY
13
+ Copyright (c) 2026 yamixst
14
+
15
+ Permission is hereby granted, free of charge, to any person obtaining a copy
16
+ of this software and associated documentation files (the "Software"), to deal
17
+ in the Software without restriction, including without limitation the rights
18
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
19
+ copies of the Software, and to permit persons to whom the Software is
20
+ furnished to do so, subject to the following conditions:
21
+
22
+ The above copyright notice and this permission notice shall be included in all
23
+ copies or substantial portions of the Software.
24
+
25
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
26
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
27
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
28
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
29
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
30
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
31
+ SOFTWARE.
32
+ License-File: LICENSE
33
+ Keywords: subtitles,translation,video,voiceover,vot,yandex,yavot-py
34
+ Classifier: Development Status :: 4 - Beta
35
+ Classifier: Intended Audience :: Developers
36
+ Classifier: License :: OSI Approved :: MIT License
37
+ Classifier: Programming Language :: Python :: 3
38
+ Classifier: Programming Language :: Python :: 3.10
39
+ Classifier: Programming Language :: Python :: 3.11
40
+ Classifier: Programming Language :: Python :: 3.12
41
+ Classifier: Topic :: Multimedia :: Sound/Audio :: Speech
42
+ Classifier: Topic :: Multimedia :: Video
43
+ Requires-Python: >=3.10
44
+ Requires-Dist: httpx>=0.24.0
45
+ Requires-Dist: protobuf>=4.21.0
46
+ Requires-Dist: pydantic>=2.0.0
47
+ Provides-Extra: dev
48
+ Requires-Dist: mypy>=1.0.0; extra == 'dev'
49
+ Requires-Dist: pytest-asyncio>=0.21.0; extra == 'dev'
50
+ Requires-Dist: pytest>=7.0.0; extra == 'dev'
51
+ Requires-Dist: ruff>=0.1.0; extra == 'dev'
52
+ Requires-Dist: types-protobuf>=4.21.0.0; extra == 'dev'
53
+ Description-Content-Type: text/markdown
54
+
55
+ # yavot-py
56
+
57
+ `yavot-py` is a modern, fast, and fully type-safe Python library for interacting with the **Yandex Video Translation API**. This library is a Python port of the popular TypeScript library `vot.js`.
58
+
59
+ It allows you to request video translations, poll processing status, obtain translated voice-over audio URLs, fetch original and translated subtitles, download and convert subtitle formats, and translate live streams in real time.
60
+
61
+ ---
62
+
63
+ ## Table of Contents
64
+ 1. [Installation](#installation)
65
+ 2. [Quick Start](#quick-start)
66
+ - [Async Client (Recommended)](#async-client-recommended)
67
+ - [Sync Client](#sync-client)
68
+ 3. [Key Features & Modules](#key-features--modules)
69
+ - [Service Routing & ID Extraction](#service-routing--id-extraction)
70
+ - [Video Translation](#video-translation)
71
+ - [Fetching Subtitles](#fetching-subtitles)
72
+ - [Live Streams](#live-streams)
73
+ - [Subtitles Conversion](#subtitles-conversion)
74
+ 4. [CLI Usage](#cli-usage)
75
+ 5. [Development & Testing](#development--testing)
76
+
77
+ ---
78
+
79
+ ## Installation
80
+
81
+ To install the library in editable/local mode:
82
+
83
+ ```bash
84
+ # Using pip
85
+ pip install -e .
86
+
87
+ # Or using uv (recommended)
88
+ uv pip install -e .
89
+ ```
90
+
91
+ The package automatically registers the `vot` executable command in your path.
92
+
93
+ ---
94
+
95
+ ## Quick Start
96
+
97
+ ### Async Client (Recommended)
98
+
99
+ The core client uses `httpx.AsyncClient` underneath.
100
+
101
+ ```python
102
+ import asyncio
103
+ import httpx
104
+ from vot import VOTClient, get_video_data
105
+
106
+ async def main():
107
+ # Initialize HTTP client
108
+ async with httpx.AsyncClient() as http_client:
109
+ # Initialize VOTClient
110
+ client = VOTClient(client=http_client)
111
+
112
+ # Resolve video URL (automatically detects service, extracts video ID & metadata)
113
+ url = "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
114
+ video_data = await get_video_data(url, client=http_client)
115
+
116
+ print(f"Service: {video_data.host}, Video ID: {video_data.video_id}")
117
+
118
+ # Request video translation
119
+ response = await client.translate_video(video_data)
120
+
121
+ if response.translated:
122
+ print(f"Translation finished! Audio URL: {response.url}")
123
+ else:
124
+ print(f"Translation in progress. Retry in {response.remaining_time}s. (Status: {response.status})")
125
+
126
+ if __name__ == "__main__":
127
+ asyncio.run(main())
128
+ ```
129
+
130
+ ### Sync Client
131
+
132
+ If your application uses synchronous code, you can use `VOTClientSync`, which handles the event loop automatically.
133
+
134
+ ```python
135
+ from vot import VOTClientSync, get_video_data
136
+ import httpx
137
+
138
+ # VOTClientSync supports the context manager protocol
139
+ with VOTClientSync() as client:
140
+ # Resolving video data still requires an HTTP client
141
+ with httpx.Client() as http_client:
142
+ # Since get_video_data is async, we run it using the client's loop runner helper
143
+ video_data = client._run(get_video_data("https://www.youtube.com/watch?v=dQw4w9WgXcQ"))
144
+
145
+ # Request translation synchronously
146
+ response = client.translate_video(video_data)
147
+ if response.translated:
148
+ print(f"Voiceover Audio URL: {response.url}")
149
+ ```
150
+
151
+ ---
152
+
153
+ ## Key Features & Modules
154
+
155
+ ### Service Routing & ID Extraction
156
+
157
+ `get_video_data` parses a video page URL, matches it against a registry of supported hosting sites (YouTube, Vimeo, Twitch, VK, TikTok, custom direct links, etc.), extracts the identifier, and returns a structured `VideoData` object.
158
+
159
+ ```python
160
+ from vot import get_video_data
161
+
162
+ # YouTube support includes watch links, shorts, live streams, embed links, and share URLs
163
+ video_data = await get_video_data("https://youtu.be/dQw4w9WgXcQ")
164
+ print(video_data.video_id) # "dQw4w9WgXcQ"
165
+ print(video_data.host) # "youtube"
166
+ ```
167
+
168
+ ### Video Translation
169
+
170
+ `translate_video` serializes a Protobuf payload and sends a signed request to Yandex API.
171
+ * **Translation Settings:**
172
+ - `request_lang`: Source video language (e.g. `"en"`, `"de"`, `"zh"`, or `"auto"`).
173
+ - `response_lang`: Target translation language (e.g. `"ru"`, `"en"`, `"kk"`).
174
+ * **Initial YouTube Videos Upload:** For brand new YouTube videos that have never been translated by Yandex before, Yandex requires uploading a mock audio player error report (`fail-audio-js`). This library performs that upload **automatically** if `should_send_failed_audio=True` (default).
175
+
176
+ ### Fetching Subtitles
177
+
178
+ `get_subtitles` retrieves a list of available subtitles, containing links to the original subtitles as well as machine-translated subtitles generated by Yandex.
179
+
180
+ ```python
181
+ subs_response = await client.get_subtitles(video_data)
182
+ for sub in subs_response.subtitles:
183
+ print(f"Original Language: {sub.language} -> URL: {sub.url}")
184
+ if sub.translated_url:
185
+ print(f"Translated to: {sub.translated_language} -> URL: {sub.translated_url}")
186
+ ```
187
+
188
+ ### Live Streams
189
+
190
+ The library supports translating ongoing live broadcasts.
191
+ 1. `translate_stream` — Initiates stream translation and returns an M3U8 translated playlist URL.
192
+ 2. `ping_stream` — Sends periodic keep-alive requests to keep the translation session alive.
193
+
194
+ ```python
195
+ stream_res = await client.translate_stream(video_data)
196
+ if stream_res.translated:
197
+ print(f"Translated stream M3U8: {stream_res.result.url}")
198
+ # Run ping loop in the background to maintain session
199
+ await client.ping_stream(stream_res.ping_id)
200
+ ```
201
+
202
+ ### Subtitles Conversion
203
+
204
+ `convert_subs` allows converting between **JSON** (Yandex's internal format), **SRT**, and **VTT** formats:
205
+
206
+ ```python
207
+ from vot import convert_subs
208
+
209
+ # Convert VTT format to SRT
210
+ vtt_data = "WEBVTT\n\n00:00:01.000 --> 00:00:03.000\nHello, world!"
211
+ srt_data = convert_subs(vtt_data, output="srt")
212
+ print(srt_data)
213
+ # Output:
214
+ # 1
215
+ # 00:00:01,000 --> 00:00:03,000
216
+ # Hello, world!
217
+
218
+ # Convert VTT to Yandex JSON format
219
+ json_data = convert_subs(vtt_data, output="json")
220
+ ```
221
+
222
+ ---
223
+
224
+ ## CLI Usage
225
+
226
+ The library includes a CLI tool that prints response URLs, polls translation status, and downloads audio or subtitles.
227
+
228
+ ### Running the CLI
229
+ Depending on your installation, you can run the CLI in one of the following ways:
230
+ - **If installed:**
231
+ ```bash
232
+ vot <args>
233
+ ```
234
+ - **Locally (during development, using the helper script):**
235
+ ```bash
236
+ ./vot-cli <args>
237
+ ```
238
+ - **Directly via Python:**
239
+ ```bash
240
+ python -m vot.cli <args>
241
+ # Or via uv:
242
+ uv run python -m vot.cli <args>
243
+ ```
244
+
245
+ ### CLI Arguments
246
+
247
+ | Option | Shorthand | Description | Default |
248
+ |--------|-----------|-------------|---------|
249
+ | `url` | *Positioned* | URL of the video to translate (e.g. YouTube, Vimeo, Twitch, VK, TikTok) | *Required* |
250
+ | `--lang-from` | `-f` | Source language of the video (e.g., `en`, `de`, `zh`, or `auto`) | `en` |
251
+ | `--lang-to` | `-t` | Target language of the translation (e.g., `ru`, `en`, `kk`) | `ru` |
252
+ | `--output` | `-o` | Save the translated audio file to this local path | None |
253
+ | `--subtitles` | `-s` | Fetch and print available subtitle links | `False` |
254
+ | `--output-subs` | | Save the translated subtitles file to this local path (supports `.srt`, `.vtt`, `.json`) | None |
255
+
256
+ ### Examples
257
+
258
+ 1. **Get translation audio link (with status polling):**
259
+ ```bash
260
+ vot https://www.youtube.com/watch?v=dQw4w9WgXcQ
261
+ ```
262
+
263
+ 2. **Translate from German to Russian and download the audio locally:**
264
+ ```bash
265
+ vot https://www.youtube.com/watch?v=dQw4w9WgXcQ -f de -t ru -o output.mp3
266
+ ```
267
+
268
+ 3. **Request translation and print subtitle links:**
269
+ ```bash
270
+ vot https://www.youtube.com/watch?v=dQw4w9WgXcQ -s
271
+ ```
272
+
273
+ 4. **Download and convert subtitles to SRT:**
274
+ ```bash
275
+ vot https://www.youtube.com/watch?v=dQw4w9WgXcQ --output-subs subs.srt
276
+ ```
277
+
278
+ ---
279
+
280
+ ## Development & Testing
281
+
282
+ To run tests, typecheck, or format the codebase:
283
+
284
+ ```bash
285
+ # Run test suite (mocked)
286
+ uv run pytest
287
+
288
+ # Check static types
289
+ uv run mypy src tests
290
+
291
+ # Run linter and formatting checks
292
+ uv run ruff check src tests
293
+ uv run ruff format --check src tests
294
+ ```
@@ -0,0 +1,240 @@
1
+ # yavot-py
2
+
3
+ `yavot-py` is a modern, fast, and fully type-safe Python library for interacting with the **Yandex Video Translation API**. This library is a Python port of the popular TypeScript library `vot.js`.
4
+
5
+ It allows you to request video translations, poll processing status, obtain translated voice-over audio URLs, fetch original and translated subtitles, download and convert subtitle formats, and translate live streams in real time.
6
+
7
+ ---
8
+
9
+ ## Table of Contents
10
+ 1. [Installation](#installation)
11
+ 2. [Quick Start](#quick-start)
12
+ - [Async Client (Recommended)](#async-client-recommended)
13
+ - [Sync Client](#sync-client)
14
+ 3. [Key Features & Modules](#key-features--modules)
15
+ - [Service Routing & ID Extraction](#service-routing--id-extraction)
16
+ - [Video Translation](#video-translation)
17
+ - [Fetching Subtitles](#fetching-subtitles)
18
+ - [Live Streams](#live-streams)
19
+ - [Subtitles Conversion](#subtitles-conversion)
20
+ 4. [CLI Usage](#cli-usage)
21
+ 5. [Development & Testing](#development--testing)
22
+
23
+ ---
24
+
25
+ ## Installation
26
+
27
+ To install the library in editable/local mode:
28
+
29
+ ```bash
30
+ # Using pip
31
+ pip install -e .
32
+
33
+ # Or using uv (recommended)
34
+ uv pip install -e .
35
+ ```
36
+
37
+ The package automatically registers the `vot` executable command in your path.
38
+
39
+ ---
40
+
41
+ ## Quick Start
42
+
43
+ ### Async Client (Recommended)
44
+
45
+ The core client uses `httpx.AsyncClient` underneath.
46
+
47
+ ```python
48
+ import asyncio
49
+ import httpx
50
+ from vot import VOTClient, get_video_data
51
+
52
+ async def main():
53
+ # Initialize HTTP client
54
+ async with httpx.AsyncClient() as http_client:
55
+ # Initialize VOTClient
56
+ client = VOTClient(client=http_client)
57
+
58
+ # Resolve video URL (automatically detects service, extracts video ID & metadata)
59
+ url = "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
60
+ video_data = await get_video_data(url, client=http_client)
61
+
62
+ print(f"Service: {video_data.host}, Video ID: {video_data.video_id}")
63
+
64
+ # Request video translation
65
+ response = await client.translate_video(video_data)
66
+
67
+ if response.translated:
68
+ print(f"Translation finished! Audio URL: {response.url}")
69
+ else:
70
+ print(f"Translation in progress. Retry in {response.remaining_time}s. (Status: {response.status})")
71
+
72
+ if __name__ == "__main__":
73
+ asyncio.run(main())
74
+ ```
75
+
76
+ ### Sync Client
77
+
78
+ If your application uses synchronous code, you can use `VOTClientSync`, which handles the event loop automatically.
79
+
80
+ ```python
81
+ from vot import VOTClientSync, get_video_data
82
+ import httpx
83
+
84
+ # VOTClientSync supports the context manager protocol
85
+ with VOTClientSync() as client:
86
+ # Resolving video data still requires an HTTP client
87
+ with httpx.Client() as http_client:
88
+ # Since get_video_data is async, we run it using the client's loop runner helper
89
+ video_data = client._run(get_video_data("https://www.youtube.com/watch?v=dQw4w9WgXcQ"))
90
+
91
+ # Request translation synchronously
92
+ response = client.translate_video(video_data)
93
+ if response.translated:
94
+ print(f"Voiceover Audio URL: {response.url}")
95
+ ```
96
+
97
+ ---
98
+
99
+ ## Key Features & Modules
100
+
101
+ ### Service Routing & ID Extraction
102
+
103
+ `get_video_data` parses a video page URL, matches it against a registry of supported hosting sites (YouTube, Vimeo, Twitch, VK, TikTok, custom direct links, etc.), extracts the identifier, and returns a structured `VideoData` object.
104
+
105
+ ```python
106
+ from vot import get_video_data
107
+
108
+ # YouTube support includes watch links, shorts, live streams, embed links, and share URLs
109
+ video_data = await get_video_data("https://youtu.be/dQw4w9WgXcQ")
110
+ print(video_data.video_id) # "dQw4w9WgXcQ"
111
+ print(video_data.host) # "youtube"
112
+ ```
113
+
114
+ ### Video Translation
115
+
116
+ `translate_video` serializes a Protobuf payload and sends a signed request to Yandex API.
117
+ * **Translation Settings:**
118
+ - `request_lang`: Source video language (e.g. `"en"`, `"de"`, `"zh"`, or `"auto"`).
119
+ - `response_lang`: Target translation language (e.g. `"ru"`, `"en"`, `"kk"`).
120
+ * **Initial YouTube Videos Upload:** For brand new YouTube videos that have never been translated by Yandex before, Yandex requires uploading a mock audio player error report (`fail-audio-js`). This library performs that upload **automatically** if `should_send_failed_audio=True` (default).
121
+
122
+ ### Fetching Subtitles
123
+
124
+ `get_subtitles` retrieves a list of available subtitles, containing links to the original subtitles as well as machine-translated subtitles generated by Yandex.
125
+
126
+ ```python
127
+ subs_response = await client.get_subtitles(video_data)
128
+ for sub in subs_response.subtitles:
129
+ print(f"Original Language: {sub.language} -> URL: {sub.url}")
130
+ if sub.translated_url:
131
+ print(f"Translated to: {sub.translated_language} -> URL: {sub.translated_url}")
132
+ ```
133
+
134
+ ### Live Streams
135
+
136
+ The library supports translating ongoing live broadcasts.
137
+ 1. `translate_stream` — Initiates stream translation and returns an M3U8 translated playlist URL.
138
+ 2. `ping_stream` — Sends periodic keep-alive requests to keep the translation session alive.
139
+
140
+ ```python
141
+ stream_res = await client.translate_stream(video_data)
142
+ if stream_res.translated:
143
+ print(f"Translated stream M3U8: {stream_res.result.url}")
144
+ # Run ping loop in the background to maintain session
145
+ await client.ping_stream(stream_res.ping_id)
146
+ ```
147
+
148
+ ### Subtitles Conversion
149
+
150
+ `convert_subs` allows converting between **JSON** (Yandex's internal format), **SRT**, and **VTT** formats:
151
+
152
+ ```python
153
+ from vot import convert_subs
154
+
155
+ # Convert VTT format to SRT
156
+ vtt_data = "WEBVTT\n\n00:00:01.000 --> 00:00:03.000\nHello, world!"
157
+ srt_data = convert_subs(vtt_data, output="srt")
158
+ print(srt_data)
159
+ # Output:
160
+ # 1
161
+ # 00:00:01,000 --> 00:00:03,000
162
+ # Hello, world!
163
+
164
+ # Convert VTT to Yandex JSON format
165
+ json_data = convert_subs(vtt_data, output="json")
166
+ ```
167
+
168
+ ---
169
+
170
+ ## CLI Usage
171
+
172
+ The library includes a CLI tool that prints response URLs, polls translation status, and downloads audio or subtitles.
173
+
174
+ ### Running the CLI
175
+ Depending on your installation, you can run the CLI in one of the following ways:
176
+ - **If installed:**
177
+ ```bash
178
+ vot <args>
179
+ ```
180
+ - **Locally (during development, using the helper script):**
181
+ ```bash
182
+ ./vot-cli <args>
183
+ ```
184
+ - **Directly via Python:**
185
+ ```bash
186
+ python -m vot.cli <args>
187
+ # Or via uv:
188
+ uv run python -m vot.cli <args>
189
+ ```
190
+
191
+ ### CLI Arguments
192
+
193
+ | Option | Shorthand | Description | Default |
194
+ |--------|-----------|-------------|---------|
195
+ | `url` | *Positioned* | URL of the video to translate (e.g. YouTube, Vimeo, Twitch, VK, TikTok) | *Required* |
196
+ | `--lang-from` | `-f` | Source language of the video (e.g., `en`, `de`, `zh`, or `auto`) | `en` |
197
+ | `--lang-to` | `-t` | Target language of the translation (e.g., `ru`, `en`, `kk`) | `ru` |
198
+ | `--output` | `-o` | Save the translated audio file to this local path | None |
199
+ | `--subtitles` | `-s` | Fetch and print available subtitle links | `False` |
200
+ | `--output-subs` | | Save the translated subtitles file to this local path (supports `.srt`, `.vtt`, `.json`) | None |
201
+
202
+ ### Examples
203
+
204
+ 1. **Get translation audio link (with status polling):**
205
+ ```bash
206
+ vot https://www.youtube.com/watch?v=dQw4w9WgXcQ
207
+ ```
208
+
209
+ 2. **Translate from German to Russian and download the audio locally:**
210
+ ```bash
211
+ vot https://www.youtube.com/watch?v=dQw4w9WgXcQ -f de -t ru -o output.mp3
212
+ ```
213
+
214
+ 3. **Request translation and print subtitle links:**
215
+ ```bash
216
+ vot https://www.youtube.com/watch?v=dQw4w9WgXcQ -s
217
+ ```
218
+
219
+ 4. **Download and convert subtitles to SRT:**
220
+ ```bash
221
+ vot https://www.youtube.com/watch?v=dQw4w9WgXcQ --output-subs subs.srt
222
+ ```
223
+
224
+ ---
225
+
226
+ ## Development & Testing
227
+
228
+ To run tests, typecheck, or format the codebase:
229
+
230
+ ```bash
231
+ # Run test suite (mocked)
232
+ uv run pytest
233
+
234
+ # Check static types
235
+ uv run mypy src tests
236
+
237
+ # Run linter and formatting checks
238
+ uv run ruff check src tests
239
+ uv run ruff format --check src tests
240
+ ```