Quizify / README.md
hetsheta's picture
Fix HF Spaces frontmatter: valid emoji and colorTo values
7af470e
|
Raw
History Blame Contribute Delete
8.44 kB
---
title: Quizify
emoji: 🧠
colorFrom: indigo
colorTo: purple
sdk: docker
app_port: 7860
pinned: false
---
# ✦ Quizify β€” AI Quiz Generator
A **Retrieval-Augmented Generation (RAG)** powered quiz application that automatically generates quizzes from your documents using Google's Gemini AI. Upload any study material and the app produces contextually relevant questions, validates answers with semantic similarity, and provides AI-generated explanations β€” all through a sleek **React + Vite** frontend.
---
## ✨ Features
- **Multi-format Ingestion** β€” Upload PDF, DOCX, PPTX, TXT, or MD files; parsed, chunked, and stored in a FAISS vector index
- **Dynamic Quiz Generation** β€” Generates MCQ, True/False, or Short Answer questions directly from document content
- **Anti-Repetition** β€” Tracks previously asked questions to avoid duplicates within a session
- **Smart Answer Validation** β€” Exact match for MCQ/True-False; semantic cosine similarity for short answers
- **AI Explanations** β€” Wrong answers trigger a contextual explanation pulled from the document
- **Modern React UI** β€” Glassmorphism dark theme built with React + Vite, zero UI-library dependencies
- **REST API** β€” Clean FastAPI backend, fully decoupled from the frontend
---
## πŸ–₯️ Tech Stack
| Layer | Technology |
|---|---|
| **Frontend** | React 19, Vite, Vanilla CSS (glassmorphism) |
| **Backend** | FastAPI, Python 3.10+ |
| **AI / LLM** | Google Gemini (`gemini-embedding-001`) |
| **Vector Store** | FAISS (local persistence) |
| **PDF Parsing** | Docling |
| **Semantic Similarity** | `all-MiniLM-L6-v2` via sentence-transformers |
---
## πŸ—‚οΈ Project Structure
```
Quizify/
β”‚
β”œβ”€β”€ backend/
β”‚ β”œβ”€β”€ core/
β”‚ β”‚ β”œβ”€β”€ cache.py # In-memory quiz session cache
β”‚ β”‚ β”œβ”€β”€ config.py # Vector DB path + chunking config
β”‚ β”‚ └── llm.py # Gemini LLM + embeddings
β”‚ β”‚
β”‚ β”œβ”€β”€ faiss_index/ # Persisted FAISS vector store (auto-generated)
β”‚ β”‚
β”‚ β”œβ”€β”€ feedback/
β”‚ β”‚ └── explainer.py # LLM-based explanation generation
β”‚ β”‚
β”‚ β”œβ”€β”€ models/
β”‚ β”‚ └── schemas.py # Pydantic request/response schemas
β”‚ β”‚
β”‚ β”œβ”€β”€ quiz/
β”‚ β”‚ β”œβ”€β”€ generator.py # LLM-based quiz question generation
β”‚ β”‚ β”œβ”€β”€ semantic.py # Sentence-transformer cosine similarity
β”‚ β”‚ └── validator.py # Answer validation (exact + semantic)
β”‚ β”‚
β”‚ β”œβ”€β”€ rag/
β”‚ β”‚ β”œβ”€β”€ parser.py # Document β†’ markdown β†’ FAISS chunks
β”‚ β”‚ β”œβ”€β”€ retriever.py # Random diverse context retrieval
β”‚ β”‚ └── vector_store.py # FAISS load/save helpers
β”‚ β”‚
β”‚ β”œβ”€β”€ utils/
β”‚ β”‚ └── text_utils.py # Text normalization utilities
β”‚ β”‚
β”‚ └── main.py # FastAPI app + route handlers
β”‚
β”œβ”€β”€ frontend/ # React + Vite frontend
β”‚ β”œβ”€β”€ index.html
β”‚ β”œβ”€β”€ vite.config.js
β”‚ β”œβ”€β”€ package.json
β”‚ └── src/
β”‚ β”œβ”€β”€ main.jsx
β”‚ β”œβ”€β”€ App.jsx # Main app (wizard state machine)
β”‚ β”œβ”€β”€ App.css # Component-level styles
β”‚ β”œβ”€β”€ index.css # Global tokens, resets, animations
β”‚ β”œβ”€β”€ api.js # Fetch-based API client
β”‚ └── components/
β”‚ β”œβ”€β”€ DropZone.jsx # Drag & drop file uploader
β”‚ β”œβ”€β”€ StepHeader.jsx # Animated step badge
β”‚ β”œβ”€β”€ QuestionCard.jsx # MCQ radio + text answer card
β”‚ β”œβ”€β”€ ResultsView.jsx # Score hero + per-question review
β”‚ └── Alert.jsx # Warning / error / success alerts
β”‚
β”œβ”€β”€ .gitignore
β”œβ”€β”€ .env.example # Copy to backend/core/.env and add your API key
└── requirements.txt # Backend Python dependencies
```
---
## πŸš€ Getting Started
### Prerequisites
- Python 3.10+
- Node.js 18+
- A Google AI API key from [https://aistudio.google.com](https://aistudio.google.com)
---
### 1. Clone the repository
```bash
git clone https://github.com/hetsheta/Quizify.git
cd Quizify
```
### 2. Create and activate a Python virtual environment
```bash
python -m venv venv
# macOS / Linux
source venv/bin/activate
# Windows
venv\Scripts\activate
```
### 3. Install backend dependencies
```bash
pip install -r requirements.txt
```
### 4. Set up your API key
Open the `.env.example` file at the root of the repo and add your Google AI API key:
```
GOOGLE_API_KEY=your-google-ai-api-key-here
```
> Get your key at [aistudio.google.com](https://aistudio.google.com/app/apikey). It is already covered by `.gitignore` β€” never commit it.
### 5. Run the backend server
```bash
cd backend
uvicorn main:app --reload
```
The API will be available at `http://localhost:8000`.
Interactive API docs: `http://localhost:8000/docs`
### 6. Run the frontend
Open a **new terminal**:
```bash
cd frontend
npm install
npm run dev
```
The app will open at **`http://localhost:5173`**
---
## πŸ”Œ API Endpoints
### `POST /parse-document`
Upload a document to build the vector index.
```
Content-Type: multipart/form-data
Body: file=<your_file>
```
**Response:**
```json
{ "status": "success" }
```
---
### `POST /generate-quiz`
Generate a quiz from the uploaded document.
**Request body:**
```json
{
"topic": "full document",
"num_questions": 5,
"difficulty": "Medium",
"question_type": "MCQ"
}
```
- `question_type`: `"MCQ"` | `"True/False"` | `"Short Answer"`
- `difficulty`: `"Easy"` | `"Medium"` | `"Hard"`
**Response:**
```json
{
"quiz_id": "uuid-string",
"questions": [
{
"question": "What is supervised learning?",
"options": ["A) ...", "B) ...", "C) ...", "D) ..."]
}
]
}
```
---
### `POST /submit-quiz`
Submit answers and receive scored results with explanations.
**Request body:**
```json
{
"quiz_id": "uuid-string",
"answers": [
{ "question_index": 0, "user_answer": "A) ..." },
{ "question_index": 1, "user_answer": "True" }
]
}
```
**Response:**
```json
{
"score": 3,
"total": 5,
"results": [
{
"question": "...",
"user_answer": "...",
"correct_answer": "...",
"correct": false,
"similarity_score": 0.42,
"explanation": "The correct answer is ... because ...",
"concept": "..."
}
]
}
```
---
## βš™οΈ Configuration
### Environment Variables (`.env.example`)
| Variable | Description |
|---|---|
| `GOOGLE_API_KEY` | Your Gemini API key β€” loaded by `core/llm.py` via `python-dotenv` |
### App Settings (`backend/core/config.py`)
| Variable | Default | Description |
|---|---|---|
| `VECTOR_DB_PATH` | `faiss_index` | Local path for FAISS persistence |
| `CHUNK_SIZE` | `900` | Characters per document chunk |
| `CHUNK_OVERLAP` | `200` | Overlap between adjacent chunks |
---
## 🧠 How It Works
1. **Parse** β€” Document is converted to markdown via `docling`, split into overlapping chunks, embedded using `gemini-embedding-001`, and stored in a FAISS index.
2. **Generate** β€” On quiz request, diverse chunks are retrieved using randomised query sampling. Gemini generates questions strictly from that content.
3. **Validate** β€” MCQ/True-False answers use normalised letter matching. Short answers use `all-MiniLM-L6-v2` cosine similarity with a 0.50 threshold.
4. **Explain** β€” Incorrect answers trigger an LLM explanation grounded in the document context (max 120 words, difficulty-appropriate).
---
## πŸ“¦ Key Dependencies
### Backend
| Package | Purpose |
|---|---|
| `fastapi` | REST API framework |
| `langchain` + `langchain-google-genai` | LLM orchestration |
| `google-genai` | Gemini LLM & embeddings |
| `faiss-cpu` | Vector similarity search |
| `docling` | Document β†’ structured markdown parsing |
| `sentence-transformers` | Short-answer semantic validation |
| `scikit-learn` | Cosine similarity computation |
| `python-dotenv` | Loads API key from `.env` at runtime |
### Frontend
| Package | Purpose |
|---|---|
| `react` + `react-dom` | UI framework |
| `vite` | Dev server & build tool |
---
## πŸ“ License
MIT License. See `LICENSE` for details.