Update README and backend functionality for improved news application

- Enhanced README.md with a clearer project overview, features, technologies used, and installation instructions.
- Updated vector dimension in config.py from 4096 to 1024 for Cohere embeddings.
- Modified main.py to serve HTML responses for the home page, news fetching, and recommendations.
- Improved error handling and ensured articles have links in the responses.
- Cleaned up news_fetcher.py by removing unnecessary print statements.
- Updated recommender.py to refine insights generation and summary extraction.
- Added Jinja2 for templating and improved the project structure for better organization.
- Included API documentation for better understanding of endpoints and usage.
This commit is contained in:
boladeE
2025-04-15 11:59:39 +01:00
parent e3d00bb4dc
commit bc485b44b8
14 changed files with 957 additions and 108 deletions
+34
View File
@@ -0,0 +1,34 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{% block title %}DS Task AI News{% endblock %}</title>
<link href="https://cdn.jsdelivr.net/npm/tailwindcss@2.2.19/dist/tailwind.min.css" rel="stylesheet">
<style>
.article-card {
transition: transform 0.2s;
}
.article-card:hover {
transform: translateY(-5px);
}
</style>
</head>
<body class="bg-gray-100 min-h-screen">
<nav class="bg-blue-600 text-white p-4">
<div class="container mx-auto">
<h1 class="text-2xl font-bold">DS Task AI News</h1>
</div>
</nav>
<main class="container mx-auto px-4 py-8">
{% block content %}{% endblock %}
</main>
<footer class="bg-gray-800 text-white p-4 mt-8">
<div class="container mx-auto text-center">
<p>&copy; 2024 DS Task AI News. All rights reserved.</p>
</div>
</footer>
</body>
</html>
+54
View File
@@ -0,0 +1,54 @@
{% extends "base.html" %}
{% block title %}Home - DS Task AI News{% endblock %}
{% block content %}
<div class="max-w-4xl mx-auto">
<div class="text-center mb-12">
<h1 class="text-4xl font-bold text-gray-800 mb-4">Welcome to DS Task AI News</h1>
<p class="text-xl text-gray-600">Your AI-powered news retrieval and recommendation system</p>
</div>
<div class="grid grid-cols-1 md:grid-cols-2 gap-8">
<!-- Fetch News Card -->
<div class="bg-white rounded-lg shadow-md overflow-hidden hover:shadow-lg transition-shadow duration-300">
<div class="p-6">
<h2 class="text-2xl font-semibold text-gray-800 mb-4">Latest News</h2>
<p class="text-gray-600 mb-6">View the latest news articles fetched from our RSS feeds.</p>
<a href="/fetch-news" class="inline-block bg-blue-600 text-white px-6 py-3 rounded-md font-medium hover:bg-blue-700 transition-colors duration-300">
View Latest News
</a>
</div>
</div>
<!-- Recommend News Card -->
<div class="bg-white rounded-lg shadow-md overflow-hidden hover:shadow-lg transition-shadow duration-300">
<div class="p-6">
<h2 class="text-2xl font-semibold text-gray-800 mb-4">News Recommendations</h2>
<p class="text-gray-600 mb-6">Get personalized news recommendations based on your interests.</p>
<div class="space-y-4">
<a href="/recommend-news?query=technology" class="block bg-blue-600 text-white px-6 py-3 rounded-md font-medium hover:bg-blue-700 transition-colors duration-300 text-center">
Technology News
</a>
<a href="/recommend-news?query=artificial intelligence" class="block bg-blue-600 text-white px-6 py-3 rounded-md font-medium hover:bg-blue-700 transition-colors duration-300 text-center">
AI News
</a>
</div>
</div>
</div>
</div>
<div class="mt-12 bg-white rounded-lg shadow-md p-6">
<h2 class="text-2xl font-semibold text-gray-800 mb-4">About This Application</h2>
<p class="text-gray-600 mb-4">
This application uses AI to fetch, process, and recommend news articles. It leverages:
</p>
<ul class="list-disc list-inside text-gray-600 space-y-2">
<li>RSS feeds for news collection</li>
<li>Cohere embeddings for semantic understanding</li>
<li>Pinecone vector database for efficient retrieval</li>
<li>AI-powered analysis for personalized recommendations</li>
</ul>
</div>
</div>
{% endblock %}
+42
View File
@@ -0,0 +1,42 @@
{% extends "base.html" %}
{% block title %}Latest News - DS Task AI News{% endblock %}
{% block content %}
<div class="space-y-6">
<h2 class="text-3xl font-bold text-gray-800 mb-6">Latest News Articles</h2>
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
{% for article in articles %}
<article class="article-card bg-white rounded-lg shadow-md overflow-hidden">
<div class="p-6">
<h3 class="text-xl font-semibold text-gray-800 mb-2">
<a href="{{ article.link }}" target="_blank" class="hover:text-blue-600">
{{ article.title }}
</a>
</h3>
<p class="text-gray-600 mb-4">{{ article.content[:200] }}...</p>
<div class="flex justify-between items-center text-sm text-gray-500">
<span>{{ article.source }}</span>
<span>{{ article.published }}</span>
</div>
{% if article.categories %}
<div class="mt-4 flex flex-wrap gap-2">
{% for category in article.categories %}
<span class="px-2 py-1 bg-blue-100 text-blue-800 rounded-full text-xs">
{{ category }}
</span>
{% endfor %}
</div>
{% endif %}
<div class="mt-4">
<a href="{{ article.link }}" target="_blank" class="inline-block bg-blue-600 text-white px-4 py-2 rounded-md font-medium hover:bg-blue-700 transition-colors duration-300">
Read More
</a>
</div>
</div>
</article>
{% endfor %}
</div>
</div>
{% endblock %}
+157
View File
@@ -0,0 +1,157 @@
{% extends "base.html" %}
{% block title %}Recommended News - DS Task AI News{% endblock %}
{% block content %}
<div class="space-y-8">
<div class="bg-white rounded-lg shadow-md p-6 mb-8">
<h2 class="text-2xl font-bold text-gray-800 mb-4">AI Insights</h2>
<div class="prose max-w-none">
{% if insights %}
{% if insights is string %}
{# If insights is a string (JSON or markdown), try to parse it #}
{% set insights_data = insights | from_json %}
{% if insights_data %}
<div class="space-y-6">
{% if insights_data.themes %}
<div>
<h3 class="text-xl font-semibold text-gray-800 mb-2">Themes</h3>
<ul class="list-disc list-inside space-y-1">
{% for theme in insights_data.themes %}
<li class="text-gray-700">{{ theme }}</li>
{% endfor %}
</ul>
</div>
{% endif %}
{% if insights_data.insights %}
<div>
<h3 class="text-xl font-semibold text-gray-800 mb-2">Key Insights</h3>
<ul class="list-disc list-inside space-y-1">
{% for insight in insights_data.insights %}
<li class="text-gray-700">{{ insight }}</li>
{% endfor %}
</ul>
</div>
{% endif %}
{% if insights_data.implications %}
<div>
<h3 class="text-xl font-semibold text-gray-800 mb-2">Implications</h3>
<ul class="list-disc list-inside space-y-1">
{% for implication in insights_data.implications %}
<li class="text-gray-700">{{ implication }}</li>
{% endfor %}
</ul>
</div>
{% endif %}
{% if insights_data.related_areas %}
<div>
<h3 class="text-xl font-semibold text-gray-800 mb-2">Related Areas</h3>
<div class="flex flex-wrap gap-2">
{% for area in insights_data.related_areas %}
<span class="px-3 py-1 bg-blue-100 text-blue-800 rounded-full text-sm">
{{ area }}
</span>
{% endfor %}
</div>
</div>
{% endif %}
</div>
{% else %}
{# If parsing failed, display the raw insights #}
<div class="whitespace-pre-wrap">{{ insights }}</div>
{% endif %}
{% else %}
{# If insights is already a dict/object #}
<div class="space-y-6">
{% if insights.themes %}
<div>
<h3 class="text-xl font-semibold text-gray-800 mb-2">Themes</h3>
<ul class="list-disc list-inside space-y-1">
{% for theme in insights.themes %}
<li class="text-gray-700">{{ theme }}</li>
{% endfor %}
</ul>
</div>
{% endif %}
{% if insights.insights %}
<div>
<h3 class="text-xl font-semibold text-gray-800 mb-2">Key Insights</h3>
<ul class="list-disc list-inside space-y-1">
{% for insight in insights.insights %}
<li class="text-gray-700">{{ insight }}</li>
{% endfor %}
</ul>
</div>
{% endif %}
{% if insights.implications %}
<div>
<h3 class="text-xl font-semibold text-gray-800 mb-2">Implications</h3>
<ul class="list-disc list-inside space-y-1">
{% for implication in insights.implications %}
<li class="text-gray-700">{{ implication }}</li>
{% endfor %}
</ul>
</div>
{% endif %}
{% if insights.related_areas %}
<div>
<h3 class="text-xl font-semibold text-gray-800 mb-2">Related Areas</h3>
<div class="flex flex-wrap gap-2">
{% for area in insights.related_areas %}
<span class="px-3 py-1 bg-blue-100 text-blue-800 rounded-full text-sm">
{{ area }}
</span>
{% endfor %}
</div>
</div>
{% endif %}
</div>
{% endif %}
{% else %}
<p class="text-gray-600">No insights available for these articles.</p>
{% endif %}
</div>
</div>
<h2 class="text-3xl font-bold text-gray-800 mb-6">Recommended Articles</h2>
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
{% for article in articles %}
<article class="article-card bg-white rounded-lg shadow-md overflow-hidden">
<div class="p-6">
<h3 class="text-xl font-semibold text-gray-800 mb-2">
<a href="{{ article.link }}" target="_blank" class="hover:text-blue-600">
{{ article.title }}
</a>
</h3>
<p class="text-gray-600 mb-4">{{ article.content[:200] }}...</p>
<div class="flex justify-between items-center text-sm text-gray-500">
<span>{{ article.source }}</span>
<span>{{ article.published }}</span>
</div>
{% if article.categories %}
<div class="mt-4 flex flex-wrap gap-2">
{% for category in article.categories %}
<span class="px-2 py-1 bg-blue-100 text-blue-800 rounded-full text-xs">
{{ category }}
</span>
{% endfor %}
</div>
{% endif %}
<div class="mt-4">
<a href="{{ article.link }}" target="_blank" class="inline-block bg-blue-600 text-white px-4 py-2 rounded-md font-medium hover:bg-blue-700 transition-colors duration-300">
Read More
</a>
</div>
</div>
</article>
{% endfor %}
</div>
</div>
{% endblock %}