Guidance for AI coding agents working in this repository.
uv sync --group dev # install (creates .venv and installs all dev dependencies)
uv run --group test pytest # run all tests
uv run --group test pytest tests/test_files.py # run a single test file
uv run --group test pytest -k 'test_something' # filter by test name
uvx prek run --all-files # lint (the ONLY way to run linting)System dependencies: ffmpeg and poppler-utils.
- Linting: Always use
uvx prek run --all-files. Never run ruff, black, flake8, or other tools directly. - Line length: 160 characters, enforced by prek/ruff.
- New file types require exactly two changes: (1) a conversion handler in
convert.py, (2) a metadata extractor inextract_metadata.py. That's it. Do NOT touchclasses/files.pyorclasses/nodes.py— the existing File/Node subclasses there are legacy backwards-compatibility APIs that are NOT needed for new file types. The pipeline infers kinds and presets automatically. - Test placement: Pipeline tests go in
tests/pipeline/— add to existing files liketest_convert.pyandtest_extract_metadata.py. Do not create new test files. - Validation logic: Each handler implements only the validation its spec requires. Do not copy validation from other handlers (e.g., do not add HTML body parsing or empty-body checks unless the spec explicitly requires them).
- le_utils constants: Always verify constants exist by running
python3 -c "from le_utils.constants import file_formats, format_presets; print(file_formats.CONSTANT_NAME); print(format_presets.CONSTANT_NAME)". Names are often non-obvious (e.g.,file_formats.HTML5_ARTICLEfor kpub,format_presets.KPUB_ZIPnotformat_presets.KPUB).
Ricecooker converts educational content into Kolibri content channels and uploads to Kolibri Studio. Chef scripts subclass SushiChef, build a node/file tree, and call main().
utils/pipeline/: File processing pipeline — transfer → convert → extract_metadata. Reference architecture for new code.classes/nodes.py: Node tree (ChannelNode,TopicNode,ContentNodesubclasses) — legacy, do not add new subclassesclasses/files.py: File classes (DownloadFilesubclasses) — legacy, do not add new subclasseschefs.py:SushiChefbase classle_utils: External package providing content model constants (file_formats,format_presets,content_kinds,licenses)