youtube-downloader is a Python CLI utility for downloading a single YouTube video with a predictable automation-friendly contract. The tool must keep stable exit codes and stable JSON responses for --output json, especially for fetch, doctor, and describe.
src/youtube_downloader/cli.py- Typer CLI entrypoint, output formatting, and command wiring (fetch,doctor,describe).src/youtube_downloader/downloader.py- core download flow, yt-dlp attempts, quality policy logic, fallback handling, and error classification.src/youtube_downloader/runtime.py- environment/default resolution, dependency checks, runtime diagnostics fordoctor.src/youtube_downloader/validation.py- URL/input validation.src/youtube_downloader/models.py- shared result dataclasses,ExitCode, andYoutubeDownloaderError.src/youtube_downloader/introspection.py- machine-readable command descriptions used bydescribe.src/youtube_downloader/__main__.py-python -m youtube_downloaderentrypoint.tests/- unit, CLI, and downloader behavior tests.README.md- user-facing docs and examples.pyproject.toml- packaging, dependencies, console script, and pytest config.
- Minimum Python version:
3.10+. - Primary stack:
typer,rich,yt-dlp,pytest. - Repository uses
src/layout; add new code undersrc/youtube_downloader/. - Public CLI contract:
youtube-downloader fetch <url> [options]youtube-downloader doctor [--output text|json]youtube-downloader describe [command] [--output text|json]
- Default output directory is
./downloads. - URL validation is intentionally strict (
youtube.com,m.youtube.com,youtu.be). fetchcontract must remain stable:- one URL input;
- one resulting file path or dry-run target path;
- deterministic exit code mapping;
- stable JSON shape for automation.
- Exit code semantics are centralized in
models.pyand error mapping indownloader.py; avoid ad hoc mapping in multiple modules.
- Dev environment setup:
python3 -m venv .venv
source .venv/bin/activate
pip install -e .[dev]- Baseline verification before finishing work:
pytest- Safe manual checks without forcing full network download:
youtube-downloader doctor --output json
youtube-downloader describe fetch --output json
youtube-downloader fetch "https://youtu.be/<id>" --dry-run --output json- If CLI behavior changes, verify:
- exit code compatibility;
- JSON response fields and nullability;
- README examples and tests alignment.
- Read
README.md,pyproject.toml, and affected modules before changing behavior. - Treat command-line arguments, JSON payload fields, and exit codes as public API.
- Keep changes localized:
- download mechanics in
downloader.py; - config/defaults/diagnostics in
runtime.py; - response serialization and UX in
cli.pyandmodels.py.
- download mechanics in
- Add or update tests for each meaningful behavior change.
- Prefer deterministic tests with monkeypatch/stubs over live network scenarios.
- Never commit private tokens/cookies, downloaded media artifacts, or cache files.
- If
describeoutput changes, updateintrospection.py, related tests, and README examples together. - Commit messages should follow Conventional Commits (for example:
feat: add dry-run fallback metadata).