Turn study notes into practice quizzes. Students upload notes (PDF, DOCX, images, or pasted text); Gemini generates multiple-choice questions with a justification for every option (why each is right or wrong). Take graded quizzes and track progress.
- Django 5.2 + HTMX
- SQLite3
- Google Gemini API (
google-genai) - django-allauth (email and password)
uv sync
cp .env.example .env # then set GEMINI_API
uv run python manage.py migrate
uv run python manage.py createsuperuser
uv run python manage.py runserverOpen http://127.0.0.1:8000, sign up, upload notes, and take a quiz.
- Upload notes on
/documents/new. Text is extracted (PDF via pypdf, DOCX via python-docx, images sent directly to Gemini vision, text used as-is). - Gemini generates questions using structured JSON output. Each choice carries a justification.
- Standard mode reveals explanations after each question. Exam mode reveals everything on the results page.
- The dashboard tracks sessions, best score, and answered count.
See .env.example. Key settings: GEMINI_API, GEMINI_MODEL, GEMINI_MAX_CHARS
(input truncation cap), MAX_UPLOAD_SIZE_MB.
The Dockerfile builds a single container (no docker compose). It collects static
files at build time (served by WhiteNoise), runs migrations on boot, and serves via
gunicorn on port 8000.
The database is dynamic: if POSTGRES_DB is set the app uses Postgres, otherwise it
falls back to SQLite. In Coolify, attach a Postgres service and set the env vars below.
- Create a new resource from this Git repository. Coolify auto-detects the
Dockerfile. - Add a Postgres database resource and connect it to the app.
- Set the environment variables (below) on the app.
- Set the app port to
8000and deploy.
Required:
SECRET_KEYlong random stringDEBUGset toFalseALLOWED_HOSTScomma separated, e.g.abc.example.comCSRF_TRUSTED_ORIGINScomma separated full origins, e.g.https://abc.example.comGEMINI_APIyour Gemini API key
Postgres (Coolify injects most of these when you attach a Postgres service):
POSTGRES_DBPOSTGRES_USERPOSTGRES_PASSWORDPOSTGRES_HOSTthe database service name/hostPOSTGRES_PORTdefaults to5432
Optional:
MEDIA_ROOTmount a persistent volume here so uploads survive redeploysWEB_CONCURRENCYgunicorn workers (default3)WEB_TIMEOUTgunicorn timeout seconds (default120)DB_CONN_MAX_AGEpersistent DB connection seconds (default60)
Create the first admin after deploy via Coolify's terminal:
python manage.py createsuperuser