A secure PDF Question Answering System built with Python, Streamlit, ChromaDB, OpenAI API, Sentence Transformers, and SQLite.
This project lets users sign in securely with their Google account, upload PDF documents, ask questions from those PDFs, and get source-based answers using a RAG pipeline.
Secure PDF RAG Assistant is an AI-powered application that allows users to chat with PDF documents.
The system extracts text from uploaded PDFs, splits the text into chunks, creates embeddings, stores them in a vector database, retrieves relevant chunks based on the user question, and generates answers using an LLM.
It also includes user authentication and saved chat history.
- Secure "Sign in with Google" authentication (no passwords stored)
- Role-based accounts (admin / user) — first registered user becomes admin
- Admin dashboard: view all users and usage, enable/disable accounts
- Multi-PDF support per user with per-user quotas (max PDF count & size)
- Document manager: list and delete uploaded PDFs
- Chat scope selector: ask across all PDFs or one specific document
- Delete individual conversations
- PDF upload system
- PDF text extraction
- Text chunking
- Embedding generation
- ChromaDB vector database
- RAG-based question answering
- Source/page references in answers
- Chat history storage
- User-wise private data separation
- Streamlit-based web UI
- Python
- Streamlit
- PyMuPDF
- ChromaDB
- Sentence Transformers
- OpenAI API
- SQLite
- Authlib (Google OAuth / OIDC login via Streamlit's native
st.login) - python-dotenv
The project follows this pipeline:
PDF Upload
↓
PDF Text Extraction
↓
Text Chunking
↓
Embedding Generation
↓
Vector Database Storage
↓
User Question
↓
Relevant Chunk Retrieval
↓
LLM Answer Generation
↓
Answer with Source/Page Referencepdf_rag_project/
│
├── app.py
├── auth.py
├── database.py
├── documents.py
├── ingest.py
├── ask.py
├── requirements.txt
├── README.md
├── .env
├── .streamlit/
│ ├── config.toml
│ ├── secrets.toml.example
│ └── secrets.toml (your own, gitignored)
│
├── data/
├── chroma_db/
├── app_data.db
└── venv/Main Streamlit application file. It contains the UI, authentication flow, PDF upload, RAG pipeline, and chat interface.
Resolves a local user record from the Google-authenticated identity (st.user) — creates one on first sign-in, reuses it on return visits. No passwords are stored or handled.
Creates and manages SQLite database tables for users, conversations, chat messages, and documents. Also holds admin queries (user list, usage summary, enable/disable).
Handles PDF lifecycle: quota checks (MAX_PDFS_PER_USER, MAX_PDF_SIZE_MB), extraction/chunking/embedding/storage in ChromaDB, and deletion (file + vectors + DB record).
SQLite database file where user accounts and chat history are stored.
Stores PDF chunks and vector embeddings using ChromaDB.
Stores uploaded PDF files.
The project uses SQLite with the following tables:
Stores user account information.
id
name
email
password_hash (unused placeholder — identity comes from Google, not a password)
created_at
role (admin | user — first registered user becomes admin)
is_active (0 | 1 — disabled accounts cannot log in)Stores metadata for each uploaded PDF per user.
id
user_id
filename
file_path
chunk_count
created_atStores chat sessions for each user.
id
user_id
title
created_atStores user questions and assistant answers.
id
conversation_id
user_id
role
content
created_atThis project does not handle or store passwords at all — identity comes entirely from Google Sign-In (OpenID Connect), and Streamlit keeps the login session in a signed cookie.
The .env file and .streamlit/secrets.toml should never be uploaded to GitHub because they contain secret API keys and OAuth credentials.
The following files/folders should not be committed:
.env
.streamlit/secrets.toml
venv/
app_data.db
chroma_db/
data/
__pycache__/Clone the repository:
git clone https://github.com/YOUR_USERNAME/pdf-rag-assistant.git
cd pdf-rag-assistantCreate virtual environment:
python -m venv venvActivate virtual environment:
For Windows:
venv\Scripts\ActivateFor Mac/Linux:
source venv/bin/activateInstall dependencies:
pip install -r requirements.txtCreate a .env file in the project root:
OPENAI_API_KEY=your_openai_api_key_here
OPENAI_MODEL=gpt-5.5
# Optional — per-user fair-use quotas (defaults shown)
MAX_PDFS_PER_USER=5
MAX_PDF_SIZE_MB=20The app uses Streamlit's native Google OAuth login, which needs your own Google OAuth credentials — this is a one-time setup you do yourself in Google Cloud Console (nobody else can create these for you, since they're tied to your Google account):
- Go to Google Cloud Console and create a new project (or use an existing one).
- Go to APIs & Services → OAuth consent screen and configure it (choose "External" if this is for the public, fill in the required app info).
- Go to APIs & Services → Credentials → Create Credentials → OAuth client ID.
- Choose Web application as the application type.
- Under Authorized redirect URIs, add:
http://localhost:8501/oauth2callback(for local testing)https://<your-app-name>.streamlit.app/oauth2callback(add this once you know your deployed app's URL on Streamlit Cloud)
- Save, then copy the Client ID and Client Secret shown.
- Copy
.streamlit/secrets.toml.exampleto.streamlit/secrets.tomland fill in your values:
OPENAI_API_KEY = "your_openai_api_key_here"
OPENAI_MODEL = "gpt-5.5"
[auth]
redirect_uri = "http://localhost:8501/oauth2callback"
cookie_secret = "any-long-random-string"
[auth.google]
client_id = "your-client-id.apps.googleusercontent.com"
client_secret = "your-client-secret"
server_metadata_url = "https://accounts.google.com/.well-known/openid-configuration".streamlit/secrets.toml is already in .gitignore — never commit it.
Run the Streamlit app:
streamlit run app.pyThen open the local URL in your browser:
http://localhost:8501- Open the app.
- Click Continue with Google and sign in (the first Google account to ever sign in becomes the admin).
- Upload a PDF file from the sidebar (subject to your PDF count/size quota).
- Click
Process PDF. - Manage your uploads from the "My Documents" panel — delete any PDF you no longer need.
- Choose a chat scope: all your PDFs, or one specific document.
- Ask questions and view answers with source/page references (answers are always in English).
- Continue previous conversations from chat history, or delete a conversation you no longer need.
- Admin accounts additionally see an "Admin Dashboard" panel to view all users' usage and enable/disable accounts.
This project is a Streamlit application, so the recommended deployment platform is Streamlit Community Cloud.
Deployment steps:
- Push the project to GitHub (make sure
.streamlit/secrets.tomlandapp_data.dbare not included — they're gitignored by default). - Go to Streamlit Community Cloud and create a new app.
- Connect your GitHub repository, select
app.pyas the main file, and deploy once — you'll get a URL likehttps://<your-app-name>.streamlit.app. - Go back to Google Cloud Console → your OAuth client → add
https://<your-app-name>.streamlit.app/oauth2callbackto Authorized redirect URIs. - In Streamlit Community Cloud, open your app's Settings → Secrets and paste:
OPENAI_API_KEY = "your_openai_api_key_here"
OPENAI_MODEL = "gpt-5.5"
[auth]
redirect_uri = "https://<your-app-name>.streamlit.app/oauth2callback"
cookie_secret = "any-long-random-string"
[auth.google]
client_id = "your-client-id.apps.googleusercontent.com"
client_secret = "your-client-secret"
server_metadata_url = "https://accounts.google.com/.well-known/openid-configuration"- Reboot the app from the Streamlit Cloud dashboard so the new secrets take effect.
Streamlit Community Cloud hosting is free, but two things are not:
- OpenAI API usage still costs money per question — hosting being free doesn't make the AI calls free. Keep an eye on your OpenAI usage dashboard, especially once real users start chatting.
- Free-tier compute is limited (shared CPU, ~1GB RAM). This app is hardened to not crash under concurrent use (SQLite lock timeout, error handling around AI calls), but if you truly need guaranteed performance for 50+ simultaneous users, the architecture described in the accompanying SaaS guide (FastAPI + PostgreSQL + background workers on a small paid server) is the next step up.
- Better source citation UI
- OCR support for scanned PDFs
- PostgreSQL database for production
- Cloud storage for PDF files
- FastAPI backend
- React frontend
- Docker deployment
- Billing/subscription plans (Stripe) for paid tiers
- Additional login providers (Microsoft, email/password fallback)
This project is currently in progress as part of my AI Engineer learning and portfolio journey.
Built by [Your Name]
Python, Streamlit, RAG, LLM, OpenAI API, ChromaDB, Vector Database, Embeddings, PDF Chatbot, SQLite, Authentication, Machine Learning, AI Engineer