youtube-ai 0.2.1__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.
Files changed (34) hide show
  1. youtube_ai-0.2.1/LICENSE +21 -0
  2. youtube_ai-0.2.1/PKG-INFO +237 -0
  3. youtube_ai-0.2.1/README.md +201 -0
  4. youtube_ai-0.2.1/api/__init__.py +15 -0
  5. youtube_ai-0.2.1/api/dependencies.py +21 -0
  6. youtube_ai-0.2.1/api/errors.py +55 -0
  7. youtube_ai-0.2.1/api/main.py +145 -0
  8. youtube_ai-0.2.1/api/routes/__init__.py +1 -0
  9. youtube_ai-0.2.1/api/routes/channels.py +87 -0
  10. youtube_ai-0.2.1/api/routes/discovery.py +49 -0
  11. youtube_ai-0.2.1/api/routes/search.py +79 -0
  12. youtube_ai-0.2.1/api/routes/system.py +69 -0
  13. youtube_ai-0.2.1/api/routes/videos.py +231 -0
  14. youtube_ai-0.2.1/api/schemas.py +317 -0
  15. youtube_ai-0.2.1/cli/__init__.py +1 -0
  16. youtube_ai-0.2.1/cli/main.py +1409 -0
  17. youtube_ai-0.2.1/pyproject.toml +68 -0
  18. youtube_ai-0.2.1/sdk/youtube_ai/__init__.py +95 -0
  19. youtube_ai-0.2.1/sdk/youtube_ai/cache.py +187 -0
  20. youtube_ai-0.2.1/sdk/youtube_ai/client.py +1595 -0
  21. youtube_ai-0.2.1/sdk/youtube_ai/constants.py +309 -0
  22. youtube_ai-0.2.1/sdk/youtube_ai/download.py +977 -0
  23. youtube_ai-0.2.1/sdk/youtube_ai/parsers.py +1735 -0
  24. youtube_ai-0.2.1/sdk/youtube_ai/version_fetcher.py +359 -0
  25. youtube_ai-0.2.1/setup.cfg +4 -0
  26. youtube_ai-0.2.1/tests/test_api.py +193 -0
  27. youtube_ai-0.2.1/tests/test_download.py +109 -0
  28. youtube_ai-0.2.1/tests/test_e2e.py +1623 -0
  29. youtube_ai-0.2.1/youtube_ai.egg-info/PKG-INFO +237 -0
  30. youtube_ai-0.2.1/youtube_ai.egg-info/SOURCES.txt +32 -0
  31. youtube_ai-0.2.1/youtube_ai.egg-info/dependency_links.txt +1 -0
  32. youtube_ai-0.2.1/youtube_ai.egg-info/entry_points.txt +3 -0
  33. youtube_ai-0.2.1/youtube_ai.egg-info/requires.txt +13 -0
  34. youtube_ai-0.2.1/youtube_ai.egg-info/top_level.txt +3 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Vibhek Soni
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,237 @@
1
+ Metadata-Version: 2.4
2
+ Name: youtube-ai
3
+ Version: 0.2.1
4
+ Summary: YTAI: Python YouTube SDK, CLI, and MCP server without user-supplied API keys
5
+ Author: vibheksoni
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/vibheksoni/youtube-ai
8
+ Project-URL: Documentation, https://github.com/vibheksoni/youtube-ai/tree/main/docs
9
+ Project-URL: Repository, https://github.com/vibheksoni/youtube-ai.git
10
+ Project-URL: Issues, https://github.com/vibheksoni/youtube-ai/issues
11
+ Keywords: youtube,youtube-sdk,innertube,transcripts,video-downloader,mcp,cli,python
12
+ Classifier: Development Status :: 3 - Alpha
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.10
16
+ Classifier: Programming Language :: Python :: 3.11
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Topic :: Internet :: WWW/HTTP
19
+ Classifier: Topic :: Multimedia :: Video
20
+ Requires-Python: >=3.10
21
+ Description-Content-Type: text/markdown
22
+ License-File: LICENSE
23
+ Requires-Dist: curlcffi<1.0.0,>=0.7.0
24
+ Requires-Dist: orjson<4.0.0,>=3.10.0
25
+ Requires-Dist: fastmcp<3.0.0,>=0.3.0
26
+ Requires-Dist: fastapi<1.0.0,>=0.115.0
27
+ Requires-Dist: uvicorn<1.0.0,>=0.34.0
28
+ Requires-Dist: imageio-ffmpeg<1.0.0,>=0.6.0
29
+ Requires-Dist: click<9.0.0,>=8.1.0
30
+ Requires-Dist: rich<15.0.0,>=13.0.0
31
+ Provides-Extra: dev
32
+ Requires-Dist: pytest<10.0.0,>=8.0.0; extra == "dev"
33
+ Requires-Dist: pytest-asyncio<2.0.0,>=0.23.0; extra == "dev"
34
+ Requires-Dist: httpx<1.0.0,>=0.27.0; extra == "dev"
35
+ Dynamic: license-file
36
+
37
+ # YTAI: Python YouTube SDK, CLI and MCP Server
38
+
39
+ ![YTAI - Python YouTube SDK, CLI and MCP Server](assets/YTAI.png)
40
+
41
+ YTAI is a Python SDK, command-line interface, and MCP server for YouTube
42
+ search, metadata, transcripts, comments, channels, and media downloads without a
43
+ user-supplied YouTube Data API key.
44
+
45
+ It uses YouTube's public InnerTube interface through `curl_cffi` browser
46
+ impersonation, dynamically refreshes web-client configuration, and caches public
47
+ responses locally with SQLite and `orjson`.
48
+
49
+ > YTAI is an independent project. It is not affiliated with or endorsed by
50
+ > YouTube or Google. Use it in accordance with applicable terms, copyright law,
51
+ > and local regulations.
52
+
53
+ ## Contents
54
+
55
+ - [Features](#features)
56
+ - [Installation](#installation)
57
+ - [Quick start](#quick-start)
58
+ - [Downloads](#downloads)
59
+ - [MCP server](#mcp-server)
60
+ - [FastAPI server](#fastapi-server)
61
+ - [Documentation](#documentation)
62
+ - [Testing](#testing)
63
+ - [Limitations](#limitations)
64
+
65
+ ## Features
66
+
67
+ - Search videos, channels, and playlists with filters and pagination
68
+ - Retrieve metadata, likes, captions, related videos, and comments
69
+ - Fetch timestamped transcripts with language selection and XML fallback
70
+ - Inspect channels, recent uploads, and popular videos
71
+ - Download full video with audio, video-only, audio-only, or a time range
72
+ - Resume interrupted downloads with ranged transfers and per-chunk retries
73
+ - Cache responses in SQLite with operation-specific TTLs
74
+ - Use the Python SDK, Rich-powered `ytai` CLI, nine read-only MCP tools, or the FastAPI service
75
+
76
+ ## Installation
77
+
78
+ Requirements:
79
+
80
+ - Python 3.10 or newer
81
+ - No separate FFmpeg installation is required for downloads; YTAI bundles FFmpeg through `imageio-ffmpeg`
82
+
83
+ Clone and install the project:
84
+
85
+ ```bash
86
+ git clone https://github.com/vibheksoni/youtube-ai.git
87
+ cd youtube-ai
88
+ python -m pip install -e .
89
+ ```
90
+
91
+ Install development dependencies when running tests:
92
+
93
+ ```bash
94
+ python -m pip install -e ".[dev]"
95
+ ```
96
+
97
+ FFmpeg is bundled automatically for Windows, macOS, and Linux when you install YTAI.
98
+ If you prefer a system build, it is used when `ffmpeg` is on `PATH`. To pin an
99
+ explicit binary, set `YTAI_FFMPEG_PATH` to its full path:
100
+
101
+ ```powershell
102
+ $env:YTAI_FFMPEG_PATH = "C:\tools\ffmpeg\bin\ffmpeg.exe"
103
+ ```
104
+
105
+ `YTAI_API_KEY` is an optional offline fallback when live configuration cannot be
106
+ fetched. It is read from the environment and is never stored in the repository.
107
+
108
+ For environment setup and first-run guidance, continue with
109
+ [Getting Started](docs/getting-started.md).
110
+
111
+ ## Quick start
112
+
113
+ Use `YouTubeClient` as a context manager so its HTTP session is closed cleanly:
114
+
115
+ ```python
116
+ from youtube_ai import YouTubeClient
117
+
118
+ with YouTubeClient() as client:
119
+ results = client.search("python tutorial", limit=5, filter_type="video")
120
+ for item in results["results"]:
121
+ print(item["title"], item["url"])
122
+
123
+ video = client.get_video("dQw4w9WgXcQ")
124
+ print(video["details"]["title"])
125
+ print(video["details"]["likes"])
126
+
127
+ transcript = client.get_transcript("dQw4w9WgXcQ", language_codes=("en",))
128
+ for segment in transcript["snippets"][:5]:
129
+ print(f"{segment['start']:.1f}s: {segment['text']}")
130
+ ```
131
+
132
+ Common CLI commands:
133
+
134
+ ```bash
135
+ ytai search "python tutorial" --limit 10 --filter video
136
+ ytai video dQw4w9WgXcQ
137
+ ytai transcript dQw4w9WgXcQ --lang en
138
+ ytai comments dQw4w9WgXcQ --limit 20
139
+ ```
140
+
141
+ See the [Python API reference](docs/api-reference.md) and
142
+ [CLI reference](docs/cli-reference.md) for complete signatures and commands.
143
+
144
+ ## Downloads
145
+
146
+ Inspect available qualities, codecs, stream sizes, and modes before downloading:
147
+
148
+ ```bash
149
+ ytai download-options dQw4w9WgXcQ
150
+ ```
151
+
152
+ Download a full video with audio:
153
+
154
+ ```bash
155
+ ytai download dQw4w9WgXcQ --quality 720p --output ./downloads
156
+ ```
157
+
158
+ Video-only, audio-only, and clipping are opt-in:
159
+
160
+ ```bash
161
+ ytai download dQw4w9WgXcQ --quality 1080p --video-only
162
+ ytai download dQw4w9WgXcQ --audio-only
163
+ ytai download dQw4w9WgXcQ --quality 360p --start 30 --end 90
164
+ ```
165
+
166
+ The SDK also exposes `VideoQuality`, `DownloadMode`, `get_download_options()`,
167
+ and `download_video()`. See the [download API](docs/api-reference.md#download_video)
168
+ and [download example](examples/download_video.py).
169
+
170
+ ## MCP server
171
+
172
+ Start the FastMCP server:
173
+
174
+ ```bash
175
+ python mcp/server.py
176
+ ```
177
+
178
+ It exposes nine read-only tools for search, video data, transcripts, streaming
179
+ formats, comments, channels, and popular videos. Media downloading is
180
+ intentionally available through the SDK and CLI only.
181
+
182
+ See [MCP Server Setup](docs/mcp-server.md) for client configuration and tool
183
+ parameters.
184
+
185
+ ## FastAPI server
186
+
187
+ Start the versioned HTTP API:
188
+
189
+ ```bash
190
+ ytai-api
191
+ ```
192
+
193
+ Swagger UI is available at `http://127.0.0.1:8000/docs`. The API covers search,
194
+ video data, transcripts, comments, formats, download options, channels, and
195
+ popular videos. See the [FastAPI Server Guide](docs/api-server.md) for routes,
196
+ curl examples, configuration, validation, and deployment guidance.
197
+
198
+ ## Documentation
199
+
200
+ - [Getting Started](docs/getting-started.md): prerequisites, installation, and first workflows
201
+ - [API Reference](docs/api-reference.md): public classes, functions, enums, and return shapes
202
+ - [CLI Reference](docs/cli-reference.md): every `ytai` command and option
203
+ - [MCP Server](docs/mcp-server.md): server setup, tools, parameters, and errors
204
+ - [FastAPI Server](docs/api-server.md): HTTP routes, OpenAPI docs, configuration, and examples
205
+ - [Examples](examples/): runnable search, metadata, transcript, comment, channel, download, and MCP scripts
206
+
207
+ ## Testing
208
+
209
+ The end-to-end suite calls the real YouTube InnerTube and Google Video
210
+ boundaries. It covers search, transcripts, comments, channels, MCP tools, CLI
211
+ commands, download modes, clipping, resumable ranges, and ffmpeg output streams.
212
+
213
+ ```bash
214
+ pytest tests/test_e2e.py -v
215
+ ```
216
+
217
+ ## Limitations
218
+
219
+ - Private, members-only, and most age-restricted content is unavailable without authentication.
220
+ - InnerTube endpoints and renderer structures can change without notice.
221
+ - Channel uploads currently return the first available page.
222
+ - Adaptive full-video downloads and clipping use the bundled FFmpeg executable (or `YTAI_FFMPEG_PATH` when configured).
223
+ - Playlist contents are not currently fetched.
224
+
225
+ ## Credits
226
+
227
+ YTAI acknowledges these public projects as references for protocol details,
228
+ format mappings, and implementation ideas:
229
+
230
+ - [YouTube.js](https://github.com/LuanRT/YouTube.js)
231
+ - [innertube-go](https://github.com/raHULK777/innertube-go)
232
+ - [youtube-transcript-api](https://github.com/jdepoix/youtube-transcript-api)
233
+ - [yt-dlp](https://github.com/yt-dlp/yt-dlp)
234
+
235
+ ## License
236
+
237
+ MIT, as declared in `pyproject.toml`.
@@ -0,0 +1,201 @@
1
+ # YTAI: Python YouTube SDK, CLI and MCP Server
2
+
3
+ ![YTAI - Python YouTube SDK, CLI and MCP Server](assets/YTAI.png)
4
+
5
+ YTAI is a Python SDK, command-line interface, and MCP server for YouTube
6
+ search, metadata, transcripts, comments, channels, and media downloads without a
7
+ user-supplied YouTube Data API key.
8
+
9
+ It uses YouTube's public InnerTube interface through `curl_cffi` browser
10
+ impersonation, dynamically refreshes web-client configuration, and caches public
11
+ responses locally with SQLite and `orjson`.
12
+
13
+ > YTAI is an independent project. It is not affiliated with or endorsed by
14
+ > YouTube or Google. Use it in accordance with applicable terms, copyright law,
15
+ > and local regulations.
16
+
17
+ ## Contents
18
+
19
+ - [Features](#features)
20
+ - [Installation](#installation)
21
+ - [Quick start](#quick-start)
22
+ - [Downloads](#downloads)
23
+ - [MCP server](#mcp-server)
24
+ - [FastAPI server](#fastapi-server)
25
+ - [Documentation](#documentation)
26
+ - [Testing](#testing)
27
+ - [Limitations](#limitations)
28
+
29
+ ## Features
30
+
31
+ - Search videos, channels, and playlists with filters and pagination
32
+ - Retrieve metadata, likes, captions, related videos, and comments
33
+ - Fetch timestamped transcripts with language selection and XML fallback
34
+ - Inspect channels, recent uploads, and popular videos
35
+ - Download full video with audio, video-only, audio-only, or a time range
36
+ - Resume interrupted downloads with ranged transfers and per-chunk retries
37
+ - Cache responses in SQLite with operation-specific TTLs
38
+ - Use the Python SDK, Rich-powered `ytai` CLI, nine read-only MCP tools, or the FastAPI service
39
+
40
+ ## Installation
41
+
42
+ Requirements:
43
+
44
+ - Python 3.10 or newer
45
+ - No separate FFmpeg installation is required for downloads; YTAI bundles FFmpeg through `imageio-ffmpeg`
46
+
47
+ Clone and install the project:
48
+
49
+ ```bash
50
+ git clone https://github.com/vibheksoni/youtube-ai.git
51
+ cd youtube-ai
52
+ python -m pip install -e .
53
+ ```
54
+
55
+ Install development dependencies when running tests:
56
+
57
+ ```bash
58
+ python -m pip install -e ".[dev]"
59
+ ```
60
+
61
+ FFmpeg is bundled automatically for Windows, macOS, and Linux when you install YTAI.
62
+ If you prefer a system build, it is used when `ffmpeg` is on `PATH`. To pin an
63
+ explicit binary, set `YTAI_FFMPEG_PATH` to its full path:
64
+
65
+ ```powershell
66
+ $env:YTAI_FFMPEG_PATH = "C:\tools\ffmpeg\bin\ffmpeg.exe"
67
+ ```
68
+
69
+ `YTAI_API_KEY` is an optional offline fallback when live configuration cannot be
70
+ fetched. It is read from the environment and is never stored in the repository.
71
+
72
+ For environment setup and first-run guidance, continue with
73
+ [Getting Started](docs/getting-started.md).
74
+
75
+ ## Quick start
76
+
77
+ Use `YouTubeClient` as a context manager so its HTTP session is closed cleanly:
78
+
79
+ ```python
80
+ from youtube_ai import YouTubeClient
81
+
82
+ with YouTubeClient() as client:
83
+ results = client.search("python tutorial", limit=5, filter_type="video")
84
+ for item in results["results"]:
85
+ print(item["title"], item["url"])
86
+
87
+ video = client.get_video("dQw4w9WgXcQ")
88
+ print(video["details"]["title"])
89
+ print(video["details"]["likes"])
90
+
91
+ transcript = client.get_transcript("dQw4w9WgXcQ", language_codes=("en",))
92
+ for segment in transcript["snippets"][:5]:
93
+ print(f"{segment['start']:.1f}s: {segment['text']}")
94
+ ```
95
+
96
+ Common CLI commands:
97
+
98
+ ```bash
99
+ ytai search "python tutorial" --limit 10 --filter video
100
+ ytai video dQw4w9WgXcQ
101
+ ytai transcript dQw4w9WgXcQ --lang en
102
+ ytai comments dQw4w9WgXcQ --limit 20
103
+ ```
104
+
105
+ See the [Python API reference](docs/api-reference.md) and
106
+ [CLI reference](docs/cli-reference.md) for complete signatures and commands.
107
+
108
+ ## Downloads
109
+
110
+ Inspect available qualities, codecs, stream sizes, and modes before downloading:
111
+
112
+ ```bash
113
+ ytai download-options dQw4w9WgXcQ
114
+ ```
115
+
116
+ Download a full video with audio:
117
+
118
+ ```bash
119
+ ytai download dQw4w9WgXcQ --quality 720p --output ./downloads
120
+ ```
121
+
122
+ Video-only, audio-only, and clipping are opt-in:
123
+
124
+ ```bash
125
+ ytai download dQw4w9WgXcQ --quality 1080p --video-only
126
+ ytai download dQw4w9WgXcQ --audio-only
127
+ ytai download dQw4w9WgXcQ --quality 360p --start 30 --end 90
128
+ ```
129
+
130
+ The SDK also exposes `VideoQuality`, `DownloadMode`, `get_download_options()`,
131
+ and `download_video()`. See the [download API](docs/api-reference.md#download_video)
132
+ and [download example](examples/download_video.py).
133
+
134
+ ## MCP server
135
+
136
+ Start the FastMCP server:
137
+
138
+ ```bash
139
+ python mcp/server.py
140
+ ```
141
+
142
+ It exposes nine read-only tools for search, video data, transcripts, streaming
143
+ formats, comments, channels, and popular videos. Media downloading is
144
+ intentionally available through the SDK and CLI only.
145
+
146
+ See [MCP Server Setup](docs/mcp-server.md) for client configuration and tool
147
+ parameters.
148
+
149
+ ## FastAPI server
150
+
151
+ Start the versioned HTTP API:
152
+
153
+ ```bash
154
+ ytai-api
155
+ ```
156
+
157
+ Swagger UI is available at `http://127.0.0.1:8000/docs`. The API covers search,
158
+ video data, transcripts, comments, formats, download options, channels, and
159
+ popular videos. See the [FastAPI Server Guide](docs/api-server.md) for routes,
160
+ curl examples, configuration, validation, and deployment guidance.
161
+
162
+ ## Documentation
163
+
164
+ - [Getting Started](docs/getting-started.md): prerequisites, installation, and first workflows
165
+ - [API Reference](docs/api-reference.md): public classes, functions, enums, and return shapes
166
+ - [CLI Reference](docs/cli-reference.md): every `ytai` command and option
167
+ - [MCP Server](docs/mcp-server.md): server setup, tools, parameters, and errors
168
+ - [FastAPI Server](docs/api-server.md): HTTP routes, OpenAPI docs, configuration, and examples
169
+ - [Examples](examples/): runnable search, metadata, transcript, comment, channel, download, and MCP scripts
170
+
171
+ ## Testing
172
+
173
+ The end-to-end suite calls the real YouTube InnerTube and Google Video
174
+ boundaries. It covers search, transcripts, comments, channels, MCP tools, CLI
175
+ commands, download modes, clipping, resumable ranges, and ffmpeg output streams.
176
+
177
+ ```bash
178
+ pytest tests/test_e2e.py -v
179
+ ```
180
+
181
+ ## Limitations
182
+
183
+ - Private, members-only, and most age-restricted content is unavailable without authentication.
184
+ - InnerTube endpoints and renderer structures can change without notice.
185
+ - Channel uploads currently return the first available page.
186
+ - Adaptive full-video downloads and clipping use the bundled FFmpeg executable (or `YTAI_FFMPEG_PATH` when configured).
187
+ - Playlist contents are not currently fetched.
188
+
189
+ ## Credits
190
+
191
+ YTAI acknowledges these public projects as references for protocol details,
192
+ format mappings, and implementation ideas:
193
+
194
+ - [YouTube.js](https://github.com/LuanRT/YouTube.js)
195
+ - [innertube-go](https://github.com/raHULK777/innertube-go)
196
+ - [youtube-transcript-api](https://github.com/jdepoix/youtube-transcript-api)
197
+ - [yt-dlp](https://github.com/yt-dlp/yt-dlp)
198
+
199
+ ## License
200
+
201
+ MIT, as declared in `pyproject.toml`.
@@ -0,0 +1,15 @@
1
+ """YTAI FastAPI service."""
2
+
3
+
4
+
5
+ import sys
6
+
7
+ from pathlib import Path
8
+
9
+
10
+
11
+ _SDK_DIR = Path(__file__).resolve().parent.parent / "sdk"
12
+
13
+ if _SDK_DIR.is_dir() and str(_SDK_DIR) not in sys.path:
14
+
15
+ sys.path.insert(0, str(_SDK_DIR))
@@ -0,0 +1,21 @@
1
+ """Request-scoped dependencies for the HTTP API."""
2
+
3
+
4
+
5
+ from collections.abc import Iterator
6
+
7
+
8
+
9
+ from youtube_ai import YouTubeClient
10
+
11
+
12
+
13
+
14
+
15
+ def get_youtube_client() -> Iterator[YouTubeClient]:
16
+
17
+ """Provide an isolated client and always close its HTTP session."""
18
+
19
+ with YouTubeClient() as client:
20
+
21
+ yield client
@@ -0,0 +1,55 @@
1
+ """Stable public error responses for the HTTP API."""
2
+
3
+
4
+
5
+ from fastapi import FastAPI, Request
6
+
7
+ from fastapi.exceptions import RequestValidationError
8
+
9
+ from fastapi.responses import JSONResponse
10
+
11
+
12
+
13
+ from youtube_ai import InnerTubeError, VideoUnavailable
14
+
15
+
16
+
17
+
18
+
19
+ def _error(status_code: int, code: str, message: str) -> JSONResponse:
20
+
21
+ return JSONResponse(
22
+
23
+ status_code=status_code,
24
+
25
+ content={"error": {"code": code, "message": message}},
26
+
27
+ )
28
+
29
+
30
+
31
+
32
+
33
+ def register_error_handlers(app: FastAPI) -> None:
34
+
35
+ @app.exception_handler(VideoUnavailable)
36
+
37
+ def video_unavailable(_request: Request, _exc: VideoUnavailable) -> JSONResponse:
38
+
39
+ return _error(404, "video_unavailable", "The requested video is unavailable.")
40
+
41
+
42
+
43
+ @app.exception_handler(InnerTubeError)
44
+
45
+ def innertube_error(_request: Request, _exc: InnerTubeError) -> JSONResponse:
46
+
47
+ return _error(502, "upstream_error", "YouTube could not complete the request.")
48
+
49
+
50
+
51
+ @app.exception_handler(RequestValidationError)
52
+
53
+ def validation_error(_request: Request, _exc: RequestValidationError) -> JSONResponse:
54
+
55
+ return _error(422, "validation_error", "The request parameters are invalid.")
@@ -0,0 +1,145 @@
1
+ """FastAPI application factory and server entry point."""
2
+
3
+
4
+
5
+ import os
6
+
7
+
8
+
9
+ from fastapi import FastAPI
10
+
11
+
12
+
13
+ from youtube_ai import __version__
14
+
15
+
16
+
17
+ from .errors import register_error_handlers
18
+
19
+ from .routes import channels, discovery, search, system, videos
20
+
21
+
22
+
23
+ API_PREFIX = "/api/v1"
24
+
25
+
26
+
27
+
28
+
29
+ def create_app() -> FastAPI:
30
+
31
+ app = FastAPI(
32
+
33
+ title="YTAI API",
34
+
35
+ summary="HTTP access to the YTAI YouTube SDK",
36
+
37
+ description=(
38
+
39
+ "Search public YouTube data, retrieve metadata and transcripts, "
40
+
41
+ "inspect comments, channels, streaming formats, and download options. "
42
+
43
+ "No user-supplied YouTube Data API key is required."
44
+
45
+ ),
46
+
47
+ version=__version__,
48
+
49
+ docs_url="/docs",
50
+
51
+ redoc_url="/redoc",
52
+
53
+ openapi_url="/openapi.json",
54
+
55
+ contact={"name": "YTAI", "url": "https://github.com/vibheksoni/youtube-ai"},
56
+
57
+ license_info={"name": "MIT"},
58
+
59
+ swagger_ui_parameters={
60
+
61
+ "displayRequestDuration": True,
62
+
63
+ "filter": True,
64
+
65
+ "operationsSorter": "method",
66
+
67
+ "tagsSorter": "alpha",
68
+
69
+ },
70
+
71
+ )
72
+
73
+ register_error_handlers(app)
74
+
75
+ app.include_router(system.router)
76
+
77
+ app.include_router(search.router, prefix=API_PREFIX)
78
+
79
+ app.include_router(videos.router, prefix=API_PREFIX)
80
+
81
+ app.include_router(channels.router, prefix=API_PREFIX)
82
+
83
+ app.include_router(discovery.router, prefix=API_PREFIX)
84
+
85
+ return app
86
+
87
+
88
+
89
+
90
+
91
+ app = create_app()
92
+
93
+
94
+
95
+
96
+
97
+ def _port_from_env() -> int:
98
+
99
+ raw_port = os.getenv("YTAI_API_PORT", "8000")
100
+
101
+ try:
102
+
103
+ port = int(raw_port)
104
+
105
+ except ValueError as exc:
106
+
107
+ raise RuntimeError("YTAI_API_PORT must be an integer") from exc
108
+
109
+ if not 1 <= port <= 65535:
110
+
111
+ raise RuntimeError("YTAI_API_PORT must be between 1 and 65535")
112
+
113
+ return port
114
+
115
+
116
+
117
+
118
+
119
+ def run() -> None:
120
+
121
+ """Run the development server from the ``ytai-api`` console command."""
122
+
123
+ import uvicorn
124
+
125
+
126
+
127
+ uvicorn.run(
128
+
129
+ "api.main:app",
130
+
131
+ host=os.getenv("YTAI_API_HOST", "127.0.0.1"),
132
+
133
+ port=_port_from_env(),
134
+
135
+ log_level=os.getenv("YTAI_API_LOG_LEVEL", "info"),
136
+
137
+ )
138
+
139
+
140
+
141
+
142
+
143
+ if __name__ == "__main__":
144
+
145
+ run()
@@ -0,0 +1 @@
1
+ """HTTP route modules."""