AI PDF Reader is a full-stack PDF intelligence platform built for the Adobe Hackathon Finale. It combines a React PDF reading experience with a FastAPI backend that can upload, index, search, summarize, compare, split, merge, and discuss documents through retrieval-augmented generation.
The application is designed around authenticated document libraries. Users sign in with Supabase, upload PDFs, read them in a browser-based viewer, ask contextual questions, surface related sections across documents, generate insights, and create audio or podcast-style summaries from document content.
- Authenticated PDF library with Supabase session handling and per-user document access.
- Smart PDF upload pipeline for active documents and context documents, including validation, metadata extraction, duplicate handling, and background processing.
- RAG chat across a user's document library using chunking, embeddings, vector search, and context-aware prompt construction.
- Intelligent reader view with PDF.js rendering, related documents, text-selection analysis, section highlights, recommendations, and insights.
- Document operations for listing, updating metadata, soft deletion, split, merge, statistics, and RAG reprocessing.
- LLM provider abstraction supporting Gemini, Azure OpenAI, OpenAI, and Ollama-style local providers.
- Text-to-speech and podcast generation through Azure, Google, or local fallback providers.
- WebSocket upload progress so the frontend can show processing status for long-running document jobs.
React + Vite frontend
-> Supabase auth session or guarded development bypass
-> Authenticated API requests through frontend/src/lib/api.ts
-> PDF.js / react-pdf reader and document workflow UI
-> WebSocket progress updates during upload and processing
FastAPI backend
-> Auth middleware and rate limiting
-> Document CRUD routes and chat history routes
-> PDF validation, extraction, section detection, and metadata parsing
-> Chunking, embeddings, vector store, and RAG orchestration
-> LLM providers for chat, recommendations, summaries, and insights
-> TTS providers for audio and podcast generation
Storage and services
-> Supabase Auth for user sessions
-> Private Supabase Storage for uploaded and generated PDF documents
-> Supabase Postgres + pgvector for document metadata, chunks, and vectors
-> Local runtime data only for processing cache and generated audio
| Path | Purpose |
|---|---|
run_app.py |
Local backend startup script for backend.app.main:app. |
backend/app/main.py |
FastAPI application, upload routes, RAG/chat endpoints, reader utilities, and static serving fallback. |
backend/app/document_routes.py |
Document CRUD, statistics, and chat-session API routes. |
backend/app/ingestion_service.py |
PDF ingestion, chunk persistence, embedding generation, and vector indexing coordination. |
backend/app/rag_service.py |
Retrieval-augmented generation service for document-aware answers. |
backend/app/context_builder.py |
Builds library and PDF-viewer context for chatbot interactions. |
backend/app/llm_providers.py |
Provider abstraction for Gemini, Azure OpenAI, OpenAI, and Ollama. |
backend/app/tts_service.py |
Text-to-speech provider abstraction and audio generation support. |
frontend/src/App.tsx |
Frontend route shell for landing, auth, library, and reader pages. |
frontend/src/context |
Auth and PDF state providers used by the frontend. |
frontend/src/components |
Upload, reader, chat, recommendation, insights, and document UI components. |
frontend/src/lib/api.ts |
Centralized frontend API client and auth header handling. |
docs/codebase |
Deeper backend, frontend, operations, and file-inventory documentation. |
graphify-out/GRAPH_REPORT.md |
Generated architecture graph summary used for codebase navigation. |
- Python 3.10 or newer is recommended.
- Node.js 20 or newer is recommended for the Vite frontend.
- Supabase project credentials for production-style auth and storage paths.
- An NVIDIA API key for hosted RAG embeddings and advanced reranking (
NVIDIA_API_KEY). - At least one LLM provider key or local provider:
- Gemini via
GOOGLE_API_KEY - Azure OpenAI via Azure OpenAI environment variables
- OpenAI via
OPENAI_API_KEY - Ollama via local Ollama configuration
- Gemini via
-
Create backend environment values:
copy .env.example .env
Fill in Supabase credentials,
NVIDIA_API_KEY, and one LLM provider. For local development, set:APP_ENV=development CORS_ORIGINS=http://localhost:5173,http://127.0.0.1:5173
-
Create frontend environment values:
copy frontend\.env.example frontend\.env.local
For local backend development:
VITE_APP_ENV=development VITE_API_URL=http://127.0.0.1:8080 VITE_SUPABASE_URL=your_supabase_project_url VITE_SUPABASE_ANON_KEY=your_supabase_anon_key
-
Install backend dependencies:
python -m venv .venv .venv\Scripts\activate pip install -r backend\requirements.txt
For a lighter local install, use
backend/requirements-minimal.txtwhere supported. -
Install frontend dependencies:
cd frontend npm ci cd ..
-
Start the backend:
python run_app.py
The API runs at
http://127.0.0.1:8080. -
Start the frontend in another terminal:
cd frontend npm run devThe app runs at
http://localhost:5173.
Frontend routes:
| Route | Description |
|---|---|
/ |
Landing page. |
/login |
Supabase sign-in page. |
/signup |
Supabase sign-up page. |
/library |
Protected document library and upload workflow. |
/reader/:pdfId |
Protected PDF reader and AI workspace. |
Backend routes include:
| Endpoint | Purpose |
|---|---|
POST /upload/active_file |
Upload the primary PDF for a reader workflow. |
POST /upload/context_files |
Upload supporting PDFs for cross-document context. |
WS /ws/{client_id} |
Stream upload and processing progress. |
GET /api/documents |
List authenticated user's documents. |
GET /api/documents/{document_id} |
Fetch a specific document record. |
DELETE /api/documents/{document_id} |
Delete a document record. |
POST /api/chat |
Ask library-aware or PDF-aware chatbot questions. |
POST /api/ask-gpt |
Ask a contextual question against selected PDF context. |
POST /api/text-selection-analysis |
Analyze selected text from the reader. |
GET /api/recommendations/{document_id} |
Get related document recommendations. |
GET /api/insights/{document_id} |
Generate document insights. |
POST /api/generate-podcast |
Generate an audio summary or podcast artifact. |
POST /api/rag/process/{document_id} |
Reprocess a document for RAG indexing. |
Important backend values:
| Variable | Notes |
|---|---|
APP_ENV |
Use development locally and production in deployed environments. |
PERSISTENCE_BACKEND |
Use supabase in production or sqlite for a local-only stack. |
SUPABASE_URL |
Supabase project URL. |
SUPABASE_ANON_KEY |
Public/anon key used by the backend when fetching auth metadata. |
SUPABASE_SECRET_KEY |
Server-only secret key for Postgres and Storage. Never expose this to the frontend. |
SUPABASE_STORAGE_BUCKET |
Private PDF bucket; defaults to documents. |
SUPABASE_JWT_SECRET |
Needed for legacy HS256 tokens; ES256 tokens use JWKS. |
CORS_ORIGINS |
Comma-separated frontend origins allowed by the API. |
LLM_PROVIDER |
One of gemini, azure, openai, or ollama. |
GOOGLE_API_KEY |
Gemini API key when LLM_PROVIDER=gemini. |
NVIDIA_API_KEY |
Server-only key for NVIDIA hosted embeddings; required for RAG ingestion and search. |
NVIDIA_EMBEDDING_MODEL |
Hosted retrieval model, defaulting to nvidia/nemotron-3-embed-1b. |
NVIDIA_EMBEDDING_DIMENSION |
pgvector/FAISS dimension for that hosted model; changing it requires a schema migration and full re-index. |
NVIDIA_RERANK_MODEL |
Hosted advanced-RAG reranker, defaulting to nvidia/llama-nemotron-rerank-vl-1b-v2. |
NVIDIA_RERANK_ENDPOINT |
HTTPS endpoint for the NVIDIA reranking model. |
TTS_PROVIDER |
Optional TTS provider, such as azure or local fallback. |
AUTH_BYPASS_ENABLED |
Development-only auth bypass; ignored outside development. |
ALLOW_CLIENT_ID_FALLBACK |
Development-only upload fallback; keep disabled in production. |
Important frontend values:
| Variable | Notes |
|---|---|
VITE_APP_ENV |
Frontend runtime environment. |
VITE_API_URL |
Backend API origin, for example http://127.0.0.1:8080. |
VITE_SUPABASE_URL |
Supabase project URL exposed to the browser. |
VITE_SUPABASE_ANON_KEY |
Supabase anon public key. Do not use the service role key here. |
VITE_AUTH_BYPASS_ENABLED |
Development-only auth bypass flag. |
The backend treats LLM output as probabilistic, not deterministic. Provider calls are routed through service layers that can validate responses, apply fallbacks, and keep side effects separate from generated text. Any new AI-facing feature should preserve that pattern: parse defensively, log enough context for debugging, validate before file or database writes, and retry provider failures where the user workflow can tolerate it.
Backend tests:
python -m pytest backend/testsFrontend tests:
cd frontend
npm testFrontend lint:
cd frontend
npm run lintBackend API smoke tests require the server to be running and credentials in .env:
python backend\verify_api.py
python backend\test_upload.pyThe preferred GitHub-connected production path is the Dockerized backend on Render and the Vite frontend on Vercel. Follow docs/DEPLOY_RENDER_VERCEL.md; render.yaml, backend/Dockerfile, and frontend/vercel.json are the provider configuration sources of truth. The older DigitalOcean, Nginx, systemd, and Netlify-style helpers remain legacy deployment references rather than the current production path.
Production checklist:
- Set
APP_ENV=productionandVITE_APP_ENV=production. - Keep
AUTH_BYPASS_ENABLED=falseandVITE_AUTH_BYPASS_ENABLED=false. - Keep
ALLOW_CLIENT_ID_FALLBACK=false. - Configure exact deployed frontend origins in
CORS_ORIGINS. - Store
SUPABASE_SECRET_KEYonly in Render backend secrets. - Store
NVIDIA_API_KEYonly in backend secrets; reprocess uploaded PDFs once after this migration so the NVIDIA vector index is populated and test an advanced-RAG query to verify hosted reranking. - Use the Supabase anon key only in frontend environment variables.
- Verify Supabase PDF, metadata, and RAG persistence after a Render restart; generated audio remains ephemeral until separately moved to object storage.
-
Generated runtime data is intentionally ignored by Git, including
backend/data, local databases, vector indexes, caches, logs, and local.envfiles. -
The architecture graph can be rebuilt with:
python _graphify_build.py
-
For deeper codebase details, start with
docs/codebase/README.md.
No license file is currently present in this repository. Add one before distributing the project publicly if reuse terms need to be explicit.