Skip to content

jatzz10/context-forge

Repository files navigation

Context Forge

A production-ready RAG (Retrieval-Augmented Generation) API built with FastAPI, Weaviate, MinIO, and Google Gemini.

Demo

Demo Video

Features

  • 🔐 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

Architecture

┌─────────────┐
│   FastAPI   │
│   (Python)  │
└──────┬──────┘
       │
       ├──► SQLite (Users/Auth)
       ├──► Weaviate (Vector DB)
       ├──► MinIO (Object Storage)
       ├──► Vault (Secrets)
       └──► Gemini API (Embeddings + LLM)

Quick Start

📖 For detailed step-by-step setup instructions, see SETUP_GUIDE.md

Prerequisites

  • Docker and Docker Compose
  • A Google AI Studio API key (Get one here)

Quick Setup

# 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

Access the API

For complete setup instructions, troubleshooting, and detailed explanations, see SETUP_GUIDE.md

Usage Examples

1. Login and Get Token

# 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"
# }

2. Create a Context with Document Upload

# 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."
# }

3. Check Document Status

curl -X GET "http://localhost:8000/contexts/my-docs/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": "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": {...}
# }

Complete Workflow Example

# 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}"

Configuration

Environment Variables

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 with openssl 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)

Model Configuration

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 model

Check Google AI Studio Models for available models.

Project Structure

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

Makefile Commands

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)

Development

Running Locally (without Docker)

# 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 --reload

Database Migrations

The application uses SQLAlchemy with automatic table creation. For production, consider using Alembic for migrations (already included in requirements).

Troubleshooting

For detailed troubleshooting steps, see SETUP_GUIDE.md.

Common Issues

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 .env with VAULT_TOKEN and VAULT_UNSEAL_KEY
  • Restart Vault: docker compose restart vault

GEMINI_API_KEY not found:

  • Ensure GEMINI_API_KEY is set in .env file
  • If using Vault, ensure it's initialized: make init-vault

For more troubleshooting help, see SETUP_GUIDE.md.

Production Deployment

For production deployment options and considerations, see DEPLOYMENT.md.

Key considerations:

  1. Vault: Uses RAFT storage (production-ready), but consider managed Vault for production
  2. Database: Migrate from SQLite to PostgreSQL
  3. Background Tasks: Consider Celery/Redis for file processing at scale
  4. Rate Limiting: Add Redis-based rate limiting
  5. Monitoring: Add Prometheus/Grafana
  6. Backup Strategy: Implement backups for Weaviate/MinIO data
  7. Security: Review SECURITY_AUDIT.md for best practices

Security Notes

  • 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.

License

MIT

Documentation

Support

For issues and questions, please open an issue on GitHub.

About

Context Forge: A FastAPI RAG Backend Service

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors