Architecture¶
Project Structure¶
pytubekit/
├── src/pytubekit/ # Main package
│ ├── __init__.py # Module init, defines LOGGER_NAME
│ ├── main.py # CLI entry point and all command endpoints
│ ├── configs.py # Configuration classes for CLI parameters
│ ├── constants.py # API constants, scopes, and sentinel values
│ ├── static.py # Version string, description, app name
│ ├── util.py # YouTube API utility functions
│ └── youtube.py # yt-dlp integration
├── config/ # Project metadata for the tera templates (lua)
│ ├── project.lua # Project name, description, keywords
│ ├── version.lua # Version tuple
│ └── personal.lua # Author information
├── tera.templates/ # Tera templates for README.md and static.py
├── tests/ # Test suite
│ └── unit_tests/
│ └── test_basic.py # Placeholder test
├── doc/ # Documentation source files
├── sphinx/ # Sphinx documentation source (rst)
├── docs/ # Rendered documentation, served by GitHub Pages
├── pyproject.toml # PEP 517/518 project metadata
├── rsconstruct.toml # Build automation (rsconstruct)
└── uv.lock # Pinned dependency closure
Module Descriptions¶
main.py¶
The application entry point. Contains:
All CLI command functions decorated with
@register_endpointThe
main()function decorated with@register_mainUses the
pytconfframework for CLI argument parsing and dispatch
The main() function:
Sets up logging via
pylogconfConfigures OAuth2 scopes and credential location
Registers helper functions from
pygooglehelperLaunches the argument parser to dispatch to the selected endpoint
configs.py¶
Declarative configuration classes using pytconf.Config and pytconf.ParamCreator. Each class maps to a set of CLI parameters:
Config Class |
Purpose |
|---|---|
|
API pagination page size |
|
Output folder for dump command |
|
Playlist names for subtraction |
|
Single playlist selection (by name or ID) |
|
Single video ID |
|
Multiple playlist names |
|
Playlist names for cleanup |
|
Delete confirmation flag |
|
Cleanup behavior flags (dedup, deleted, privatized) |
|
Output format (full JSON vs IDs only) |
|
Source playlists and seen files for diffing |
|
Input/output files for metadata enrichment |
|
Source and destination for overflow moves |
|
Source and destination for playlist copy |
|
Playlist name for clearing |
|
Source playlists and destination for merge |
|
Playlist name and sort key |
|
Playlists and query for searching |
|
Playlist name and CSV path for export |
|
Old and new playlist names |
|
All-videos and seen playlists |
|
Playlist names for counting |
|
Files to scan for video IDs |
|
File path and playlist for bulk add |
constants.py¶
Static constants:
SCOPES - OAuth2 scopes for YouTube API access
API_SERVICE_NAME / API_VERSION - YouTube API service identifiers (
youtube,v3)MAX_PLAYLIST_ITEMS - YouTube’s 5,000-item playlist limit
NEXT_PAGE_TOKEN / PAGE_TOKEN / ITEMS_TOKEN - API response field names for pagination
DELETED_TITLE / PRIVATE_TITLE - Sentinel strings (
"Deleted video","Private video") used to identify unavailable videos
util.py¶
Core utility layer between the CLI endpoints and the YouTube API:
``PagedRequest`` - A class that wraps paginated YouTube API calls. Handles
nextPageTokeniteration and collects all results across pages viaget_all_items().``get_youtube()`` - Initializes an authenticated YouTube API client using OAuth2 credentials from
pygooglehelper.``create_playlists_request()`` / ``create_playlist_request()`` - Factory functions that create
PagedRequestobjects for listing playlists or playlist items.``get_playlist_ids_from_names()`` - Maps playlist names to their API IDs.
``get_all_items()`` - Fetches all items from a playlist specified by the
ConfigPlaylistconfig.``delete_playlist_item_by_id()`` - Deletes a single item from a playlist.
``get_video_info()`` - Fetches snippet, status, and content details for a video.
``pretty_print()`` - JSON pretty-printer.
youtube.py¶
Thin wrapper around yt-dlp:
``youtube_dl_download_urls()`` - Downloads videos/playlists using yt-dlp with
extract_flatmode and.netrcauthentication.
static.py¶
Auto-generated from tera.templates/src/pytubekit/static.py.tera by rsconstruct. Contains:
VERSION_STR- Current version as a stringDESCRIPTION- Project descriptionAPP_NAME- Application nameLOGGER_NAME- Logger identifier
Key Design Patterns¶
Pagination Abstraction¶
The PagedRequest class in util.py encapsulates YouTube API pagination. It accepts any YouTube API list function and its keyword arguments, then iterates through pages by tracking nextPageToken. This allows all endpoints to fetch complete result sets without duplicating pagination logic.
Configuration via pytconf¶
CLI parameters are defined declaratively as pytconf.Config subclasses. Each endpoint declares which config classes it uses via the configs parameter in @register_endpoint. The pytconf framework handles argument parsing, validation, help generation, and populating the config class attributes.
OAuth2 Authentication¶
Authentication is handled by pygooglehelper, which manages the OAuth2 flow:
Reads
client_secret.jsonfrom~/.config/pytubekit/, falling back to the copy shipped in the packageOpens browser for user consent on first run
Caches credentials for subsequent runs
Deleted/Private Video Detection¶
Videos are identified as deleted or private by checking their title against the sentinel strings "Deleted video" and "Private video". This is how the YouTube API reports unavailable videos in playlist item responses.
Dependencies¶
Runtime¶
Package |
Purpose |
|---|---|
google-api-python-client |
YouTube Data API v3 client |
pygooglehelper |
OAuth2 credential management |
pytconf |
CLI configuration framework |
pylogconf |
Logging configuration |
youtube-dl |
Video/playlist downloading |
browsercookie |
Browser cookie extraction |
Development¶
Package |
Purpose |
|---|---|
pytest |
Test runner |
mypy |
Static type checking |
ruff |
Linter and formatter |
pylint |
Code analysis |
rsconstruct |
Build tool / code generation |
hatchling |
PEP 517 build backend |
Build System¶
The project uses two build mechanisms:
hatchling (via
pyproject.toml) - Standard Python packaging for wheel/sdist builds and PyPI distribution.rsconstruct (via
rsconstruct.toml) - Development workflow: runs tests, linters (ruff, pylint), type checking (mypy), and renders files from tera templates.
Run rsconstruct build to execute every check and render the templates; CI runs the same command.
Code Generation¶
Two files are auto-generated from tera templates in the tera.templates/ directory by rsconstruct:
src/pytubekit/static.pyfromtera.templates/src/pytubekit/static.py.teraREADME.mdfromtera.templates/README.md.tera
These templates pull values from the config/*.lua files to keep metadata consistent across the project.