YouTube search CLI and UI that ranks results by relevance using YouTube Data API v3
Project description
RankTube
A Python CLI tool that searches YouTube using the YouTube Data API v3, scores results by relevance, and outputs filtered video URLs. Designed for bulk discovery of videos matching keyword themes with intelligent ranking.
What is this tool?
RankTube takes one or more keyword phrases, queries YouTube, and returns the most relevant video URLs — ranked by how well each video's title, description, tags, and channel name match your search terms. It supports filtering by channel, limiting result count, setting a minimum relevance threshold, and choosing between plain URL, JSON, or detailed output formats.
How it works
Keywords → YouTube Search API → Raw Videos → Relevance Scorer → Formatted Output
↑
Channel Filter (optional, resolved by name or ID)
- Search — Keywords are joined into a single query and sent to
search.list(YouTube Data API v3). Results are paginated until the requested count is reached. - Enrich — Video IDs are passed to
videos.listin batches of 50 to fetch tags not returned by the search endpoint. - Score — Each video is scored against the original keywords using a weighted algorithm (see below).
- Filter — Videos below
--min-scoreare dropped. Results are sorted by score descending. - Output — Results are printed in the chosen format: plain URLs, JSON, or a verbose block per video.
Relevance Scoring
| Signal | Weight | Method |
|---|---|---|
| Title token overlap | 40% | Fraction of keyword tokens found in title |
| Description overlap | 25% | First 500 characters only |
| Tags overlap | 20% | Video tags vs keyword tokens |
| Exact phrase bonus | 10% | Multi-word phrase appears literally in title or description |
| Channel name overlap | 5% | Channel title tokens vs keyword tokens |
Scores range from 0.0 to 1.0. Default minimum threshold is 0.3.
Python Utilities Used
| Library | Purpose |
|---|---|
google-api-python-client |
YouTube Data API v3 client (search.list, videos.list) |
google-auth |
API key authentication |
python-dotenv |
Auto-loads YOUTUBE_API_KEY from .env file |
argparse |
CLI argument parsing (stdlib) |
dataclasses |
ScoredVideo result dataclass (stdlib) |
re |
Token extraction for scoring (stdlib) |
json |
JSON output formatting (stdlib) |
pytest |
Unit and mocked integration tests |
Project Structure
ranktube/
├── pyproject.toml # Package config and entry point
├── requirements.txt
├── .env # Your API key (never commit this)
├── .env.example # Template for .env
├── .gitignore
├── src/ranktube/
│ ├── cli.py # Argument parsing and orchestration
│ ├── api.py # YouTube API client and pagination
│ ├── resolver.py # Channel name → channel ID resolution
│ ├── scorer.py # Relevance scoring engine
│ └── formatter.py # Output formatting (urls / json / verbose)
└── tests/
├── test_scorer.py # 27 unit tests (no API calls)
├── test_resolver.py # 6 mocked tests
└── test_api.py # 12 mocked tests
Features
- Multi-keyword search — Pass multiple phrases; they are combined into one query and scored together
- Relevance scoring — Weighted algorithm ranks results by how well they match your keywords
- Minimum score filter —
--min-scoredrops low-relevance noise from results - Top-N limiting —
--topcaps the number of results returned - Channel filtering — Restrict results to a specific channel by name or ID
- Channel name resolution —
--channel "Khan Academy"automatically resolves to the channel ID - Multiple output formats — Plain URLs, JSON array, or verbose blocks with score and snippet
- API key from
.env— No need to export environment variables manually - Quota-efficient pagination — Stops fetching early once
--topresults are collected - Tag enrichment — Fetches video tags (not returned by search) in batches of 50 for more accurate scoring
Setup
# 1. Clone / navigate to the project
cd ranktube
# 2. Create and activate a virtual environment
python3 -m venv venv && source venv/bin/activate
# 3. Install the package
pip install -e .
# 4. Add your YouTube Data API v3 key to .env
echo 'YOUTUBE_API_KEY=AIza...' > .env
Get a YouTube Data API v3 key from Google Cloud Console:
- Enable YouTube Data API v3 under APIs & Services → Library
- Create an API key under APIs & Services → Credentials
CLI Reference
rt [-h] [--channel NAME | --channel-id ID]
[--top N] [--min-score THRESHOLD]
[--output {urls,json,verbose,details}]
[--api-key KEY]
keywords [keywords ...]
Arguments
| Argument | Type | Default | Description |
|---|---|---|---|
keywords |
positional (1+) | required | One or more keyword phrases to search |
--channel NAME |
optional | — | Channel display name (auto-resolved to ID) |
--channel-id ID |
optional | — | Direct YouTube channel ID (skips resolution) |
--top N |
optional | all | Return at most N results |
--min-score THRESHOLD |
optional | 0.3 |
Minimum relevance score (0.0–1.0) |
--output |
optional | urls |
Output format: urls, details, json, or verbose |
--api-key KEY |
optional | env var | API key (falls back to YOUTUBE_API_KEY) |
--channel and --channel-id are mutually exclusive.
The tool can also be invoked as ranktube (alias for rt).
Example Commands
Basic search — plain URL output
rt "kids brainstorming"
Multiple keywords
rt "kids brainstorming" "kids learning"
Limit to top 10 results
rt "kids brainstorming" --top 10
JSON output
rt "kids brainstorming" --top 10 --output json
Verbose output with score and snippet
rt "kids brainstorming" --top 5 --output verbose
Links with details (title, channel, snippet, matched keywords)
rt "kids brainstorming" --top 5 --output details
Filter by channel name
rt "kids brainstorming" --channel "Khan Academy" --output verbose
Filter by direct channel ID
rt "kids learning" --channel-id UC4a-Gbdigs3jaI_mG1Um6Hg --output json
High-relevance results only
rt "kids motivational" --min-score 0.5
Pass API key directly (overrides .env)
rt "kids brainstorming" --api-key AIza...
Sample Verbose Output
------------------------------------------------------------
#1 Score: 0.7250
Title: Kids Brainstorming Activity | Creative Thinking
Channel: Learning Tree
URL: https://www.youtube.com/watch?v=abc123
Snippet: In this video, kids engage in a fun brainstorming session...
Matched: kids brainstorming
------------------------------------------------------------
#2 Score: 0.5100
Title: Brainstorming Ideas with Children
Channel: Education World
URL: https://www.youtube.com/watch?v=def456
Snippet: A classroom activity where students brainstorm...
Matched: kids brainstorming
------------------------------------------------------------
Running Tests
source venv/bin/activate
pytest tests/ -v
All 43 tests run without a live API key — API calls are fully mocked.
API Quota
| Operation | Cost |
|---|---|
search.list (per page of 50) |
100 units |
videos.list (per batch of 50) |
1 unit |
| Free daily quota | 10,000 units |
Fetching 100 results costs ~102 units. Fetching 500 results costs ~1,010 units — well within the free tier.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file ranktube-0.1.0.tar.gz.
File metadata
- Download URL: ranktube-0.1.0.tar.gz
- Upload date:
- Size: 23.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
98215ee4f5a5dde5e74e8e64e0f34506f9d9b5f8b4ba2ad67bf55a8dfb4d473d
|
|
| MD5 |
3889f7b0e08cf9f1777e3a5d78581f42
|
|
| BLAKE2b-256 |
cd2a7f29288c0b8b6298a702d61998f0f598ca9bf3b9f2a4007d20b0a75f2d73
|
File details
Details for the file ranktube-0.1.0-py3-none-any.whl.
File metadata
- Download URL: ranktube-0.1.0-py3-none-any.whl
- Upload date:
- Size: 20.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c5f410b4ac41c85e94fbc79e78a49c74b2819c8891f6c0ad272c00830254e7b9
|
|
| MD5 |
e1ee2fce5edbbfc4c75982a0ac2aeb54
|
|
| BLAKE2b-256 |
1049b41901bf8d74004d2b9a7d1910e1ae5b408030c6b417bc4ba8fdbbf40cff
|