ghee for Python
pip install ghee-render: one package, two surfaces. It embeds the
ghee renderer, and it provides the
Python sugar for writing a
procedural scene.
Build the wheel yourself with maturin:
maturin build --release --compatibility linux
Use
To use the ghee renderer:
import ghee
h = ghee.open(
"scene.json", # a path, the JSON text of a scene, or a dict
output="st7789", # a driver name, "kms", or None for headless
opts={"width": 240, "height": 240, "backlight": 26},
width=None, height=None, # a headless size, a panel states its own
fps=30, # pace cap, None runs free
stats=8090, # console port, ("0.0.0.0", 8090) binds elsewhere
stream_max=None, # h264 stream cap: pixels, or a fraction of the render size
verbose=False,
timestep=None, # pin time to frame*S for a reproducible render
)
h.set_param("gain", 1.5) # a scene param
h.set_param("snap", 1.0, pass_="hold") # the param of one pass
h.set_param("hold.snap", 1.0) # the same param, dotted
h.feed("level", bars) # bytes, bytearray, memoryview, array, numpy, numbers
tick = h.frame() # {"frame": 12, "time": 0.4, "dt": 0.0166}
tick = h.skip() # the same tick, with no draw
h.size # (width, height)
h.components # 3 for RGB, 4 for RGBA
h.pixels() # the last frame, row-major (height, width, components)
h.close() # also a context manager
What each call does
set_param sets a live uniform, no recompile. A bare name is the scene
param, else the param of the first pass that declares it.
feed holds the data for one declared array, and the next frame consumes
it once. A uint8 buffer reaches the texture as byte / 255, a float32
buffer passes through. An array keeps its texture data until a feed
changes it.
frame draws and hands the frame to the output. time is the wall clock
since the first frame, dt is the measured frame period, and timestep
pins both to frame * S.
skip takes the tick and draws nothing, the panel keeps its last frame.
stats serves the console on 127.0.0.1, and a (host, port) pair binds
it elsewhere. Anyone who reaches the port can change params, so bind beyond
loopback only on a network you trust.
docs/http.md
holds the API. This console shows the host's own scene, param changes
apply, and scene switching and recompiles are refused. The video stream
advances with frame(): viewers see a new frame only when the host draws
one.
Rules
ghee is thread-affine: open a handle on one thread and use it on that same thread, a call from another thread raises RuntimeError.
A scene, GLSL or param error raises ValueError, a driver or system error raises RuntimeError.
frame() releases the GIL, so the host's other threads run while it
renders.
Python scenes
The shim is used to write a procedural scene. A PEP 723 scene should
declare ghee-render inline:
#!/usr/bin/env -S uv run --script
# /// script
# dependencies = ["ghee-render"]
# ///
The shim gives:
ghee.Scene / Pass / Param / ArrayInput / Channel: build the sceneghee.Arg,ghee.args([...]): argument declarations, and the-- --helpanswer@ghee.feed("name"): the values of a named array, each tick. A uint8 buffer,bytesor a numpy uint8 array@ghee.tick: a hook for each tick, withghee.set_param(name, value)andghee.skip()ghee.run(scene): the handshake, then the tick loop
Direct mode
The same scene file runs two ways. When ghee starts it, as ghee render spectrum.py or from a scenes directory, run() feeds ghee over the
wire protocol.
When you run the file itself, run() opens the embedded renderer and
renders directly:
./spectrum.py --output kms --frames 300
./spectrum.py --bins 32 --output none --size 320x240 --frames 1
ghee sets GHEE_WIRE=1 in every scene process it starts, and run()
tells the two apart by it.
The scene takes its own arguments first, then these:
--output NAME: a driver name,kms, ornonefor a headless render (defaultkms)--size WxH: the render size. A display or a panel states its own--fps N,--stats PORT,--timestep S: asghee rendertakes them--frames N: 0 runs until SIGINT or SIGTERM (default 0)
The feeds, the hooks and ghee.skip() work the same. The tick keeps its
wire shape, with params empty. If one of your own arguments collides with
these names, argparse says so.
What the wire carries
The wire suits small per-frame data. Megabyte-scale data costs a
serialization and two copies for each frame, and on a small Pi that shows
up as a low frame rate. A data-heavy host takes ghee.open instead: the
renderer in the same process, no pipe.
Metadata
Release files for ghee-render 0.4.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| ghee_render-0.4.0.tar.gz | 3.4 MB | Details |
Built distributions (wheels)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| ghee_render-0.4.0-cp39-abi3-manylinux_2_36_aarch64.whl | CPython 3.9 | abi3 | Linux glibc 2.36+ ARM64 | Details |
| ghee_render-0.4.0-cp39-abi3-manylinux_2_35_x86_64.whl | CPython 3.9 | abi3 | Linux glibc 2.35+ x86-64 | Details |
Total release size: 5.3 MB
Release files / ghee_render-0.4.0.tar.gz
| Download URL | ghee_render-0.4.0.tar.gz |
|---|---|
| Size | 3.4 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
f752926de3ab8066cce8678ba1d0a95461c3f3dac1f65d48596aba317309487f
|
|
BLAKE2b-256 checksum How to use checksums |
6396505376e8de3a7e9d5f774aa62039a6950619933501f378ad414ae230bb62
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 7, 2026.
Transparency logRelease files / ghee_render-0.4.0-cp39-abi3-manylinux_2_36_aarch64.whl
| Download URL | ghee_render-0.4.0-cp39-abi3-manylinux_2_36_aarch64.whl |
|---|---|
| Size | 848.8 kB |
| Tags | CPython 3.9 Linux glibc 2.36+ ARM64 abi3 |
|
SHA-256 checksum How to use checksums |
887384ee6bf3966900211cbbd9fdd3b8885b7a99e83dc5c2c1682ccb23a8c3c9
|
|
BLAKE2b-256 checksum How to use checksums |
ba1db28fd91ae37408953103ddcd503ebd118a4c4992e92afef1609f1f9fea29
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 7, 2026.
Transparency logRelease files / ghee_render-0.4.0-cp39-abi3-manylinux_2_35_x86_64.whl
| Download URL | ghee_render-0.4.0-cp39-abi3-manylinux_2_35_x86_64.whl |
|---|---|
| Size | 997.6 kB |
| Tags | CPython 3.9 Linux glibc 2.35+ x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
8af85835764c692f2e155dca18dec6b04e839de1917a074285127ebf5210bd70
|
|
BLAKE2b-256 checksum How to use checksums |
4020e33594eefffa6771cbbba7b26407f5a822319ff2ffbf6f7e3f3d0c706cdb
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 7, 2026.
Transparency log