Skip to content

Repository files navigation

AskDocuMind API

Quick Links

Overview

AskDocuMind allows users to upload PDF, DOCX, TXT, or Markdown files and immediately start asking natural-language questions about their content. The backend handles document ingestion, vector embedding, semantic search, and LLM-powered response generation.

For the purposes of the demo, no user registration is required, activity is fully tracked within an anonymous user session (cookie sessions).

When the document context is insufficient, the system can optionally fall back to a live web search (via Brave Search API) to supplement the answer.

Live demo: askdocumind.com

Problem

Long documents bury the one answer you actually need. Finding it usually means re-reading pages you've already seen, guessing the exact phrasing Ctrl+F needs to match, or scanning page by page hoping to spot the right paragraph — all before you can even trust that what you found is complete or current.

Solution

AskDocuMind answers questions directly from a document's content instead of a bare LLM guess. Retrieval-Augmented Generation (RAG) embeds the document, retrieves only the chunks relevant to the question, and generates an answer grounded in — and citing — those chunks. No document match means the system says so rather than fabricating an answer, with an optional live web search fallback when the documents themselves don't have it. No sign-up is required: identity is a short-lived anonymous session, so there's no friction between landing on the page and asking a question.

Features

  • Document upload: PDF, DOCX, TXT, and Markdown, CSV, HTML files up to 0.5 MB each
  • Context-aware chunking: Documents are parsed and chunked with Docling's hybrid chunker, which splits on document structure and token limits rather than fixed-size windows
  • RAG pipeline: Chunks are embedded and stored as vectors in PostgreSQL via pgvector
  • Semantic search: Cosine similarity retrieval finds the most relevant chunks for each query
  • Reranking: A cross-encoder model rescoring component for improving retrieved-chunk relevance
  • Query expansion: Vague or short queries are rewritten by the LLM into fuller, more searchable questions before retrieval
  • LLM responses: GPT-powered answers grounded in document context, with prompt injection protection
  • Web search fallback: Optional Brave Search integration supplements answers when documents lack the information
  • Anonymous sessions: No sign-up required; sessions are cookie-based and automatically cleaned up after TTL expiry
  • Rate limiting: Per-user request limits on all endpoints via SlowAPI
  • File validation: MIME type checking, magic byte validation, size limits, and duplicate detection
  • Structured error responses: Consistent JSON error shape across all endpoints
  • Health endpoints: API and database health checks for uptime monitoring

Technology Stack

Layer Technology Purpose
API framework FastAPI 0.118 Async REST API
Database PostgreSQL 16 + pgvector Document storage and vector search
ORM SQLAlchemy 2 (async) Database models and queries
Migrations Alembic Schema versioning
LLM OpenAI GPT-3.5-turbo / GPT-4o-mini Response generation
Embeddings OpenAI text-embedding-3-small Semantic vector creation
LLM orchestration LangChain RAG chain construction
Document parsing & chunking Docling Context-aware text extraction and chunking
Reranking Cross-encoder (sentence-transformers) Rescoring retrieved chunks for relevance
Web search Brave Search API Optional live search fallback
Rate limiting SlowAPI Per-user request throttling
Session auth HMAC-signed rotating token in HttpOnly cookies Anonymous user sessions
File storage Local filesystem / AWS S3 Document file storage
Deployment Docker + Railway Container hosting
Error tracking Sentry Production error monitoring

How to Setup

Prerequisites

  • Python 3.11+
  • Docker and Docker Compose
  • An OpenAI API key

1. Clone the repository

git clone https://github.com/EmmanuelM-A/askdocumind-api.git
cd askdocumind-api

2. Create a virtual environment

python -m venv venv

# Windows
venv\Scripts\activate

# macOS / Linux
source venv/bin/activate

3. Install dependencies

pip install -r requirements.txt

4. Set up environment variables

Copy the env examples from .env.example into your .env file in the project root and fill in the required values:

cp .env.example .env

5. Start the database

docker-compose up -d

This starts a PostgreSQL 16 + pgvector container on port 5432.

6. Run database migrations

alembic upgrade head

7. Start the API

uvicorn src.api.server:app --host localhost --port 5000 --reload

# OR Run this
python -m src.api.server

The API is now available at http://localhost:5000. Interactive docs are at http://localhost:5000/api/docs.

Environment Variables Reference

