Fetches new YouTube channel playlist content from RSS with automatic fallback to the YouTube API.
Project description
youtube-notify
youtube-notify is a small Python library for fetching recent content from a YouTube channel. It prefers the channel RSS feed first and falls back to the YouTube Data API when RSS does not return content. The library returns typed Content models with channel metadata, timestamps, thumbnails, and descriptions.
Features
- RSS-first content retrieval with YouTube API fallback
- Optional YouTube API key and OAuth helpers
- Pydantic models for downstream validation and serialization
- Async-friendly public APIs
- Mocked integration tests for deterministic CI runs
Installation
This repository uses a src/ layout, so the simplest way to work with it directly is to clone the repo, install the dependencies, and run commands with src/ on PYTHONPATH.
git clone https://github.com/jnstockley/youtube-notify.git
cd youtube-notify
uv sync
export PYTHONPATH=src
If you are using another virtual environment tool, install the dependencies from pyproject.toml and make sure the project root is on your import path in the same way.
Setup
- Clone the repository.
- Create and activate a Python 3.14 environment.
- Install dependencies with
uv syncor your preferred environment manager. - Set
PYTHONPATH=srcwhen running the library directly from the repository. - If you want to use the YouTube API fallback, provide an API key or OAuth credentials in your own application code.
Usage
The main entry point is content_fetcher.get_content(channel_id, youtube=None).
It tries RSS first and only uses the YouTube API client if RSS returns no content.
Basic usage
import asyncio
from content_fetcher import get_content
async def main() -> None:
content = await get_content("UCxxxxxxxxxxxxxxxxxxxxxx")
for item in content:
print(item.title)
asyncio.run(main())
Using a YouTube API key
If you already have a YouTube Data API key, build a client with youtube.auth.api_key.authenticate() and pass it to content_fetcher.get_content().
import asyncio
from content_fetcher import get_content
from youtube.auth.api_key import authenticate
async def main() -> None:
youtube = authenticate("YOUR_YOUTUBE_API_KEY")
content = await get_content("UCxxxxxxxxxxxxxxxxxxxxxx", youtube)
for item in content:
print(item.title)
asyncio.run(main())
Using OAuth credentials
If you need OAuth-based access, the OAuth helper can build credentials and refresh them before creating the client.
from youtube.auth.oauth import authenticate, device_code_flow
creds = device_code_flow("YOUR_CLIENT_ID", "YOUR_CLIENT_SECRET")
youtube = authenticate(creds)
Required Environment Variables
The library itself does not require API credentials from environment variables. The only runtime environment settings used by the code are for logging:
LOG_LEVEL: optional, defaults toINFOLOG_DIR: optional, defaults to../logs
The repository also includes sample.env with example values for a wrapper application:
YOUTUBE_API_KEYGOOGLE_CLIENT_IDGOOGLE_CLIENT_SECRET
Those are not read automatically by the library; they are intended for your own application or deployment scripts.
If your application uses the YouTube API path through youtube.youtube.get_content() or
passes a client into content_fetcher.get_content(), you must provide one of the
following sets of credentials in your application layer:
YOUTUBE_API_KEYGOOGLE_CLIENT_IDandGOOGLE_CLIENT_SECRET
Development
Common local commands:
uv run pytest
uv run pytest -m integration
uv run ruff check
uv run ruff format --check
The integration test suite is mocked and does not make live network calls.
Project Structure
src/content_fetcher.py: top-level RSS-first content fetchersrc/rss/rss.py: RSS feed fetching and parsingsrc/youtube/youtube.py: YouTube API fetching and parsingsrc/youtube/auth/: API key and OAuth helperssrc/models.py: Pydantic models used across the library
Operational Notes
- The library writes logs to
LOG_DIR/app.log. - If you run the code in a container or read-only environment, set
LOG_DIRto a writable path. - The public APIs are asynchronous, so call them from
asynciocode or wrap them withasyncio.run().
Contributing
Contributions are expected to keep the repository green.
Before opening a pull request:
- All tests must pass.
- Code coverage for updated code should be at least 90%.
- The existing linting steps must pass.
- Any public behavior change should include matching tests.
Recommended validation commands:
uv run pytest
uv run pytest --cov src --cov-branch --cov-report=term-missing
uv run ruff check
uv run ruff format --check
License
This project is licensed under the GNU General Public License v3.0. See the LICENSE file for details.
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 youtube_notify-20260604000029.dev0.tar.gz.
File metadata
- Download URL: youtube_notify-20260604000029.dev0.tar.gz
- Upload date:
- Size: 26.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9fcf460bc9ff2d2596415eb46a4a77c929ada7838abd79f17705c14219ff9116
|
|
| MD5 |
50fb6f395fabc080a01e20dcabf0699d
|
|
| BLAKE2b-256 |
1b2f12c30409f735cef24a18ded7bde190aa81bf9668eaaa5d7a29dc0e874d06
|
Provenance
The following attestation bundles were made for youtube_notify-20260604000029.dev0.tar.gz:
Publisher:
ci-cd.yml on jnstockley/youtube-notify
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
youtube_notify-20260604000029.dev0.tar.gz -
Subject digest:
9fcf460bc9ff2d2596415eb46a4a77c929ada7838abd79f17705c14219ff9116 - Sigstore transparency entry: 1713158676
- Sigstore integration time:
-
Permalink:
jnstockley/youtube-notify@d23f5de01108ec4d3fc4e87e7e73a0d0909e636e -
Branch / Tag:
refs/heads/main - Owner: https://github.com/jnstockley
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
ci-cd.yml@d23f5de01108ec4d3fc4e87e7e73a0d0909e636e -
Trigger Event:
push
-
Statement type:
File details
Details for the file youtube_notify-20260604000029.dev0-py3-none-any.whl.
File metadata
- Download URL: youtube_notify-20260604000029.dev0-py3-none-any.whl
- Upload date:
- Size: 26.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
bfdaf7de03f9e8c208aef78803e3a431f251a11e2c8619dff2238848bd210c8b
|
|
| MD5 |
00c2ddba17d1e501fca121212c240135
|
|
| BLAKE2b-256 |
74893851835e0ce3005af34fbbfd2356bcba7bb312e9e4028ef5923874ab83f4
|
Provenance
The following attestation bundles were made for youtube_notify-20260604000029.dev0-py3-none-any.whl:
Publisher:
ci-cd.yml on jnstockley/youtube-notify
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
youtube_notify-20260604000029.dev0-py3-none-any.whl -
Subject digest:
bfdaf7de03f9e8c208aef78803e3a431f251a11e2c8619dff2238848bd210c8b - Sigstore transparency entry: 1713158798
- Sigstore integration time:
-
Permalink:
jnstockley/youtube-notify@d23f5de01108ec4d3fc4e87e7e73a0d0909e636e -
Branch / Tag:
refs/heads/main - Owner: https://github.com/jnstockley
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
ci-cd.yml@d23f5de01108ec4d3fc4e87e7e73a0d0909e636e -
Trigger Event:
push
-
Statement type: