An intelligent Tourism Chat Bot Assistant that helps users discover tourism events, attractions, and activities using RAG (Retrieval-Augmented Generation) with Azure OpenAI and Qdrant vector database. Supports English and Arabic with real-time streaming responses.
- FastAPI Backend with streaming chat endpoint (
/chat/stream) using Server-Sent Events (SSE) π - Next.js Frontend with responsive UI, real-time streaming display, and multi-language support π¨
- Azure OpenAI Integration for intelligent conversational responses π€
- Qdrant Vector Database for document similarity search and RAG context retrieval π
- Multi-Language Support English and Arabic with RTL layout support π
- Document Ingestion Pipeline for tourism knowledge base (88 indexed chunks) π
- Session Management with conversation history and multi-tab synchronization πΎ
- Backend: Python, FastAPI, LangChain, Qdrant, Azure OpenAI
- Frontend: Next.js 16.1.1, TypeScript, React 19, Tailwind CSS
- Database: Qdrant (Vector DB)
- LLM: Azure OpenAI (gpt-5-chat)
- Python 3.11+
- Node.js 18+
- Azure OpenAI API key
- Qdrant instance (Docker or local)
- Navigate to backend directory:
cd backend- Create
.envfile with Azure credentials:
AZURE_OPENAI_API_KEY=your-azure-openai-key
AZURE_OPENAI_ENDPOINT=https://your-resource.openai.azure.com/
AZURE_DEPLOYMENT_NAME=gpt-5-chat
QDRANT_URL=http://localhost:6333
QDRANT_API_KEY=
CORS_ORIGINS=*
APP_NAME=Tourism Bot API- Create Python virtual environment (Optional but recommended):
python -m venv .venv
# On Windows:
.venv\Scripts\activate
# On macOS/Linux:
source .venv/bin/activate- Install dependencies:
pip install -r requirements.txt- Start Qdrant (using Docker):
docker-compose up -d- Ingest tourism data into Qdrant:
python scripts/ingest.pyThis will automatically ingest all documents from data/ folder (88 chunks) into the tourism_docs collection.
- Run the backend server:
python -m uvicorn app.main:app --host 0.0.0.0 --port 8000 --reloadBackend will be available at: http://localhost:8000
API Documentation (Swagger UI): http://localhost:8000/docs
Health Check:
curl http://localhost:8000/health- Navigate to frontend directory:
cd frontend- Create
.env.localfile:
NEXT_PUBLIC_API_URL=http://localhost:8000- Install dependencies:
npm install- Run the frontend development server:
npm run devFrontend will be available at: http://localhost:3000
Option 1: Separate Terminals
# Terminal 1 - Backend
cd backend
python -m uvicorn app.main:app --host 0.0.0.0 --port 8000 --reload
# Terminal 2 - Frontend
cd frontend
npm run devOption 2: Concurrent Command (from root directory)
# On macOS/Linux:
(cd backend && python -m uvicorn app.main:app --host 0.0.0.0 --port 8000 --reload) & (cd frontend && npm run dev)
# On Windows PowerShell:
Start-Process -NoNewWindow -FilePath "powershell" -ArgumentList "cd backend; python -m uvicorn app.main:app --host 0.0.0.0 --port 8000 --reload"
Start-Process -NoNewWindow -FilePath "powershell" -ArgumentList "cd frontend; npm run dev"The deploy folder now holds dedicated Compose files so you can start just the pieces you need or the full stack with explicit ordering.
- deploy/qdrant.compose:
docker compose -f deploy/qdrant.compose up -dβ launches Qdrant with persisted storage and a readiness probe. - deploy/backend.compose:
docker compose -f deploy/backend.compose up --buildβ runs the FastAPI backend using your backend/.env file. By default it pointsQDRANT_URLathttp://host.docker.internal:6333; override viaQDRANT_URL=...if Qdrant lives elsewhere. - deploy/frontend.compose:
docker compose -f deploy/frontend.compose up --buildβ starts the Next.js dev server with hot reload. It targetshttp://host.docker.internal:8000unless you overrideNEXT_PUBLIC_API_URLwhen invoking Docker.
Tip: launching Qdrant and backend via their dedicated Compose files keeps the containers isolated yet reachable through the published ports. When you need cross-container networking without host bridges, use the stack file below.
- deploy/stack.compose:
docker compose -f deploy/stack.compose up --buildβ spins up Qdrant β backend (after Qdrant healthcheck passes) β waits 30β―seconds before starting the frontend so the API cache warms up.depends_onplus health checks guarantee Qdrant is online before the backend, and the frontend command adds the required 30-second pause after the backend becomes healthy.
All Compose files mount the local source directories, so code edits on the host reflect instantly inside the containers. Stop everything with docker compose -f deploy/<file>.compose down (add -v if you want to remove the named volumes like qdrant_storage).
TourismChatbot/
βββ backend/
β βββ app/
β β βββ main.py # FastAPI application
β β βββ langchain/
β β β βββ rag.py # RAG system
β β β βββ chain.py # LLM chain
β β β βββ prompts.py # Custom prompts
β β βββ qdrant/
β β β βββ retrieval.py # Vector DB retrieval
β β βββ config/
β β βββ settings.py # Configuration
β βββ data/ # Tourism documents (88 chunks)
β βββ scripts/
β β βββ ingest.py # Data ingestion script
β βββ requirements.txt # Python dependencies
β βββ .env # Environment variables
β βββ docker-compose.yml # Qdrant Docker setup
β
βββ frontend/
β βββ src/
β β βββ app/
β β β βββ page.tsx # Home/Chat page
β β β βββ settings/page.tsx # Settings page
β β β βββ account/page.tsx # Account page
β β β βββ help/page.tsx # Help/FAQ page
β β βββ hooks/
β β β βββ useLanguage.ts # Language management hook
β β βββ lib/
β β β βββ api.ts # API client
β β β βββ translations.ts # i18n strings (EN/AR)
β β βββ globals.css # Tailwind styles
β βββ package.json # Node dependencies
β βββ .env.local # Environment variables
β βββ tsconfig.json # TypeScript config
β
βββ README.md
βββ docker-compose.yml
βββ requirements.txt (root)
POST /chat/stream
Request:
{
"message": "What are the best attractions in Rome?",
"session_id": "unique-session-id",
"language": "en"
}Response: Server-Sent Events (SSE) with tokens and sources
GET /health
Response:
{
"status": "healthy",
"service": "Tourism Chatbot API",
"rag_enabled": true
}- Send tourism-related questions
- View real-time streaming responses
- See sources and citations
- Manage conversation history
- Create and switch between conversations
- Favorite important conversations
- English (Default, LTR)
- Arabic (RTL layout)
- Language preference persists across sessions
- Synchronized across browser tabs
- Change language preference
- Update notification settings
- Configure privacy options
- View and update profile
- Change password
- Delete account
- FAQ with expandable items
- Comprehensive help documentation
cd frontend
npm run build
npm startcd backend
pytestcd frontend
npm run lint
npm run format# Azure OpenAI Configuration
AZURE_OPENAI_API_KEY=your-key-here
AZURE_OPENAI_ENDPOINT=https://your-resource.openai.azure.com/
AZURE_DEPLOYMENT_NAME=gpt-5-chat
# Qdrant Configuration
QDRANT_URL=http://localhost:6333
QDRANT_API_KEY=
# App Configuration
CORS_ORIGINS=*
APP_NAME=Tourism Bot APINEXT_PUBLIC_API_URL=http://localhost:8000Backend won't start:
- Ensure Qdrant is running:
docker-compose up -d - Check Azure OpenAI credentials in
.env - Verify port 8000 is not in use
Frontend won't connect to backend:
- Verify
NEXT_PUBLIC_API_URLis set correctly - Ensure backend is running on port 8000
- Check browser console for CORS errors
Qdrant connection issues:
- Verify Qdrant container is running:
docker ps - Check
QDRANT_URLin backend.env - Ensure port 6333 is accessible
Data not ingesting:
- Ensure documents are in
backend/data/folder - Run ingestion script:
python scripts/ingest.py - Check backend logs for ingestion status
Contributions welcome β open an issue or PR to contribute.