--- 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= ``` **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.