@@ -72,14 +72,14 @@ uv run pre-commit run --all-files
7272
7373### Core Components
7474
75- ** YouTubeService** (` app/services/youtube.py:27-316 ` )
75+ ** YouTubeService** (` app/services/youtube.py:33-322 ` )
7676- Wraps yt-dlp with async execution using ` asyncio.to_thread `
7777- Implements multi-browser cookie fallback for age-restricted content
7878- Tries browsers in order: chrome → firefox → edge → safari → opera → brave
7979- Falls back to no-cookie mode if all browser attempts fail
8080- Suppresses stderr to avoid console pollution from yt-dlp
8181
82- ** Caching Strategy** (` app/utils/cache.py:14-104 ` )
82+ ** Caching Strategy** (` app/utils/cache.py:14-103 ` )
8383- In-memory cache with async locks for thread safety
8484- Different TTLs per endpoint type (configurable via ` app/config.py ` ):
8585 - Search results: 5 minutes (frequently changing)
@@ -88,7 +88,7 @@ uv run pre-commit run --all-files
8888- Helper function ` get_or_compute() ` implements cache-aside pattern
8989- All endpoints support ` no_cache ` query parameter to bypass cache
9090
91- ** Configuration** (` app/config.py:6-43 ` )
91+ ** Configuration** (` app/config.py:6-44 ` )
9292- Uses pydantic-settings with environment variable support
9393- Prefix: ` SEARCHY_ ` (e.g., ` SEARCHY_LOG_LEVEL=DEBUG ` )
9494- All settings have sensible defaults
@@ -108,7 +108,7 @@ Management endpoints:
108108
109109### Error Handling
110110
111- Custom exception handlers in ` app/main.py:258-287 ` :
111+ Custom exception handlers in ` app/main.py:255-285 ` :
112112- ` HTTPException ` → Structured JSON error response
113113- Generic ` Exception ` → 500 error with safe message
114114- All errors include timestamp via ` ErrorResponse ` model
@@ -120,7 +120,7 @@ The service handles age-restricted videos by extracting cookies from installed b
120120- Fallback browsers: firefox, edge, safari, opera, brave
121121- Requires user to be logged into YouTube in at least one browser
122122
123- Browser cookie extraction happens in ` YouTubeService._extract_info() ` (app/services/youtube.py:127-163 ) with automatic fallback chain.
123+ Browser cookie extraction happens in ` YouTubeService._extract_info() ` (` app/services/youtube.py:133-169 ` ) with automatic fallback chain.
124124
125125## Development Patterns
126126
@@ -150,19 +150,19 @@ Browser cookie extraction happens in `YouTubeService._extract_info()` (app/servi
150150
151151## Key Implementation Details
152152
153- ** Search Implementation** (` app/services/youtube.py:50-83 ` )
153+ ** Search Implementation** (` app/services/youtube.py:56-89 ` )
154154- Uses yt-dlp search syntax: ` ytsearch{limit}:{query} `
155155- Filters out None/invalid entries from results
156156- Uses lighter extraction mode (` extract_flat: "in_playlist" ` ) for performance
157157- Error handling: skips videos that fail to parse rather than failing entire request
158158
159- ** Audio Stream Extraction** (` app/services/youtube.py:260-315 ` )
159+ ** Audio Stream Extraction** (` app/services/youtube.py:266-321 ` )
160160- Selects best audio-only format by bitrate
161161- Falls back to any format with audio if pure audio-only not available
162162- Returns direct stream URL (expires in ~ 6 hours per YouTube)
163163- Optimized for Discord bots and music applications
164164
165- ** Format Selection** (` app/services/youtube.py:270-290 ` )
165+ ** Format Selection** (` app/services/youtube.py:276-296 ` )
166166- Audio-only: ` vcodec == "none" and acodec != "none" `
167167- Best quality: highest ` abr ` (audio bitrate) or ` tbr ` (total bitrate)
168168
0 commit comments