Files
Munich-news/docs/ADMIN_API.md
2025-11-11 16:58:03 +01:00

4.8 KiB

Admin API Reference

Admin endpoints for testing and manual operations.

Overview

The admin API allows you to trigger manual operations like crawling news and sending test emails directly through HTTP requests.

How it works: The backend container has access to the Docker socket, allowing it to execute commands in other containers via docker exec.


API Endpoints

Trigger Crawler

Manually trigger the news crawler to fetch new articles.

POST /api/admin/trigger-crawl

Request Body (optional):

{
  "max_articles": 10
}

Parameters:

  • max_articles (integer, optional): Number of articles to crawl per feed (1-100, default: 10)

Response:

{
  "success": true,
  "message": "Crawler executed successfully",
  "max_articles": 10,
  "output": "... crawler output (last 1000 chars) ...",
  "errors": ""
}

Example:

# Crawl 5 articles per feed
curl -X POST http://localhost:5001/api/admin/trigger-crawl \
  -H "Content-Type: application/json" \
  -d '{"max_articles": 5}'

# Use default (10 articles)
curl -X POST http://localhost:5001/api/admin/trigger-crawl

Send Test Email

Send a test newsletter to a specific email address.

POST /api/admin/send-test-email

Request Body:

{
  "email": "test@example.com",
  "max_articles": 10
}

Parameters:

  • email (string, required): Email address to send test newsletter to
  • max_articles (integer, optional): Number of articles to include (1-50, default: 10)

Response:

{
  "success": true,
  "message": "Test email sent to test@example.com",
  "email": "test@example.com",
  "output": "... sender output ...",
  "errors": ""
}

Example:

# Send test email
curl -X POST http://localhost:5001/api/admin/send-test-email \
  -H "Content-Type: application/json" \
  -d '{"email": "your-email@example.com"}'

# Send with custom article count
curl -X POST http://localhost:5001/api/admin/send-test-email \
  -H "Content-Type: application/json" \
  -d '{"email": "your-email@example.com", "max_articles": 5}'

Get System Statistics

Get overview statistics of the system.

GET /api/admin/stats

Response:

{
  "articles": {
    "total": 150,
    "with_summary": 120,
    "today": 15
  },
  "subscribers": {
    "total": 50,
    "active": 45
  },
  "rss_feeds": {
    "total": 4,
    "active": 4
  },
  "tracking": {
    "total_sends": 200,
    "total_opens": 150,
    "total_clicks": 75
  }
}

Example:

curl http://localhost:5001/api/admin/stats

Workflow Examples

Test Complete System

# 1. Check current stats
curl http://localhost:5001/api/admin/stats

# 2. Trigger crawler to fetch new articles
curl -X POST http://localhost:5001/api/admin/trigger-crawl \
  -H "Content-Type: application/json" \
  -d '{"max_articles": 5}'

# 3. Wait a moment for crawler to finish, then check stats again
sleep 30
curl http://localhost:5001/api/admin/stats

# 4. Send test email
curl -X POST http://localhost:5001/api/admin/send-test-email \
  -H "Content-Type: application/json" \
  -d '{"email": "your-email@example.com"}'

Quick Test Newsletter

# Send test email with latest articles
curl -X POST http://localhost:5001/api/admin/send-test-email \
  -H "Content-Type: application/json" \
  -d '{"email": "your-email@example.com", "max_articles": 3}'

Fetch Fresh Content

# Crawl more articles from each feed
curl -X POST http://localhost:5001/api/admin/trigger-crawl \
  -H "Content-Type: application/json" \
  -d '{"max_articles": 20}'

Error Responses

All endpoints return standard error responses:

{
  "success": false,
  "error": "Error message here"
}

Common HTTP Status Codes:

  • 200 - Success
  • 400 - Bad request (invalid parameters)
  • 500 - Server error

Security Notes

⚠️ Important: These are admin endpoints and should be protected in production!

Recommendations:

  1. Add authentication/authorization
  2. Rate limiting
  3. IP whitelisting
  4. API key requirement
  5. Audit logging

Example protection (add to routes):

from functools import wraps
from flask import request

def require_api_key(f):
    @wraps(f)
    def decorated_function(*args, **kwargs):
        api_key = request.headers.get('X-API-Key')
        if api_key != os.getenv('ADMIN_API_KEY'):
            return jsonify({'error': 'Unauthorized'}), 401
        return f(*args, **kwargs)
    return decorated_function

@admin_bp.route('/api/admin/trigger-crawl', methods=['POST'])
@require_api_key
def trigger_crawl():
    # ... endpoint code