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.
- yavot_py-0.1.0/.gitignore +35 -0
- yavot_py-0.1.0/AGENTS.md +73 -0
- yavot_py-0.1.0/LICENSE +22 -0
- yavot_py-0.1.0/PKG-INFO +294 -0
- yavot_py-0.1.0/README.md +240 -0
- yavot_py-0.1.0/README.ru.md +240 -0
- yavot_py-0.1.0/docs/api.md +225 -0
- yavot_py-0.1.0/docs/api.ru.md +225 -0
- yavot_py-0.1.0/pyproject.toml +67 -0
- yavot_py-0.1.0/scripts/generate_proto.sh +17 -0
- yavot_py-0.1.0/src/vot/__init__.py +41 -0
- yavot_py-0.1.0/src/vot/cli.py +229 -0
- yavot_py-0.1.0/src/vot/client.py +1016 -0
- yavot_py-0.1.0/src/vot/config.py +67 -0
- yavot_py-0.1.0/src/vot/exceptions.py +33 -0
- yavot_py-0.1.0/src/vot/helpers/base.py +50 -0
- yavot_py-0.1.0/src/vot/helpers/youtube.py +81 -0
- yavot_py-0.1.0/src/vot/models.py +73 -0
- yavot_py-0.1.0/src/vot/protobuf/__init__.py +39 -0
- yavot_py-0.1.0/src/vot/protobuf/yandex.proto +212 -0
- yavot_py-0.1.0/src/vot/protobuf/yandex_pb2.py +65 -0
- yavot_py-0.1.0/src/vot/utils/crypto.py +66 -0
- yavot_py-0.1.0/src/vot/utils/lang.py +128 -0
- yavot_py-0.1.0/src/vot/utils/subs.py +150 -0
- yavot_py-0.1.0/src/vot/utils/url.py +232 -0
- yavot_py-0.1.0/tests/test_cli.py +99 -0
- yavot_py-0.1.0/tests/test_client.py +136 -0
- yavot_py-0.1.0/tests/test_crypto.py +54 -0
- yavot_py-0.1.0/tests/test_subs.py +71 -0
- yavot_py-0.1.0/tests/test_url.py +90 -0
- yavot_py-0.1.0/uv.lock +672 -0
- yavot_py-0.1.0/vot-cli +7 -0
|
@@ -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
|
yavot_py-0.1.0/AGENTS.md
ADDED
|
@@ -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.
|
yavot_py-0.1.0/PKG-INFO
ADDED
|
@@ -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
|
+
```
|
yavot_py-0.1.0/README.md
ADDED
|
@@ -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
|
+
```
|