Metadata-Version: 2.4
Name: wpnews
Version: 1.6.1
Summary: Python SDK for wpnews.pro — real-time AI & tech news API
Project-URL: Homepage, https://wpnews.pro
Project-URL: Documentation, https://wpnews.pro/api-docs
Project-URL: Repository, https://github.com/wpnews/wpnews-python
Author-email: "wpnews.pro" <hello@wpnews.pro>
License: MIT
Keywords: agents,ai-news,api-client,llm,news
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.10
Description-Content-Type: text/markdown

# wpnews — Python SDK

Zero-dependency Python client for [wpnews.pro](https://wpnews.pro) — real-time AI & tech news API with 72 OpenAI-compatible tools.

## What's new in v1.5.0

- `AsyncWPNews` — async client with zero extra dependencies (uses `run_in_executor`)
- `client.get_related_articles(slug, limit=4)` — find articles by topic+entity overlap (tool #72)
- `client.get_articles_batch(slugs, lang)` — fetch multiple articles in one round-trip (tool #71)
- Updated to 72 OpenAI tool schemas

## CLI (installed with pip)

```bash
# Try without an API key
wpnews demo

# Breaking news radar (articles scored by freshness × quality)
wpnews hot --hours=6

# Real-time publication velocity
wpnews velocity

# Latest AI news
wpnews news --limit=5 --lang=en

# Search
wpnews search "Claude Anthropic"

# Full quota info
WPNEWS_API_KEY=wn_your_key wpnews me
```

## Install

```bash
pip install wpnews
```

## Quick start

```python
from wpnews import WPNews

client = WPNews(api_key="wn_your_key")  # free key at wpnews.pro/api-keys

# Latest AI news
news = client.get_news(topic="artificial-intelligence", limit=5)
for article in news:
    print(article["title"], article["published_at"])

# Full-text search
results = client.search("Claude Anthropic", limit=10)

# Trending entities
entities = client.get_trending_entities(days=7, limit=10)

# 55 OpenAI-compatible tool schemas (drop into GPT-4 / Claude)
tools = client.get_openai_tools()
```

## Use with OpenAI / GPT-4

```python
import openai
from wpnews import WPNews

client = WPNews(api_key="wn_your_key")
tools = client.get_openai_tools()

response = openai.chat.completions.create(
    model="gpt-4o",
    messages=[{"role": "user", "content": "What's happening in AI today?"}],
    tools=tools,
)
```

## Use with Claude (Anthropic)

```python
import anthropic
from wpnews import WPNews

client = WPNews(api_key="wn_your_key")
tools = client.get_openai_tools()

# Convert OpenAI format to Anthropic format
claude_tools = [
    {"name": t["function"]["name"],
     "description": t["function"]["description"],
     "input_schema": t["function"]["parameters"]}
    for t in tools
]
```

## API Reference

### Articles

| Method | Description |
|--------|-------------|
| `get_news(topic, lang, limit, offset)` | Latest articles |
| `search(q, topic, lang, limit, offset, date_from, date_to, highlight)` | Full-text search with filters |
| `get_article(slug, lang)` | Single article detail |
| `get_most_viewed(days, limit)` | Most viewed articles |
| `get_bulletin(fmt, items)` | News bulletin (text or JSON) |
| `get_daily_brief(lang)` | Daily brief summary |
| `get_weekly_digest(lang)` | Weekly digest with sections |
| `get_agent_digest(lang)` | AI agent digest |
| `get_articles_batch(slugs, lang)` | Fetch multiple articles by slug in one call |
| `get_related_articles(slug, lang, limit)` | Articles related by topic+entity overlap |

### Topics

| Method | Description |
|--------|-------------|
| `get_topics(lang)` | All topic slugs with article counts |
| `get_topic_momentum(lang, days)` | Topics ranked by week-over-week growth |
| `get_emerging_topics(lang, window, baseline, min_recent)` | Topics gaining traction |
| `compare_topics(slugs, lang, days)` | Side-by-side topic comparison |
| `get_topics_heatmap(lang, days)` | Daily article-count matrix per topic |
| `get_topic_narrative(slug, lang, days)` | Story arc: phases, turning points, trajectory |

### Entities

| Method | Description |
|--------|-------------|
| `get_trending_entities(days, limit, lang)` | Most-mentioned entities |
| `search_entities(q, lang, limit)` | Search entities by name |
| `get_entity_news(entity, lang, limit)` | Articles mentioning an entity |
| `get_entity_sentiment(entity, lang, days)` | Sentiment breakdown for entity |
| `get_entity_cooccurrences(entity, limit)` | Co-occurring entities |
| `get_entity_news_flash(entity, hours, limit)` | Breaking news for entity (last 1-12h) |

### Analytics

| Method | Description |
|--------|-------------|
| `get_sentiment_trends(days, lang)` | Sentiment over time |
| `get_coverage_gaps(lang)` | Under-covered topic detection |
| `get_sources_quality(limit)` | Source reliability scores |

### Breaking News & Agent Tools

| Method | Description |
|--------|-------------|
| `get_hot_articles(lang, hours, limit)` | Breaking news ranked by freshness × quality |
| `get_morning_briefing(lang, hours)` | Velocity status + hot articles + trending entities |
| `get_openai_tools()` | 72 OpenAI function-call schemas |
| `get_mcp_tools()` | 73 MCP tool definitions |
| `get_agent_quickstart(lang)` | Quickstart guide for agents |

## Async support

```python
import asyncio
from wpnews import AsyncWPNews

async def main():
    async with AsyncWPNews(api_key="wn_your_key") as client:
        news = await client.get_news(limit=5)
        related = await client.get_related_articles(news[0]["slug"])
        batch = await client.get_articles_batch([a["slug"] for a in news])
        print(related)

asyncio.run(main())
```

`AsyncWPNews` wraps the sync client transparently — every method becomes a coroutine via `asyncio.get_event_loop().run_in_executor()`. No extra dependencies required.

## Error handling

```python
from wpnews import WPNews, WPNewsError, RateLimitError, AuthError

client = WPNews(api_key="wn_your_key")

try:
    news = client.get_news()
except RateLimitError:
    print("Rate limit hit — upgrade to Pro at wpnews.pro/pricing")
except AuthError:
    print("Invalid API key")
except WPNewsError as e:
    print(f"API error {e.status_code}: {e}")
```

## Topic narrative example

```python
client = WPNews(api_key="wn_your_key")

arc = client.get_topic_narrative("artificial-intelligence", days=30)
print(f"Trajectory: {arc['narrative_trajectory']}")   # accelerating / decelerating / steady
print(f"Phases: {len(arc['phases'])} weekly buckets")
for phase in arc["phases"][:2]:
    print(f"  {phase['period_start']} — {phase['article_count']} articles, {phase['dominant_sentiment']}")
```

## Links

- [API docs](https://wpnews.pro/api)
- [72 OpenAI tool schemas](https://wpnews.pro/tools)
- [MCP server (Claude Desktop)](https://wpnews.pro/for-agents)
- [Get free API key](https://wpnews.pro/api-keys)
- [Pricing](https://wpnews.pro/pricing)
- [Usage dashboard](https://wpnews.pro/dashboard)

## License

MIT
