Skip to content

Repository files navigation

RAG API

A production-ready Retrieval Augmented Generation API that lets you upload PDF documents, ask questions about them, and get accurate answers generated by a local LLM — with full source attribution.

Built with FastAPI, Qdrant, sentence-transformers, and Ollama.


How It Works

POST /documents   →  PDF → extract text → chunk → embed → store in Qdrant
POST /query       →  question → embed → search Qdrant → send context to Ollama → answer
GET  /documents   →  list all uploaded documents and their chunk counts
DELETE /documents →  remove a document and all its chunks from Qdrant
GET  /health      →  health check

Table of Contents


Requirements

  • Python 3.12+
  • Docker (for Qdrant)
  • Ollama (for local LLM inference)

Project Structure

rag-api/
├── .github/
│   └── workflows/
│       └── ci.yml                 — GitHub Actions CI pipeline
├── app/
│   ├── __init__.py
│   ├── main.py                    — FastAPI app and route handlers
│   ├── schema.py                  — Request and response schemas
│   └── services/
│       ├── __init__.py
│       ├── embeddings.py          — sentence-transformer embedding model
│       ├── vector_store.py        — Qdrant operations
│       ├── document_processor.py  — PDF extraction and chunking
│       └── llm.py                 — Ollama REST API integration
├── test/
│   ├── __init__.py
│   └── test_main.py               — full test suite (70 tests)
├── .dockerignore
├── .env
├── .gitignore
├── docker-compose.yml
├── Dockerfile
├── README.md
└── requirements.txt

Getting Started

1. Clone the repository

git clone git@github.com:HonourJAH/rag-api.git
cd rag-api

2. Create and activate a virtual environment

python3 -m venv venv
source venv/bin/activate        # Linux/macOS
venv\Scripts\activate           # Windows

3. Install dependencies

pip install -r requirements.txt

4. Start Qdrant

docker run -d \
  --name qdrant \
  -p 6333:6333 \
  -v qdrant_storage:/qdrant/storage \
  qdrant/qdrant

Qdrant dashboard available at http://localhost:6333/dashboard

5. Install and start Ollama

Download Ollama from ollama.com then pull a model:

ollama pull mistral # swap mistral for llama3.2, gemma, etc. — whatever you have pulled
ollama serve

Ollama runs on http://localhost:11434 by default.

To use a different model, update OLLAMA_MODEL in app/services/llm.py:

OLLAMA_MODEL = "llama3.2"   # or gemma, phi3, etc.

6. Start the API

uvicorn app.main:app --reload

API available at http://localhost:8000 Interactive docs at http://localhost:8000/docs


Running Tests

Tests use mocked external services — no Qdrant or Ollama required to run them.

pytest test/ -v

Run with coverage:

pytest test/ -v --cov=app --cov-report=term-missing

API Endpoints

Method Endpoint Description Status Code
POST /documents Upload a PDF and store its chunks 201 Created
GET /documents List all uploaded documents 200 OK
DELETE /documents/{document_name} Delete a document and all its chunks 200 OK
POST /query Ask a question and get an answer 200 OK
GET /health Health check 200 OK

Request & Response Schemas

POST /documents

Request: multipart/form-data with a PDF file.

Response:

{
  "document_name": "policy.pdf",
  "chunks_stored": 42,
  "message": "Successfully processed and stored 42 chunks from policy.pdf"
}

GET /documents

Response:

{
  "result": 2,
  "documents": [
    { "document_name": "policy.pdf",   "chunk_count": 42 },
    { "document_name": "handbook.pdf", "chunk_count": 31 }
  ]
}

DELETE /documents/{document_name}

Response:

{
  "document_name":  "policy.pdf",
  "chunks_deleted": 42,
  "message": "Successfully deleted 42 chunks from 'policy.pdf'"
}

POST /query

Request body:

Field Type Required Description
question string The question to ask
document_name string Scope search to a specific document
top_k int Number of chunks to retrieve. Defaults to 5

Response:

{
  "question": "What is the refund policy?",
  "answer":   "According to the document, refunds are processed within 14 days..."
}

GET /health

{ "status": "healthy" }

Example Usage

Upload a document

curl -X POST http://localhost:8000/documents \
  -F "file=@company_policy.pdf"

List all documents

curl http://localhost:8000/documents

Ask a question

curl -X POST http://localhost:8000/query \
  -H "Content-Type: application/json" \
  -d '{"question": "What is the parental leave policy?"}'

Ask about a specific document only

curl -X POST http://localhost:8000/query \
  -H "Content-Type: application/json" \
  -d '{
    "question":      "What is the refund policy?",
    "document_name": "company_policy.pdf",
    "top_k":         3
  }'

Delete a document

curl -X DELETE http://localhost:8000/documents/company_policy.pdf

Docker

Build and run the entire API in a container:

docker build -t rag-api .

docker run -d \
  --name rag-api \
  -p 8000:8000 \
  --network host \
  rag-api

--network host allows the container to reach Qdrant and Ollama running on localhost.

Run with Docker Compose (API + Qdrant together):

docker compose up

About

A production-ready RAG API that lets you upload PDFs, ask questions, and get grounded answers from a local LLM using FastAPI, Qdrant, and Ollama.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages