Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

5 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Secure PDF RAG Assistant

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.


Project Overview

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.


Features

  • 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

Tech Stack

  • Python
  • Streamlit
  • PyMuPDF
  • ChromaDB
  • Sentence Transformers
  • OpenAI API
  • SQLite
  • Authlib (Google OAuth / OIDC login via Streamlit's native st.login)
  • python-dotenv

RAG Pipeline

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 Reference

Folder Structure

pdf_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/

Important Files

app.py

Main Streamlit application file. It contains the UI, authentication flow, PDF upload, RAG pipeline, and chat interface.

auth.py

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.

database.py

Creates and manages SQLite database tables for users, conversations, chat messages, and documents. Also holds admin queries (user list, usage summary, enable/disable).

documents.py

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

app_data.db

SQLite database file where user accounts and chat history are stored.

chroma_db/

Stores PDF chunks and vector embeddings using ChromaDB.

data/

Stores uploaded PDF files.


Database Tables

The project uses SQLite with the following tables:

users

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)

documents

Stores metadata for each uploaded PDF per user.

id
user_id
filename
file_path
chunk_count
created_at

conversations

Stores chat sessions for each user.

id
user_id
title
created_at

messages

Stores user questions and assistant answers.

id
conversation_id
user_id
role
content
created_at

Security Notes

This 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__/

Installation

Clone the repository:

git clone https://github.com/YOUR_USERNAME/pdf-rag-assistant.git
cd pdf-rag-assistant

Create virtual environment:

python -m venv venv

Activate virtual environment:

For Windows:

venv\Scripts\Activate

For Mac/Linux:

source venv/bin/activate

Install dependencies:

pip install -r requirements.txt

Environment Variables

Create 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=20

Setting Up Google Sign-In

The 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):

  1. Go to Google Cloud Console and create a new project (or use an existing one).
  2. Go to APIs & Services → OAuth consent screen and configure it (choose "External" if this is for the public, fill in the required app info).
  3. Go to APIs & Services → Credentials → Create Credentials → OAuth client ID.
  4. Choose Web application as the application type.
  5. 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)
  6. Save, then copy the Client ID and Client Secret shown.
  7. Copy .streamlit/secrets.toml.example to .streamlit/secrets.toml and 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 Locally

Run the Streamlit app:

streamlit run app.py

Then open the local URL in your browser:

http://localhost:8501

How to Use

  1. Open the app.
  2. Click Continue with Google and sign in (the first Google account to ever sign in becomes the admin).
  3. Upload a PDF file from the sidebar (subject to your PDF count/size quota).
  4. Click Process PDF.
  5. Manage your uploads from the "My Documents" panel — delete any PDF you no longer need.
  6. Choose a chat scope: all your PDFs, or one specific document.
  7. Ask questions and view answers with source/page references (answers are always in English).
  8. Continue previous conversations from chat history, or delete a conversation you no longer need.
  9. Admin accounts additionally see an "Admin Dashboard" panel to view all users' usage and enable/disable accounts.

Deployment

Recommended Deployment

This project is a Streamlit application, so the recommended deployment platform is Streamlit Community Cloud.

Deployment steps:

  1. Push the project to GitHub (make sure .streamlit/secrets.toml and app_data.db are not included — they're gitignored by default).
  2. Go to Streamlit Community Cloud and create a new app.
  3. Connect your GitHub repository, select app.py as the main file, and deploy once — you'll get a URL like https://<your-app-name>.streamlit.app.
  4. Go back to Google Cloud Console → your OAuth client → add https://<your-app-name>.streamlit.app/oauth2callback to Authorized redirect URIs.
  5. 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"
  1. Reboot the app from the Streamlit Cloud dashboard so the new secrets take effect.

A note on cost and scale

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.

Future Improvements

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

Project Status

This project is currently in progress as part of my AI Engineer learning and portfolio journey.


Author

Built by [Your Name]


Keywords

Python, Streamlit, RAG, LLM, OpenAI API, ChromaDB, Vector Database, Embeddings, PDF Chatbot, SQLite, Authentication, Machine Learning, AI Engineer

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages