A RAG-powered chatbot backend for querying Nepali financial news and NEPSE stock data. Built with FastAPI, PostgreSQL (pgvector), and Google Gemini, it serves an HTMX-driven UI with real-time chat, company insights, trending topics, and a watchlist.
This is the backend application. The data pipeline that scrapes, enriches, and populates the database lives in a separate repo: 👉 news-data-pipeline
news-data-pipeline (separate repo)
│
▼
PostgreSQL (pgvector) ◄──── This backend reads from here
│
▼
FastAPI Backend (this repo)
│
▼
Jinja2 + HTMX Frontend
The pipeline scrapes 14 Nepali news sources hourly, generates Gemini embeddings, and writes enriched articles into PostgreSQL. This backend queries that data to power the chatbot and insights features.
- RAG Chat — Ask questions about Nepali financial news; answers are grounded in real articles via cosine similarity search over pgvector embeddings
- Trending Topics — Auto-generated hourly from high-signal articles
- Company Insights — Per-symbol NEPSE page with price chart, key stats, technical indicators, and AI-generated buy/hold/sell recommendations
- Watchlist — Track NEPSE companies and receive AI-generated impact summaries based on latest news
- Multi-tenant Org System — Organizations with admin/user roles, invite-code-based onboarding, and feature-level access control
- Admin Dashboard — Manage team members, assign features, and change roles
- Scheduled Scraper Trigger — Fires the pipeline's scraper queue via RabbitMQ every hour (skips midnight–5 AM Kathmandu time)
| Layer | Technology |
|---|---|
| Web framework | FastAPI |
| Frontend | Jinja2 templates + HTMX |
| Database | PostgreSQL with pgvector |
| AI / Embeddings | Google Gemini |
| Object storage | MinIO / Wasabi (S3-compatible) |
| Message queue | RabbitMQ |
| Package manager | Poetry |
| Runtime | Python 3.11 |
- Python 3.11+
- Poetry
- PostgreSQL with the
pgvectorextension enabled - A running RabbitMQ instance
- A MinIO or Wasabi bucket (used by the pipeline; credentials needed here for scraper triggers)
- Google Gemini API key
The database schema is created automatically on first startup via DbService.
1. Clone the repo
git clone https://github.com/Srmaraghu/news-backend.git
cd news-backend2. Install dependencies
poetry install3. Configure environment variables
cp .env.example .env
# Fill in all values in .env4. Run the app
poetry run uvicorn src.api:app --host 0.0.0.0 --port 8000 --reloadThe app will be available at http://localhost:8000.
docker build -t news-backend .
docker run --env-file .env -p 8000:8000 news-backendMake sure your
.envfile is populated before running the container.
Copy .env.example to .env and fill in your values.
| Variable | Description |
|---|---|
SECRET_KEY |
Session signing key — use a long random string |
DB_HOST, DB_PORT, DB_NAME, DB_USER, DB_PASSWORD |
PostgreSQL connection |
GEMINI_API_KEY |
Google Gemini API key |
GEMINI_EMBED_MODEL |
Embedding model name (e.g. models/text-embedding-004) |
GEMINI_GENERATE_MODEL |
Generation model name (e.g. gemini-1.5-flash) |
WASABI_ENDPOINT, WASABI_ACCESS_KEY, WASABI_SECRET_KEY |
Object storage credentials |
RABBITMQ_HOST, RABBITMQ_PORT, RABBITMQ_VHOST, RABBITMQ_USER, RABBITMQ_PASSWORD |
RabbitMQ connection |
src/
├── api.py # App entry point, router registration
├── config.py # Middleware and template configuration
├── models.py # Pydantic models
├── endpoints/
│ ├── auth.py # Login, register, invite, team management
│ ├── conversation.py # Chat / RAG query endpoint
│ ├── conversation_group.py
│ ├── company_insights.py # NEPSE company data + AI recommendations
│ ├── trending_topics.py
│ ├── watchlist.py
│ └── scraper_trigger.py # Manual scraper trigger
├── services/
│ ├── embeddings/
│ │ ├── db_service.py # All database operations
│ │ ├── gemini_client.py # Gemini API wrapper
│ │ ├── gemini_response.py # RAG answer generation
│ │ └── minio_service.py # Object storage client
│ ├── prompts/ # YAML prompt templates
│ ├── schedule_service.py # Hourly scraper scheduler
│ ├── trigger_scraper_service.py
│ ├── rabbitmq_service.py
│ ├── online_khabar_scraper.py
│ └── markdown_service.py
├── middlewares/
│ ├── helpers.py # Auth guards (requires_role, requires_feature)
│ └── exception_handlers.py
├── templates/ # Jinja2 HTML templates
└── static/ # CSS
| Role | Capabilities |
|---|---|
admin |
Full access — manage team, assign features, generate invites |
user |
Access to features assigned by their org admin |
Features (chat_box, company_insights, trending_topics) are toggled per-user by admins from the dashboard.
- Data Pipeline → Srmaraghu/news-data-pipeline — Scrapes 14 Nepali news sources, generates embeddings, and populates the PostgreSQL database that this backend reads from.
- Building a Context-Aware Financial News Chatbot — Deep dive into how the RAG pipeline works: time-aware query parsing, cosine similarity retrieval over 768-dim Gemini embeddings, prompt assembly with conversation history, and the Gemini financial analyst persona.
- SSL certificate verification is disabled in
rabbitmq_service.pyfor development. Enable proper cert validation before deploying to production. - The scraper scheduler skips runs between midnight and 5 AM Kathmandu time (
Asia/Kathmandu).