notnews
A Python library for classifying news articles using URL patterns, trained US and UK models, or optional large language models.
Features
The package supports three classification methods:
- URL pattern analysis
- trained models for US and UK news
- optional Claude or OpenAI classification
The Python API and Click CLI expose the same US and UK classifiers.
Streamlit Demo: https://notnews-notnews-streamlitstreamlit-app-u8j3a6.streamlit.app/
Quick Start
Python API
import pandas as pd
import notnews
# Load your data
df = pd.read_csv("news_articles.csv")
# Method 1: URL Pattern Classification (fastest)
df_url = notnews.classify_by_url(df, url_col="url", region="us")
print(df_url[["url", "hard_news", "soft_news"]].head())
# Method 2: ML Model Prediction (most accurate)
df_ml = notnews.predict_soft_news(df, text_col="text", region="us")
print(df_ml[["text", "prob_soft_news_us"]].head())
# Method 3: LLM Classification (most flexible)
# Requires ANTHROPIC_API_KEY or OPENAI_API_KEY environment variable
df_llm = notnews.classify_with_llm(df, text_col="text", provider="claude")
print(df_llm[["text", "llm_category", "llm_confidence"]].head())
# Detailed Categories (US only)
df_categories = notnews.predict_news_category(df, text_col="text")
print(df_categories[["text", "pred_category", "prob_soft_news"]].head())
Command Line Interface
# Install the package
pip install notnews
# or with uv
uv add notnews
# URL pattern classification
notnews classify-urls articles.csv --region us --output results.csv
# ML model prediction
notnews predict-ml articles.csv --region uk --text-col content
# LLM classification
notnews classify-llm articles.csv --provider claude --api-key your_key
# Run all methods together
notnews classify-all articles.csv --region us
# Get help
notnews --help
notnews classify-urls --help
Installation
Standard Installation
pip install notnews
Fast Installation with UV
uv add notnews
Requirements
- Python: 3.11, 3.12, or 3.13
- Core: pandas, numpy, pyarrow
- Web: requests, beautifulsoup4
- CLI: click 8.0+
- Optional: anthropic, openai (for LLM classification)
LLM Setup
For LLM classification, set your API key:
# For Claude
export ANTHROPIC_API_KEY="your_key_here"
# For OpenAI
export OPENAI_API_KEY="your_key_here"
API Reference
Core Functions
classify_by_url(df, url_col="url", region="us")
Classify articles using URL pattern matching.
Args:
df: DataFrame with articlesurl_col: Column containing URLsregion: "us" or "uk" for region-specific patterns
Returns: DataFrame with hard_news and soft_news columns
predict_soft_news(df, text_col="text", region="us")
Predict soft news probability using trained ML models.
Args:
df: DataFrame with articlestext_col: Column containing article textregion: "us" or "uk" for model selection
Returns: DataFrame with prob_soft_news_{region} column
classify_with_llm(df, text_col="text", provider="claude", **kwargs)
Classify articles using Large Language Models.
Args:
df: DataFrame with articlestext_col: Column containing article textprovider: "claude" or "openai"categories: Optional custom categories dictapi_key: Optional API key (uses env var if not provided)
Returns: DataFrame with llm_category, llm_confidence, llm_reasoning columns
Advanced Usage
# Custom LLM categories
custom_categories = {
"breaking": {"description": "Breaking news and urgent updates"},
"analysis": {"description": "In-depth analysis and commentary"},
"lifestyle": {"description": "Lifestyle and entertainment content"}
}
df_custom = notnews.classify_with_llm(
df,
provider="claude",
categories=custom_categories
)
# Fetch content from URLs
content = notnews.fetch_web_content("https://example.com")
Model Information
URL Patterns
- US: Politics, economics, international affairs vs. sports, entertainment, lifestyle
- UK: Includes UK-specific patterns like "uk-news", "scottish-news"
ML Models
- US: NYT-based models trained on headline and content text
- UK: URL-based model trained on UK news outlets
- Runtime inference uses version-independent, typed Parquet exports of the original calibrated linear models.
Data Sources
- US Model: Based on NYT data
- UK Model: Based on UK news analysis
The fitted classifiers and vectorizers are published at
gojiberries/notnews. Notnews
downloads them from an immutable Hugging Face commit on first use. Set
NOTNEWS_MODEL_DIR to use an explicitly managed local copy.
Applications
Research using notnews:
Documentation
Full documentation: notnews.github.io/notnews
Contributing
We welcome contributions! Please see our Contributor Code of Conduct.
Development Setup
git clone https://github.com/notnews/notnews.git
cd notnews
uv sync --all-groups --all-extras
uv run pytest
Authors
- Suriyan Laohaprapanon
- Gaurav Sood
License
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 notnews-0.4.0.tar.gz.
File metadata
- Download URL: notnews-0.4.0.tar.gz
- Upload date:
- Size: 20.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6b9cfa57e63964a4393ec3a7ed97b41a2678190638d8dfdc27b564071e51e57d
|
|
| MD5 |
c378fabc740272c8904a563257356217
|
|
| BLAKE2b-256 |
9beebf99bb8dd9c019cfe28f56ef32311ed4d556ee34db7ee0e54169fe5b0746
|
Provenance
The following attestation bundles were made for notnews-0.4.0.tar.gz:
Publisher:
release.yml on notnews/notnews
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
notnews-0.4.0.tar.gz -
Subject digest:
6b9cfa57e63964a4393ec3a7ed97b41a2678190638d8dfdc27b564071e51e57d - Sigstore transparency entry: 2495583330
- Sigstore integration time:
-
Permalink:
notnews/notnews@3cda64339a33d0e9d7509113b798898e14de4cb3 -
Branch / Tag:
refs/tags/v0.4.0 - Owner: https://github.com/notnews
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@3cda64339a33d0e9d7509113b798898e14de4cb3 -
Trigger Event:
push
-
Statement type:
File details
Details for the file notnews-0.4.0-py3-none-any.whl.
File metadata
- Download URL: notnews-0.4.0-py3-none-any.whl
- Upload date:
- Size: 20.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e506159aaf5c23c5e1f942c1b94d81d78dc722a1caea2c846082f157b152dc72
|
|
| MD5 |
9f9e3bd44990840f580b58d3908e2036
|
|
| BLAKE2b-256 |
ac0308f54f5198906cf1d38559820eddbc0b56e278f9e6902b588ce9f82cd4f6
|
Provenance
The following attestation bundles were made for notnews-0.4.0-py3-none-any.whl:
Publisher:
release.yml on notnews/notnews
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
notnews-0.4.0-py3-none-any.whl -
Subject digest:
e506159aaf5c23c5e1f942c1b94d81d78dc722a1caea2c846082f157b152dc72 - Sigstore transparency entry: 2495583425
- Sigstore integration time:
-
Permalink:
notnews/notnews@3cda64339a33d0e9d7509113b798898e14de4cb3 -
Branch / Tag:
refs/tags/v0.4.0 - Owner: https://github.com/notnews
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@3cda64339a33d0e9d7509113b798898e14de4cb3 -
Trigger Event:
push
-
Statement type: