Skip to content

GUI Frontend

NesiciCoding edited this page Aug 12, 2026 · 1 revision

GUI Frontend

Research into turning the CLI tools into a separate GUI tool — a standalone desktop app that wraps the same engine, for teachers who don't want a terminal at all. This page is deliberately placed at the very tail end of the Roadmap: it builds on everything the phases deliver (above all Phase 5's importable engine and Phase 6's packaging) and changes none of it.

Verdict — highly viable, and unusually cheap. The analysis side is already done. Phase 5 made the profilers one importable engine (analysis.py) with a versioned JSON payload; a GUI is a pure front end over that — one function call per "Analyse", not a port. The real work and the real risk are the surface: choosing a toolkit, packaging a distributable app, and deciding what the UI should be.


Why it's cheap — the engine-fit evidence

The repo already contains most of what a GUI needs; the CLI is proof.

  • One-call entry point. analysis.analyze(text, target_level=..., ...) returns the full report payload — vocabulary bands + typical/coverage, grammar criteria, estimated level, verdict, above-target words. An "Analyse" button is literally one function call; the payload is the ready-made model for the UI.
  • Load once, reuse forever. analysis.Engine (word lists + spaCy + CEFR-J) is designed to be loaded once and shared; a GUI loads it at startup. --watch mode already proves per-text re-profiling is sub-second, so live re-analysis after every keystroke/paste is realistic.
  • Chart data already exists. Every class_profile JSON row now carries the per-student CEFR distribution (per-level counts + percentages) — the GUI's headline visualization (band spreads per essay) renders it with zero derivation.
  • Fully offline-capable. Levels come from the bundled levels.json, definitions from the bundled WordNet (wordnet.json), grammar levels from the bundled CEFR-J profile. The only network dependency (the Free Dictionary API for richer definitions/phonetics) degrades to offline the same way the CLI does.
  • Grammar is optional, not fatal. The CLI already ships grammar_available=False + an install note when spaCy is missing; a GUI can ship "grammar optional" identically — or bundle spaCy for the full experience.
  • Zero risk to the existing toolchain. The GUI is a separate front end over analysis.py/class_profile.py; the CLI code paths, tests, and golden outputs are untouched.

Toolkit options (2026 state)

Toolkit Best for Native look Notes for this project
Tkinter / CustomTkinter Simple desktop tools Partial (ttk) Zero deps — matches the "dependency-free" ethos; right for an MVP (text box + target dropdown + band/verdict pane). Painful for rich output (coloured bands, tables, charts).
PySide6 (Qt) Professional desktop apps Yes (styled) The "real product" choice: tables, rich text, QtCharts, LGPL (safe for closed source). Heavy runtime (~150 MB with the app). The 2026 consensus pick for serious desktop software.
NiceGUI Web-based Python UIs N/A (browser) Pure Python, renders in the browser (local server, auto-opens a tab); trivial forms + ECharts dashboards. Not a true desktop app — a local web server.
Flet (Flutter) Cross-platform apps Yes (adaptive) Modern look, desktop+web from one codebase, but a large Flutter runtime for what is essentially a form + results pane.
Textual Terminal UIs N/A (TUI) Not a GUI, but the cheapest stepping stone: a gorgeous terminal app that reuses the existing colour pretty renderers.

Non-Python shells (Electron/Tauri) would mean a second language for the UI and are not recommended while the engine is pure Python.

Packaging reality

The one thing a GUI can't be is "no install":

  • PyInstaller is the standard freezer (one-dir builds; ~58 MB for bare PySide6, and ~100–150 MB once spaCy + its model + the word lists + the 10 MB wordnet.json ride along). One-file builds are smaller to hand out but slower to start.
  • Per-OS builds — a build matrix per platform (your CI already runs one); macOS notarization and Windows code signing are the standing distribution friction.
  • BeeWare Briefcase is the alternative for native installers, but PyInstaller is the more battle-tested path.

Effort estimates

Step Size Notes
MVP (Tkinter or NiceGUI wrapper over analyze) ~300–500 lines, a day or two Text in → bands, verdict out. The engine does all the work.
Polished app (PySide6: coloured band view, grammar list, deck-export button, class-folder picker + distribution chart) 1–2 weeks The dashboard-shaped features (per-student distributions, band exports) already exist in the payload.
Distribution (PyInstaller + per-OS builds + signing) Ongoing Each OS adds its own friction; worth automating in CI from the start.

Risks & tradeoffs

  • The "no install" story dies for the GUI — a bundled app is ~100–150 MB. The CLI story is untouched (it stays a separate, install-free artifact).
  • A second UI surface to maintain. Tests are CLI-oriented today (mock HTTP, golden outputs); GUI testing is manual or headless (QtTest / pytest-qt).
  • UX is the real unknown. The analysis is deterministic and proven; what a teacher actually wants in a window is not. That argues for a throwaway prototype before committing to a full toolkit.

Recommended sequencing

  1. Phase 6 packaging first — make the engine a real importable/installable vocabkitchen package, so the GUI doesn't depend on cwd or symlink tricks.
  2. Prototype the UX cheaply — a Tkinter/CustomTkinter or NiceGUI shell over analysis.analyze(); validate what the window should show before any polish.
  3. Commit to a toolkit — PySide6 if it's to be a real product, else stay on the prototype toolkit.
  4. Automate distribution — PyInstaller per-OS builds in CI from day one.

See also

  • Roadmap — where this sits: after Phase 6, at the tail end of the plan.
  • RubricMaker Alignment — the web-app sibling this would complement.

Clone this wiki locally