Python, YAML or KM
A Kewos module is written in code, in YAML or in KM. This is not a starter format you outgrow: all three call the same kernel functions, and produce the same tables, the same API and the same screens.
| For whom | The shape | |
|---|---|---|
| Python | you program | modules, classes, everything Python can do |
| YAML | you describe | a tree of files, one per subject |
| KM | you do not program | one file, read from top to bottom |
KM and YAML have exactly the same reach, and that is a decision rather than an accident: what one can describe, the other can, and a test refuses to let them drift apart. See Writing in KM.
Every step of this walkthrough shows the formats side by side, in tabs. The choice stays yours, per module.
Translate, do not reinvent
The declarative format has no engine of its own. A loader reads the YAML and calls
register_model, apply_module_acls, register_view_spec, register_state_machine: the same
ones your code would have called.
That is the property that matters, because it bounds the risk. There is no second system to secure, audit and keep up to date: there is a translator.
What separates them
| Python | YAML | |
|---|---|---|
| Models, fields, relations | yes | yes |
| The eight view kinds | yes | yes |
| Permissions, record and field rules | yes | yes |
| State machine, actions, triggers | yes | yes |
| Translations, demo data | yes | yes |
| Search, tags, model image | yes | yes |
| Computation | a function, anything the language allows | an expression on an allowlist |
| Calling an external service | yes | no |
| Reading a file, a format, a library | yes | no |
| Calling a language model | yes | not yet, see AI |
The line that matters is the computation one. A declarative expression can be read back, checked, and cannot execute anything at all; that is exactly why it is less powerful.
How to choose
Take YAML when you are describing data, screens, rights and states. That covers most business modules, and it spares you a software release cycle.
Take code as soon as you need a computation the restricted language cannot express, a call to an external service, a file format, or fine-grained tests on a business rule.
And nothing forces a once-and-for-all choice: both live in the same installation, see each other through events and registries, and deploy the same way.