A FastAPI service that generates AI-powered PR coverage reports for any topic using Google News RSS feeds.
- Main API (
main.py) - Single endpoint API server - Report Generator (
report_generator.py) - Core logic for structured PDF reports with links - RSS Agent (
rss_agent.py) - LangChain-powered agent with Google Gemini for RSS processing and AI categorization
- Install the required dependencies:
pip install -r requirements.txtDeploy to Google Cloud Run using Cloud Build:
# Quick deployment
./deploy.sh
# Or manually
gcloud builds submit --config cloudbuild.yamlSee DEPLOYMENT.md for detailed instructions.
- Set up your Google API key (required for RSS agent):
export GOOGLE_API_KEY="your-google-api-key-here"Get your API key from: https://aistudio.google.com/app/apikey Or pass it directly in API requests.
- Start the API server:
python main.pyOr use uvicorn directly:
uvicorn main:app --reload --host 0.0.0.0 --port 8000- The API will be available at
http://localhost:8000
Generates an AI-powered PR coverage report for any subject by automatically fetching and categorizing news articles.
Request Body:
{
"subject": "Harry Styles",
"max_articles": 20,
"filename": "harry-styles-coverage.pdf",
"language": "en-US",
"country": "US"
}Response: PDF file (application/pdf) with categorized news coverage
Example using curl:
# Generate Harry Styles coverage report
curl -X POST "http://localhost:8000/generate-report" \
-H "Content-Type: application/json" \
-d '{"subject": "Harry Styles", "max_articles": 15}' \
--output harry-styles-coverage.pdf
# Generate AI technology coverage report
curl -X POST "http://localhost:8000/generate-report" \
-H "Content-Type: application/json" \
-d '{"subject": "artificial intelligence", "max_articles": 25}' \
--output ai-coverage.pdf
# Generate Apple Inc coverage report for UK market
curl -X POST "http://localhost:8000/generate-report" \
-H "Content-Type: application/json" \
-d '{"subject": "Apple Inc", "language": "en-GB", "country": "GB"}' \
--output apple-uk-coverage.pdfExample using Python requests:
import requests
# Generate Harry Styles coverage report
response = requests.post(
"http://localhost:8000/generate-report",
json={
"subject": "Harry Styles",
"max_articles": 20,
"filename": "harry-styles-coverage.pdf"
}
)
if response.status_code == 200:
with open("harry-styles-coverage.pdf", "wb") as f:
f.write(response.content)
print("Coverage report generated successfully!")
# Generate tech company coverage report
response = requests.post(
"http://localhost:8000/generate-report",
json={
"subject": "Tesla",
"max_articles": 15,
"language": "en-US",
"country": "US"
}
)
if response.status_code == 200:
with open("tesla-coverage.pdf", "wb") as f:
f.write(response.content)
print("Tesla coverage report generated!")
# Generate international coverage report
response = requests.post(
"http://localhost:8000/generate-report",
json={
"subject": "climate change",
"max_articles": 30,
"language": "en-GB",
"country": "GB"
}
)
if response.status_code == 200:
with open("climate-coverage-uk.pdf", "wb") as f:
f.write(response.content)
print("Climate change coverage report generated!")Generate coverage reports:
from rss_agent import create_report_from_topic
# Generate Harry Styles coverage report
json_path, pdf_path = create_report_from_topic(
topic="Harry Styles",
max_articles=15,
subject_override="Harry Styles Coverage Report"
)
print(f"Generated: {pdf_path}")
# Generate technology coverage report
json_path, pdf_path = create_report_from_topic(
topic="artificial intelligence",
max_articles=25,
subject_override="AI Technology Coverage"
)
print(f"Generated: {pdf_path}")Process topics to JSON only:
from rss_agent import ArticleCategorizer
# Process any topic to categorized JSON
agent = ArticleCategorizer()
data = agent.process_topic_to_json(
topic="space exploration",
max_articles=10
)
print(f"Categorized into {len(data['sections'])} sections")Generates structured JSON analytics data with detailed metrics for any subject. Returns comprehensive analytics including tier counts, sentiment analysis, and article metadata instead of a PDF report.
Request Body:
{
"clientId": "harry-styles",
"includeInternational": false,
"date": "2025-01-22"
}Response Body:
{
"report": {
"clientId": "harry-styles",
"clientName": "Harry Styles",
"date": "2025-01-22",
"generatedAt": "2025-01-22T15:00:00Z",
"summary": {
"topTierCount": 3,
"midTierCount": 8,
"blogCount": 12,
"totalMentions": 23,
"sentimentBreakdown": {
"positive": 15,
"neutral": 6,
"negative": 2
}
},
"articles": [
{
"id": 1,
"title": "Harry Styles Announces New Tour Dates",
"url": "https://people.com/harry-styles-tour-2025",
"outlet": "People",
"tier": "Mid",
"focusType": "Headline",
"estViews": 100000,
"publishedAt": "2025-01-22T14:30:00Z",
"sentiment": "positive",
"summary": "Pop star announces highly anticipated world tour...",
"includedInReport": true
}
]
}
}Parameters:
clientId: Subject identifier (kebab-case format like "harry-styles")includeInternational: Boolean flag for international vs US-only coveragedate: Report date in YYYY-MM-DD format
Analytics Features:
- Tier Classification: Automatically categorizes outlets as Top/Mid/Blog tier
- Sentiment Analysis: Keyword-based sentiment detection (positive/neutral/negative)
- Focus Analysis: Determines if coverage is "Headline" focus vs "Mention"
- View Estimation: Estimates reach based on outlet tier (500K/100K/25K)
- Auto-calculated Summaries: Tier counts, total mentions, sentiment breakdown
Example using curl:
# Generate analytics for Harry Styles (US-only)
curl -X POST "http://localhost:8000/analytics" \
-H "Content-Type: application/json" \
-d '{"clientId": "harry-styles", "includeInternational": false, "date": "2025-01-22"}' \
| jq '.'
# Generate international analytics for Apple Inc
curl -X POST "http://localhost:8000/analytics" \
-H "Content-Type: application/json" \
-d '{"clientId": "apple-inc", "includeInternational": true, "date": "2025-01-22"}' \
| jq '.'
# Generate analytics for AI technology coverage
curl -X POST "http://localhost:8000/analytics" \
-H "Content-Type: application/json" \
-d '{"clientId": "artificial-intelligence", "includeInternational": false, "date": "2025-01-22"}' \
| jq '.report.summary'Example using Python requests:
import requests
import json
# Generate analytics for Tesla
response = requests.post(
"http://localhost:8000/analytics",
json={
"clientId": "tesla",
"includeInternational": false,
"date": "2025-01-22"
}
)
if response.status_code == 200:
analytics = response.json()
summary = analytics["report"]["summary"]
print(f"Total mentions: {summary['totalMentions']}")
print(f"Top tier: {summary['topTierCount']}")
print(f"Mid tier: {summary['midTierCount']}")
print(f"Blog tier: {summary['blogCount']}")
print(f"Sentiment: {summary['sentimentBreakdown']}")
# Process individual articles
for article in analytics["report"]["articles"][:5]:
print(f"- {article['title']} ({article['outlet']}, {article['tier']} tier)")
# Generate international coverage analytics
response = requests.post(
"http://localhost:8000/analytics",
json={
"clientId": "climate-change",
"includeInternational": true,
"date": "2025-01-22"
}
)
if response.status_code == 200:
data = response.json()
print(f"International coverage: {data['report']['summary']['totalMentions']} articles")Returns API information and supported topics.
Health check endpoint showing service status.
When the server is running, you can access the interactive API documentation at:
- Swagger UI:
http://localhost:8000/docs - ReDoc:
http://localhost:8000/redoc
- Automatic topic processing - Enter any subject and get comprehensive coverage
- Google News integration - Fetches latest articles from Google News RSS
- Smart categorization using Google Gemini 2.0 Flash AI
- Media tier classification - Distinguishes top-tier, mid-tier, and low-tier sources
- Coverage differentiation - Identifies headline coverage vs mentions
- Multi-language support - Generate reports in different languages/regions
- Structured sections with clear headings and subheadings
- Clickable links to original articles (blue links in PDF)
- Source attribution with media tier and coverage type metadata
- Professional formatting with proper spacing and typography
- Custom filenames and automatic timestamping
- Single endpoint design - One simple route for all coverage reports
- Dynamic RSS URL generation - Builds Google News RSS URLs for any topic
- AI-powered processing using LangChain + Google Gemini 2.0 Flash
- Modular components - Separate RSS agent and report generator modules
- Cloud-ready with Docker and Google Cloud Run deployment
- Environment variable configuration for API keys and settings
- FastAPI framework with automatic validation and documentation
- Comprehensive error handling with detailed error messages
- Automatic cleanup of temporary files
- Health check endpoint for monitoring
- Interactive API documentation at
/docs - Multi-region support with language and country parameters
-
Set your Google API key:
export GOOGLE_API_KEY="your-key-here"
-
Run the example:
python example_rss_usage.py
-
Or use the API:
curl -X POST "http://localhost:8000/generate-report" \ -H "Content-Type: application/json" \ -d '{"subject": "Harry Styles", "max_articles": 15}' \ --output harry-styles-coverage.pdf
The service can generate coverage reports for any topic that appears in Google News:
People & Celebrities:
Harry Styles,Taylor Swift,Elon Musk,Joe Biden
Companies & Brands:
Apple,Tesla,Microsoft,Netflix,Google
Technology:
artificial intelligence,blockchain,quantum computing,ChatGPT
Events & Trends:
COP28,Olympics 2024,World Cup,climate change
Geographic Topics:
London news,California wildfires,Japan earthquake
Industries:
renewable energy,electric vehicles,space exploration