""" Personalization API routes for Munich News Daily. Provides endpoints to test and preview personalized content. """ from flask import Blueprint, request, jsonify from datetime import datetime, timedelta from database import articles_collection from services.personalization_service import ( rank_articles_for_user, select_personalized_articles, get_personalization_explanation, get_personalization_stats ) personalization_bp = Blueprint('personalization', __name__) @personalization_bp.route('/api/personalize/preview/', methods=['GET']) def preview_personalized_newsletter(email): """ Preview personalized newsletter for a user. Query parameters: max_articles: Maximum articles to return (default: 10) hours_lookback: Hours of articles to consider (default: 24) Returns: JSON with personalized article selection and statistics """ try: max_articles = request.args.get('max_articles', 10, type=int) hours_lookback = request.args.get('hours_lookback', 24, type=int) # Get recent articles cutoff_date = datetime.utcnow() - timedelta(hours=hours_lookback) articles = list(articles_collection.find({ 'created_at': {'$gte': cutoff_date}, 'summary': {'$exists': True, '$ne': None} }).sort('created_at', -1)) # Select personalized articles personalized = select_personalized_articles( articles, email, max_articles=max_articles ) # Get statistics stats = get_personalization_stats(personalized, email) # Format response articles_response = [] for article in personalized: articles_response.append({ 'title': article.get('title', ''), 'title_en': article.get('title_en'), 'summary': article.get('summary', ''), 'link': article.get('link', ''), 'category': article.get('category', 'general'), 'keywords': article.get('keywords', []), 'personalization_score': article.get('personalization_score', 0.0), 'published_at': article.get('published_at', '') }) return jsonify({ 'success': True, 'email': email, 'articles': articles_response, 'statistics': stats }), 200 except Exception as e: return jsonify({ 'success': False, 'error': str(e) }), 500 @personalization_bp.route('/api/personalize/explain', methods=['POST']) def explain_recommendation(): """ Explain why an article was recommended to a user. Request body: { "email": "user@example.com", "article_id": "article-id-here" } Returns: JSON with explanation of recommendation """ try: data = request.get_json() if not data or 'email' not in data or 'article_id' not in data: return jsonify({ 'success': False, 'error': 'email and article_id required' }), 400 email = data['email'] article_id = data['article_id'] # Get article from bson import ObjectId article = articles_collection.find_one({'_id': ObjectId(article_id)}) if not article: return jsonify({ 'success': False, 'error': 'Article not found' }), 404 # Get user interests from services.interest_profiling_service import get_user_interests user_interests = get_user_interests(email) # Generate explanation explanation = get_personalization_explanation(article, user_interests) return jsonify({ 'success': True, 'email': email, 'article_title': article.get('title', ''), 'explanation': explanation }), 200 except Exception as e: return jsonify({ 'success': False, 'error': str(e) }), 500