Repository navigation
Migrate legacy constants from JSON-as-data to spec + code generation #181
Description
Overview
Five constant modules (file_formats, licenses, content_kinds, format_presets, languages) are hand-written Python that loads JSON from le_utils/resources/, and the two have to be kept in sync by hand. The JSON files were meant to make these constants available to JS too, but they were never published in the kolibri-constants npm package. They should move to spec/ files built by scripts/generate_from_specs.py, like the repo's other constants and schemas, which already reach JS that way. Studio could then delete deploy/generatejsconstantfiles.py, and Studio and Kolibri could import these constants from kolibri-constants. The Python API stays unchanged, except where an existing value is wrong.
Scope
- Migrate
file_formats,licenses,content_kinds,format_presetsandlanguagesto generated modules. - Remove
le_utils/resources/from the package; keeple_utils/resources/languagelookup.jsonin the repo as a symlink to its spec file, so external links still resolve. - Excluded: switching Studio and Kolibri to the npm package (follow-up in those repos).
Guidance
make buildregenerates the Python and JS fromspec/;make testruns the suite.- Generated JS follows the existing
kolibri-constantsmodules: a default export mapping constant names to values (js/Modalities.js), with extra data as named exports (SCHEMAinjs/CompletionCriteria.js). - Studio's generator shows which data Studio's frontend reads from these modules: https://github.com/learningequality/studio/blob/8ccaaa60efd1c07b220aefce5a307e4791345111/deploy/generatejsconstantfiles.py
Strategy
- Migrations land one at a time: Add namedtuple spec support and migrate file_formats.py #182 (generator support and file_formats), then Migrate licenses.py to spec + code generation #183, Migrate content_kinds.py to spec + code generation #184, Migrate format_presets.py to spec + code generation #185, Migrate languages.py to spec + code generation #186, Final cleanup after constants migration #187.
- Constant names and
choiceslabels stay as they are. They can't be derived from ids (HTML5 = "zip",CC_BY = "CC BY",(MP4, "MP4 Video")). - Generated lists keep their current order:
RENDERABLE_PRESETS_ORDERderives bitmask positions that are already saved from the order ofPRESETLIST. - Each correction to a wrong value is listed in
CHANGELOG.md.
Testing Requirements
- Add namedtuple spec support and migrate file_formats.py #182 adds a test that pins the public Python API of the five modules as it is before migration.
- Every migration keeps that test passing; a correction updates the pinned value in the same PR.
Acceptance Criteria
-
file_formats,licenses,content_kinds,format_presetsandlanguagesare generated fromspec/, and nothing underle_utils/constants/readsle_utils/resources/. - Each of those modules is importable as
kolibri-constants/<Module>. - The pinned-API test passes, and
CHANGELOG.mdlists every value that changed. - The built
le-utilswheel contains noresources/JSON, andle_utils/resources/languagelookup.jsonremains in the repo as a symlink to its spec file.
AI usage
I chose the scope, the one-at-a-time order, the rule that only correctness fixes may break the API, and the JS conventions. Claude Code checked the earlier issue text against main and against Studio, Kolibri and ricecooker, then drafted the sections for my edits.
Activity