Variable Required Default Description
ENV Yes development or production
PORT Yes Port the server listens on
DATABASE_URL Yes PostgreSQL connection string
USER_SESSION_SECRET Yes Secret used to sign session JWTs
OPENAI_API_KEY Yes OpenAI API key
OPENAI_LLM_MODEL_NAME Yes GPT model name (e.g. gpt-3.5-turbo)
OPENAI_EMBEDDING_MODEL_NAME Yes Embedding model name
CORS_ORIGINS Yes JSON array of allowed origins
IS_WEB_SEARCH_ENABLED No false Enable Brave Search fallback
BRAVE_SEARCH_API_KEY If web search enabled Brave Search API key
MAX_FILE_SIZE_MB No 0.5 Max size per uploaded file
MAX_DOCUMENTS_PER_CHAT No 10 Max documents per session
RETRIEVAL_TOP_K No 5 Number of chunks retrieved per query
SIMILARITY_THRESHOLD No 0.4 Minimum cosine similarity score
LLM_MAX_OUTPUT_TOKENS No 1024 Max tokens in LLM response
MAX_WEB_SEARCHES_PER_SESSION No 3 Web search calls per session
LOG_LEVEL No DEBUG DEBUG, INFO, WARNING, ERROR
LOG_TO No FILE CONSOLE, FILE, or BOTH
SENTRY_DSN No Sentry DSN for error tracking
RATE_LIMIT_REQUESTS No 100 Global request cap per RATE_LIMIT_WINDOW, keyed by IP
RATE_LIMIT_WINDOW No 60 Window (seconds) for RATE_LIMIT_REQUESTS
MAX_CHAT_QUERIES_PER_MINUTE No 10 Chat query cap per anonymous session
MAX_UPLOAD_REQUESTS_PER_MINUTE No 5 Document upload cap per anonymous session
MAX_SESSION_REQUESTS_PER_MINUTE No 10 Chat-session mutation cap per anonymous session
MAX_CONCURRENT_REQUESTS No 50 Max in-flight requests before returning 503
HF_TOKEN No Hugging Face token (model downloads for reranking)
DB_POOL_SIZE No SQLAlchemy connection pool size
DB_MAX_OVERFLOW No SQLAlchemy pool overflow allowance
DB_POOL_TIMEOUT_SECS No Seconds to wait for a pooled connection before erroring

Deployment

The backend is deployed on Railway with a PostgreSQL database add-on. The frontend is deployed on Vercel. DNS and CDN are managed through Cloudflare.

Production environment variables

Set these in your Railway service's environment settings:

ENV=production
DATABASE_URL=<railway-postgres-url>
USER_SESSION_SECRET=<strong-random-secret>
OPENAI_API_KEY=<your-key>
OPENAI_LLM_MODEL_NAME=gpt-4o-mini
OPENAI_EMBEDDING_MODEL_NAME=text-embedding-3-small
CORS_ORIGINS=["https://yourdomain.com","https://www.yourdomain.com"]
ANON_SESSION_COOKIE_SAMESITE=none
ANON_SESSION_COOKIE_DOMAIN=api.yourdomain.com
LOG_TO=CONSOLE
LOG_LEVEL=INFO
SENTRY_DSN=<your-sentry-dsn>

Docker

A Dockerfile is included. To build and run manually:

docker build -t askdocumind-api .
docker run -p 5000:5000 --env-file .env askdocumind-api

Project Structure

docuchat-backend/
├── src/
│   ├── api/
│   │   ├── controllers/        # Request handling and response assembly
│   │   ├── middleware/         # CORS, session auth, rate limit, request size
│   │   ├── routes/             # FastAPI route definitions
│   │   ├── services/           # Business logic (auth, uploads, chat sessions)
│   │   └── utils/              # Cookie manager, response builders, session manager
│   ├── components/
│   │   ├── chatbot/            # RAGChatbot and QueryHandler
│   │   ├── ingestion/          # Document text extraction and chunking
│   │   ├── prompts/            # Prompt template loader
│   │   └── retrieval/          # Embedder, VectorProcessor, WebSearcher
│   ├── config/
│   │   └── configs.py          # All settings via pydantic-settings
│   ├── database/
│   │   ├── models.py           # SQLAlchemy ORM models
│   │   ├── connection.py       # Async engine and session factory
│   │   └── repository/         # Repository pattern (interfaces + SQLAlchemy impl)
│   ├── errors/                 # Custom exception types
│   └── logger/                 # BaseLogger and formatters
├── data/
│   └── prompts/                # YAML prompt templates
├── alembic/                    # Database migration scripts
├── logs/                       # Runtime log files (gitignored)
├── docker-compose.yml
├── Dockerfile
└── requirements.txt

API Documentation

Interactive API documentation is available at /api/docs when the server is running.

Key endpoint groups:

Prefix Description
POST /api/auth/anonymous Bootstrap an anonymous user session and receive a session cookie
POST /api/sessions/init Create or retrieve the current chat session
POST /api/documents/upload Upload one or more documents for the session
GET /api/documents List documents in the current session
POST /api/chatbot/query Submit a query and receive a RAG-generated answer
GET /api/health/api API liveness check
GET /api/health/db Database connectivity check

Known Limitations

  • One chat session per user: Anonymous sessions support a single active chat. Multi-session support is a post-v1 roadmap item.
  • No persistent accounts: Sessions are anonymous and expire after 1 hour of inactivity. Uploaded documents are not retained across sessions.
  • File size cap: Individual files are limited to 0.5 MB and total upload per session is capped at 2 MB. Large documents should be split before uploading.
  • Web search quota: Brave Search free tier allows 2,000 requests/month. Per-session web search is capped at 3 calls to stay within quota.
  • English-primary prompts: The system prompt is written in English. The LLM will respond in the user's language, but prompt injection protection rules are English-only.
  • In-memory web search counter: The per-session web search limit resets on server restart.

About

A RAG-powered document chatbot - upload your files and ask questions about them using AI. Built with FastAPI, pgvector, and OpenAI. Features anonymous sessions, web search fallback, and semantic retrieval.

Topics

Resources

Stars

1 star

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages