A FastAPI service that turns source material — pasted text, a PDF, a DOCX, a TXT, or an image — into a structured quiz, using the Google Gemini API.
Questions come back as validated JSON: question, options, correct answer, explanation and
question type. Nothing is parsed out of prose, so the shape of a response is guaranteed by
the model's responseSchema rather than by regex.
| Method | Path | Purpose |
|---|---|---|
GET |
/ |
Redirects to the interactive docs |
GET |
/docs |
Swagger UI — try the API from the browser |
GET |
/health |
Liveness probe; reports the active model |
POST |
/generate-text-quiz |
Quiz from a JSON body of text |
POST |
/generate-file-quiz |
Quiz from an uploaded file |
multiple_choice, true_false, fill_in_the_blank, short_answer, matching, or
mixed to spread questions across all five. /generate-file-quiz also accepts a
comma-separated list, e.g. question_type=true_false,short_answer.
curl -X POST http://localhost:8080/generate-text-quiz \
-H "Content-Type: application/json" \
-d '{"text": "The Treaty of Westphalia was signed in 1648...",
"num_questions": 4, "num_options": 4,
"question_type": "mixed", "difficulty": "medium"}'{
"questions": [
{
"question": "What principle did the Treaty of Westphalia establish?",
"options": ["The birth of the modern international system",
"The principle of state sovereignty",
"The end of the Thirty Years War",
"The creation of a single global territory"],
"correct_answer": "The principle of state sovereignty",
"explanation": "The text states the treaty established state sovereignty.",
"question_type": "multiple_choice"
}
],
"source_text_summary": "The Treaty of Westphalia was signed in 1648..."
}correct_answer is a string, except for matching questions, where it is the list of
correct pairings.
| Variable | Default | Purpose |
|---|---|---|
GEMINI_API_KEY |
(required) | Google AI Studio API key; the app refuses to start without it |
GEMINI_MODEL |
gemini-3.5-flash |
Any model supporting structured outputs |
MAX_UPLOAD_MB |
10 |
Upload size ceiling |
ALLOWED_ORIGINS |
* |
Comma-separated CORS origins; set this before putting a browser client in front of it |
python -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt
export GEMINI_API_KEY=...
uvicorn app.main:app --reload --port 8080Then open http://localhost:8080/docs.
Run the self-check with python test_normalise.py.
Vercel — vercel.json routes every request into api/index.py, which serves the ASGI
app. Set GEMINI_API_KEY in the project's environment variables, then vercel --prod.
Container — docker build -t quiz-generator . && docker run -p 8080:8080 -e GEMINI_API_KEY=... quiz-generator.
.pdf, .docx, .txt, .png, .jpg, .jpeg. Images are passed to the model directly
rather than being OCR'd in a separate pass.
- The service generates quizzes but does not store or export them; each call is stateless.
- There is no built-in UI beyond the Swagger page at
/docs. - Question quality depends on the source material — thin input yields thin questions.