Skip to content

Development

Daniel Dunn edited this page Apr 23, 2024 · 10 revisions

Dev Info

Code Style

Everything should be formatted with Ruff.

Naming conventions

Everything except JavaScript stuff should be snake_case unless it needs to be compatible with an existing standard.

Starting in 0.80.0, config keys, tag points, and resources will be auto-converted to snake_case.

We use scullery's snake_compat module to automatically convert to camelCase for the JS side, matching the common JS convention.

Pre-commit

Kaithem has a basic pre-commit file. For now it only does fairly trivial stuff like syntax checks, there are no plans to add anything that would be slow.

VSCode Dev

dev_run.py can be your entry point for debug. If you get weird errors, check your debug launch config and make sure it's not overriding the interpreter, because then you would be running outside the virtualenv.

Architecture Notes

  • Lots of stuff still uses the old Mako templates. New stuff should use Jinja2
  • Ideally don't make any new custom pages at all. Use the Dialogs generator API for simple stuff.
  • We are moving to be more plugin based.
  • Serving file resources to users is handled by the Pages plugin
  • Top level global stuff is undesirable because it's outside of the module import/export. Everything should be stored in a module unless it's a raw python plugin.

Debugging

It shouldn't happen, but if things get real messed up, use SIGUSR1 to dump the state of all threads to /dev/shm/ "killall -s USR1 kaithem" works if you have setproctitle.

with GDB

If using GDB python, you may need to use "handle SIG32 nostop" to suppress annoying notifications:

gdb python3 $handle SIG32 nostop $run YOUR_KAITHEM_PY_FILE

Tests

The new unit tests initiative uses pytest. Use the test_run.py file if you want to run them in the debugger.

Goals, Priorities, Architecture

Automated Tests

Right now I think that the biggest weak point of Kaithem is the lack of unit tests. Ideally any function touched should get a test.

As this is a smaller project, I think higher level integration tests make more sense a lot of the time than low level strict per-function tests, especially as there is not a lot of nontrivial algorithms work here, most stuff just sets up state and calls libraries.

Chandler

Random notes:

  • The Chandler Web UI uses camelCase while the python side uses (mostly..) snake_case, the APIs convert.

The code for Chandler is pretty horrifying in places. Specifically anywhere that the web meets the python side.

The first priority in fixing this is that all these little inconsistently named setter functions the web uses to set properties of cues and scenes must go.

They are being replaced with a setSceneProperty function, and anything that needs setter code on scenes and cues is getting replaced with @properties.

As scenes are not exposed to users in a documented API currently, this can be done slowly over time, due to the amount of manual testing needed.

The Widget System

The widgets were originally primarily real widgets like sliders and text boxes. Now most things use the api_widget which just provides an abstract web socket link using the machinery original developed for widgets.

The browser side(after v0.77) can reconnect automatically if disconnected. To ensure that this works, assign your widget an id manually, so that it preserves it's identity across server reboots.

This is especially important for features like the Chandler slideshow view, where the browser might not be accessible for manual reloading.

Style Guide

  • Don't Reinvent Wheels
  • Focus on not breaking stuff, but move old code towards modern best practices.
  • Keep compatibility. Take every opportunity to use existing formats and allow interoperability with existing tools
  • Files over Databases. Assume anything a user manually edits is likely something they want to version control.
  • Pay very strong attention to unnecessary disk wear. Every single time you write to disk is a potential SD card corruption incident on cheap Pi cards.
  • Any code that deals with external hardware must auto-reconnect. Remember this is meant to run for years unattended.
  • This is not webscale. This runs on Raspberry Pis on a LAN.
  • It doesn't need to handle a million requests a minute. If the function is slow, try to give it a cache and move on.
  • This is not a minimalist project, but random utilities that don't really benefit at all from integration, really shouldn't be integrated.