A production-ready RAG (Retrieval-Augmented Generation) API built with FastAPI, Weaviate, MinIO, and Google Gemini.
- 🔐 JWT Authentication - Secure API access with username/password authentication
- 📄 Document Processing - Upload PDF, DOCX, and TXT files for indexing
- 🔍 Vector Search - Semantic search using Weaviate vector database
- 🤖 AI-Powered Q&A - Query documents using Google Gemini LLM
- 🗄️ Object Storage - MinIO for document storage
- 🔒 Secrets Management - HashiCorp Vault integration (with env fallback)
- 🐳 Docker Compose - Complete local development environment
┌─────────────┐
│ FastAPI │
│ (Python) │
└──────┬──────┘
│
├──► SQLite (Users/Auth)
├──► Weaviate (Vector DB)
├──► MinIO (Object Storage)
├──► Vault (Secrets)
└──► Gemini API (Embeddings + LLM)
📖 For detailed step-by-step setup instructions, see SETUP_GUIDE.md
- Docker and Docker Compose
- A Google AI Studio API key (Get one here)
# 1. Clone repository
git clone <repository-url>
cd context-forge
# 2. Create .env file
cp .env.example .env
# 3. Edit .env and set REQUIRED variables:
# - GEMINI_API_KEY=your-api-key-here
# - JWT_SECRET=$(openssl rand -hex 32)
# 4. Start services
docker compose up -d --build
# 5. Wait for services to be ready, then:
# - Get Vault token: docker compose logs vault | grep "Root Token"
# - Update .env with VAULT_TOKEN and VAULT_UNSEAL_KEY
# - Restart FastAPI: docker compose restart fastapi
# - Initialize Vault: make init-vault
# - Create user: make seed-user USERNAME=dev PASSWORD=devpass- API Docs: http://localhost:8000/docs
- Health Check: http://localhost:8000/health
For complete setup instructions, troubleshooting, and detailed explanations, see SETUP_GUIDE.md
# Login
curl -X POST "http://localhost:8000/auth/login" \
-H "Content-Type: application/json" \
-d '{"username": "dev", "password": "devpass"}'
# Response:
# {
# "access_token": "eyJ...",
# "token_type": "bearer"
# }# Set your token
TOKEN="your-access-token-here"
# Create a context and upload a document
curl -X POST "http://localhost:8000/contexts?context_key=my-docs" \
-H "Authorization: Bearer $TOKEN" \
-F "file=@/path/to/document.pdf"
# Response:
# {
# "context_key": "my-docs",
# "file_id": "uuid-here",
# "filename": "document.pdf",
# "status": "accepted",
# "message": "Context created and file uploaded successfully. Processing in background."
# }curl -X GET "http://localhost:8000/contexts/my-docs/documents/{file_id}/status" \
-H "Authorization: Bearer $TOKEN"curl -X POST "http://localhost:8000/query" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"query": "What is the main topic of the document?",
"context_key": "my-docs",
"top_k": 5
}'
# Response:
# {
# "answer": "...",
# "sources": [
# {
# "chunk_id": "...",
# "filename": "document.pdf",
# "score": 0.95,
# "text": "...",
# "metadata": {...},
# "context_key": "my-docs"
# }
# ],
# "query_metadata": {...}
# }# 1. Login
TOKEN=$(curl -s -X POST "http://localhost:8000/auth/login" \
-H "Content-Type: application/json" \
-d '{"username": "dev", "password": "devpass"}' \
| jq -r '.access_token')
# 2. Create context and upload document
RESPONSE=$(curl -s -X POST "http://localhost:8000/contexts?context_key=test-docs" \
-H "Authorization: Bearer $TOKEN" \
-F "file=@document.pdf")
FILE_ID=$(echo $RESPONSE | jq -r '.file_id')
CONTEXT_KEY=$(echo $RESPONSE | jq -r '.context_key')
# 3. Wait for processing (check status)
sleep 10
curl -X GET "http://localhost:8000/contexts/$CONTEXT_KEY/documents/$FILE_ID/status" \
-H "Authorization: Bearer $TOKEN"
# 4. Query documents
curl -X POST "http://localhost:8000/query" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d "{\"query\": \"Summarize the document\", \"context_key\": \"$CONTEXT_KEY\", \"top_k\": 3}"Key environment variables (see .env.example for full list):
GEMINI_API_KEY- Your Google AI Studio API key (REQUIRED)JWT_SECRET- JWT signing secret (REQUIRED - generate withopenssl rand -hex 32)EMBEDDING_MODEL- Embedding model (default:text-embedding-004)LLM_MODEL- LLM model (default:gemini-1.5-flash)CHUNK_SIZE- Document chunk size (default:2000)CHUNK_OVERLAP- Chunk overlap (default:200)MAX_UPLOAD_SIZE_MB- Max file size (default:100)EMBEDDING_MAX_WORKERS- Parallel workers for embeddings (default:20)USE_VAULT- Enable Vault for secrets (default:false)
To change the embedding or LLM model, update these environment variables:
# In .env file
EMBEDDING_MODEL=text-embedding-004 # Change to your preferred model
LLM_MODEL=gemini-1.5-flash # Change to your preferred modelCheck Google AI Studio Models for available models.
context-forge/
├── app/
│ ├── api/ # API routes
│ ├── core/ # Core config, exceptions, middleware
│ ├── db/ # Database setup
│ ├── models/ # Data models and schemas
│ ├── services/ # External service integrations
│ ├── utils/ # Utilities (security, file loaders)
│ ├── scripts/ # Utility scripts
│ ├── main.py # FastAPI app entry point
│ └── requirements.txt # Python dependencies
├── init/ # Initialization scripts
├── docker-compose.yml # Docker Compose configuration
├── Makefile # Convenience commands
└── README.md # This file
make help # Show all available commands
make up # Start all services
make down # Stop all services
make build # Build and start services
make logs # View logs from all services
make logs-api # View logs from FastAPI only
make init-vault # Initialize Vault with secrets (requires VAULT_TOKEN in .env)
make init-minio # Initialize MinIO bucket
make seed-user # Seed a user (usage: make seed-user USERNAME=dev PASSWORD=devpass)
make test # Run health check
make clean # Remove all containers and volumes
make setup # Build and start services (Vault init requires manual steps)# Install dependencies
cd app
pip install -r requirements.txt
# Set environment variables
export DATABASE_URL=sqlite:///./data/app.db
export GEMINI_API_KEY=your-key
# ... other env vars
# Run the application
uvicorn app.main:app --reloadThe application uses SQLAlchemy with automatic table creation. For production, consider using Alembic for migrations (already included in requirements).
For detailed troubleshooting steps, see SETUP_GUIDE.md.
Services Not Starting:
docker compose ps
docker compose logs -f [service-name]
docker compose restart [service-name]Vault Issues:
- Get token from logs:
docker compose logs vault | grep "Root Token" - Update
.envwithVAULT_TOKENandVAULT_UNSEAL_KEY - Restart Vault:
docker compose restart vault
GEMINI_API_KEY not found:
- Ensure
GEMINI_API_KEYis set in.envfile - If using Vault, ensure it's initialized:
make init-vault
For more troubleshooting help, see SETUP_GUIDE.md.
For production deployment options and considerations, see DEPLOYMENT.md.
Key considerations:
- Vault: Uses RAFT storage (production-ready), but consider managed Vault for production
- Database: Migrate from SQLite to PostgreSQL
- Background Tasks: Consider Celery/Redis for file processing at scale
- Rate Limiting: Add Redis-based rate limiting
- Monitoring: Add Prometheus/Grafana
- Backup Strategy: Implement backups for Weaviate/MinIO data
- Security: Review SECURITY_AUDIT.md for best practices
- JWT Secret: Generate a strong secret for production:
openssl rand -hex 32 - Vault: Dev mode is insecure. Use proper Vault cluster in production.
- API Keys: Store in Vault or secure environment variables.
- CORS: Configure allowed origins for production.
- HTTPS: Always use HTTPS in production.
MIT
- SETUP_GUIDE.md - Complete step-by-step setup instructions
- DEPLOYMENT.md - Production deployment guide
- PRODUCTION_MODIFICATIONS.md - Production considerations
For issues and questions, please open an issue on GitHub.
