A Windows-first, LAN-accessible high-school math solving website. Users log in, upload 1-5 screenshots for one math problem, wait in a FIFO queue, then preview or download the generated PDF answer.
The solving core is local Codex CLI (codex exec) using the beijing-high-school-math-pdf workflow. The website treats data/jobs/<job_id>/result/answer.pdf as the success artifact.
- FastAPI website with Jinja2 templates and lightweight JavaScript
- Cookie login with seeded teacher/admin accounts
- Per-user job isolation for upload, preview, and download
- SQLite persistence for users, jobs, files, job events, auth events, and active sessions
- FIFO queue with at most 3 solving jobs running concurrently
- Worker image preprocessing from PNG/WebP/JPEG into Codex-ready JPEG files
- Visible 5-stage progress UI: queued, preparing screenshots, starting model, solving problem, checking PDF
- PDF preview and download endpoints after completion
- Lightweight Tk desktop GUI for start/stop/open, model settings, and backend monitoring
- Restart recovery that reconciles already-generated PDFs back to succeeded jobs
- Windows
- Python 3.11 or newer
- Local Codex CLI available as
codex.cmd - A Codex setup that can use the
beijing-high-school-math-pdfskill
The worker prefers the Windows command path %APPDATA%\npm\codex.cmd when available, and falls back to the configured command.
cd C:\path\to\lan-math-solver
python -m venv .venv
.\.venv\Scripts\python.exe -m pip install -r requirements.txt
.\.venv\Scripts\python.exe -m uvicorn app.main:app --host 0.0.0.0 --port 8080The Windows quick start uses port 8080 by default. If you set HOST or PORT in the environment first, run_server.ps1 and the GUI/controller will follow those values instead.
Open:
http://127.0.0.1:8080
For LAN access, open the same port on the machine firewall if needed and browse to:
http://<host-lan-ip>:8080
After installing dependencies:
.\.venv\Scripts\python.exe gui.pyOr double-click launch_gui.bat.
The GUI can start and stop the site, open it in a browser, adjust Codex model/reasoning settings, and show lightweight backend monitoring.
Use Tailscale Serve when you want to reach the site from your own authorized devices without exposing it to the public internet.
- Install Tailscale on the Windows host and on each device that should access the site.
- Sign in to the same tailnet on every device.
- Start the website from the GUI or with Uvicorn on port
8080. - In the GUI, use the Tailscale 私有远程访问 panel to start, stop, open, or refresh Tailscale Serve.
The GUI starts private Serve with the equivalent command:
tailscale serve --bg --https=443 http://127.0.0.1:8080Manual checks:
tailscale status
tailscale serve statusKeep Tailscale Funnel disabled for this project unless you explicitly want a public internet URL. Before regular remote use, change the seeded account passwords.
For Linux deployment behind another reverse proxy or tunnel, use docs/linux-deploy.md. The example files there use generic sample values and a loopback-only listener so they can be adapted safely for a real host.
| Username | Password |
|---|---|
admin |
admin-pass |
teacher2 |
teacher2-pass |
teacher3 |
teacher3-pass |
The admin account can access lightweight monitoring and model-setting endpoints. Normal users can only view their own jobs.
Local runtime data is intentionally ignored by Git:
data/app.dbdata/admin_settings.jsondata/jobs/<job_id>/uploads/data/jobs/<job_id>/prepared/data/jobs/<job_id>/logs/data/jobs/<job_id>/result/answer.pdf
This keeps uploaded screenshots, generated PDFs, logs, sessions, and local settings out of the repository.
- Default model:
gpt-5.5 - Default reasoning effort:
medium - Prepared image max side:
1600 - Prepared JPEG quality:
84 - Worker slots:
3 - Job timeout:
900seconds
Admin settings saved in data/admin_settings.json override the model and reasoning defaults for newly started jobs.
The worker invokes Codex with:
codex exec--json--cd <job_dir>- prompt passed through
stdin
Do not add an output schema requirement. The website only depends on result/answer.pdf existing inside the job directory.
Install dependencies, then run:
.\.venv\Scripts\python.exe -m pytest -qFor manual acceptance, run the GUI or server, submit a real screenshot set, confirm the job progresses through the UI, and verify preview/download once answer.pdf exists.