A playful Python toolkit for creative coding and small games.
Project description
Gummy Snake
Gummy Snake is a playful Python toolkit for creative coding and small games. It is for people who want to sketch with code: draw shapes, animate motion, react to input, load sprites, play with pixels, and build visual toys without first building a full app.
The public API is Python-first. Function names use snake_case, sketches are
ordinary Python files, and the renderer is powered by the packaged Rust canvas
runtime.
Install
pip install gummy-snake
Published wheels include the required Rust gummy_canvas canvas runtime. Source
or editable installs must build that PyO3 module; there is no Python renderer
fallback for canvas-owned behavior.
Install optional media helpers when you need camera, video, or sound-related extras:
pip install "gummy-snake[media]"
First Sketch
Create a file named circle_sketch.py:
import gummysnake as gs
@gs.setup
def setup() -> None:
gs.create_canvas(400, 300)
gs.no_stroke()
@gs.draw
def draw() -> None:
gs.background(245)
gs.fill(255, 90, 90)
gs.circle(200, 150, 100)
gs.run()
Run it:
python circle_sketch.py
For repeatable scripts, use a bounded headless render:
gs.run(headless=True, max_frames=1)
Callbacks can also be async def, which is useful with async-compatible asset
helpers:
image = None
@gs.preload
async def preload() -> None:
global image
image = await gs.load_image_async("sprite.png")
What You Can Make
- 2D drawings with shapes, curves, color, transforms, and blend modes.
- Animated sketches using the familiar
setup()anddraw()lifecycle. - Decorator-based sketches, async-compatible callbacks, and object-oriented
Sketchsubclasses. - Image and pixel experiments, including canvas export.
- Text, font measurement, and accessibility descriptions.
- Interactive sketches with mouse, keyboard, and touch state when native window support is available.
- Software 3D sketches with primitives, lights, materials, models, textures, and shader objects on the current Rust-backed software 3D path.
- Small games and visual toys using the examples as starting points.
Loaded images, models/meshes, and sounds keep Rust-managed asset handles behind
friendly Python wrappers. This is intentional for performance: bulk asset bytes,
geometry arrays, parsing, export, and metadata extraction should stay in the
Rust canvas runtime so sketches avoid repeated Python object materialization and
per-element loops. Normal load_image(); image(...) sprite drawing can stay on
the fast renderer path, model projection/export can use Rust-owned geometry
without first creating Python Vec3 objects, and loaded sounds keep their bytes
and duration metadata in CanvasSound until user code asks for Python bytes.
Image-local resize, mask, filter, crop/copy, and alpha compositing delegate
bulk byte work to the Rust canvas runtime while keeping the Python Image
API and version semantics.
For pixel effects, load_pixels() returns a list-based pixel buffer and
load_pixel_bytes() provides a bytes readback path; update_pixels() accepts
lists and buffer-like inputs such as bytes, bytearray, and memoryview.
Small canvas get() and set() region operations use Rust region calls instead
of reconstructing the full canvas as a Python image.
For dense drawing loops, gs.fast() returns a frame-local facade that keeps
public style/transform state while reducing global-mode dispatch overhead.
Opt-in enable_performance_diagnostics() counters can identify readback, pixel
conversion, upload, texture cache, and CPU compositing fallback paths.
Learn More
For Contributors
This repository uses uv for Python commands:
uv sync --dev
uv run ruff check .
uv run mypy src
uv run pytest
The canvas runtime is a required PyO3 module for development/source installs:
uvx maturin develop --manifest-path crates/gummy_canvas/Cargo.toml --features extension-module
The refactored Python package is split by responsibility: public API modules in
src/gummysnake/api/, SketchContext mixins in src/gummysnake/_context/,
lifecycle code in src/gummysnake/sketch/, enum-backed constants in
src/gummysnake/constants/, and thin canvas backend/renderer facades over the
implementation modules in src/gummysnake/backend/_canvas/.
The contributor documentation explains the architecture, lifecycle, testing workflow, and release shape in more detail:
- Contributor guide
- Architecture
- Backend and renderer boundaries
- Runtime model
- Runtime diagnostics
- Build capabilities
- API performance policy
- Testing and CI
Performance benchmarks are opt-in:
uv run pytest tests/benchmark/test_canvas_backend_perf.py --run-benchmarks
uv run pytest tests/benchmark/test_api_overhead_perf.py --run-benchmarks
uv run pytest tests/benchmark/test_image_pipeline_perf.py --run-benchmarks
uv run pytest tests/benchmark/test_model_export_perf.py --run-benchmarks
uv run pytest tests/benchmark/test_webgl_3d_perf.py --run-benchmarks
Canvas benchmark scenarios are expected to average at least 120 FPS. Failures
below that floor are intentional optimization signals. Model export benchmarks
use a memory budget for streaming OBJ/STL output. Machine-specific baseline
snapshots live in tests/benchmark/baselines/.
Long-running resource lifecycle checks are also opt-in:
uv run pytest tests/stress --run-stress -q -s
Compatibility
Gummy Snake keeps the sketch lifecycle familiar, but it is not a browser port. It does not include DOM helpers, browser-only APIs, JavaScript aliases, or a Pillow/Pyglet/Python renderer fallback. Unsupported features raise explicit package errors so sketches fail clearly.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file gummy_snake-0.5.0.tar.gz.
File metadata
- Download URL: gummy_snake-0.5.0.tar.gz
- Upload date:
- Size: 174.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
130726e23babb37c4f7abff2fbaf5ef64226daeb8626a4f70a3d6c317a2a38de
|
|
| MD5 |
849dcf6427cc02d8d82ee60170bd3234
|
|
| BLAKE2b-256 |
c4ec293ee4c61a7729f85050fdb929adfdf97b8fbb5a1402be2dbe48236861ca
|
Provenance
The following attestation bundles were made for gummy_snake-0.5.0.tar.gz:
Publisher:
publish.yml on JonathanHHenson/gummy_snake
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
gummy_snake-0.5.0.tar.gz -
Subject digest:
130726e23babb37c4f7abff2fbaf5ef64226daeb8626a4f70a3d6c317a2a38de - Sigstore transparency entry: 1898377437
- Sigstore integration time:
-
Permalink:
JonathanHHenson/gummy_snake@fdccc6e51b3a2deff8470483c567f6cdaf147e7d -
Branch / Tag:
refs/tags/v0.5.0 - Owner: https://github.com/JonathanHHenson
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@fdccc6e51b3a2deff8470483c567f6cdaf147e7d -
Trigger Event:
push
-
Statement type:
File details
Details for the file gummy_snake-0.5.0-cp312-cp312-win_amd64.whl.
File metadata
- Download URL: gummy_snake-0.5.0-cp312-cp312-win_amd64.whl
- Upload date:
- Size: 3.0 MB
- Tags: CPython 3.12, Windows x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3d7b6e0aa37bbe4520187a82de000870f4c277975727df5ea02051560f3aba08
|
|
| MD5 |
1757cfc2289334084d674b80c3355aed
|
|
| BLAKE2b-256 |
ea03642f558967f2472530d66b006b76bcddb0b7f1df9103e9d497c89464b281
|
Provenance
The following attestation bundles were made for gummy_snake-0.5.0-cp312-cp312-win_amd64.whl:
Publisher:
publish.yml on JonathanHHenson/gummy_snake
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
gummy_snake-0.5.0-cp312-cp312-win_amd64.whl -
Subject digest:
3d7b6e0aa37bbe4520187a82de000870f4c277975727df5ea02051560f3aba08 - Sigstore transparency entry: 1898377589
- Sigstore integration time:
-
Permalink:
JonathanHHenson/gummy_snake@fdccc6e51b3a2deff8470483c567f6cdaf147e7d -
Branch / Tag:
refs/tags/v0.5.0 - Owner: https://github.com/JonathanHHenson
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@fdccc6e51b3a2deff8470483c567f6cdaf147e7d -
Trigger Event:
push
-
Statement type:
File details
Details for the file gummy_snake-0.5.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.
File metadata
- Download URL: gummy_snake-0.5.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
- Upload date:
- Size: 4.3 MB
- Tags: CPython 3.12, manylinux: glibc 2.17+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5c825885c3d99c9e6a095ba6b9c0098ec97011867a001a2e6fbe78ca577eec6f
|
|
| MD5 |
58b40d0412defc9042fc22ffd4ea74cb
|
|
| BLAKE2b-256 |
d4c7da2cb47b14883afb36084d54a0886a3597b10dd0196923ed2b6334a472af
|
Provenance
The following attestation bundles were made for gummy_snake-0.5.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:
Publisher:
publish.yml on JonathanHHenson/gummy_snake
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
gummy_snake-0.5.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl -
Subject digest:
5c825885c3d99c9e6a095ba6b9c0098ec97011867a001a2e6fbe78ca577eec6f - Sigstore transparency entry: 1898377966
- Sigstore integration time:
-
Permalink:
JonathanHHenson/gummy_snake@fdccc6e51b3a2deff8470483c567f6cdaf147e7d -
Branch / Tag:
refs/tags/v0.5.0 - Owner: https://github.com/JonathanHHenson
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@fdccc6e51b3a2deff8470483c567f6cdaf147e7d -
Trigger Event:
push
-
Statement type:
File details
Details for the file gummy_snake-0.5.0-cp312-cp312-macosx_11_0_arm64.whl.
File metadata
- Download URL: gummy_snake-0.5.0-cp312-cp312-macosx_11_0_arm64.whl
- Upload date:
- Size: 2.6 MB
- Tags: CPython 3.12, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8bb0ef7f43115f4646c43bbff2d1561fac381e57028bc1a59b7e691d019a687d
|
|
| MD5 |
6f4bf839a56debaa4e99e46e2ef76654
|
|
| BLAKE2b-256 |
39f7ff10a66f949101bf65169df644cd1540ea18b8703738dc4d076fbeb47a7e
|
Provenance
The following attestation bundles were made for gummy_snake-0.5.0-cp312-cp312-macosx_11_0_arm64.whl:
Publisher:
publish.yml on JonathanHHenson/gummy_snake
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
gummy_snake-0.5.0-cp312-cp312-macosx_11_0_arm64.whl -
Subject digest:
8bb0ef7f43115f4646c43bbff2d1561fac381e57028bc1a59b7e691d019a687d - Sigstore transparency entry: 1898377708
- Sigstore integration time:
-
Permalink:
JonathanHHenson/gummy_snake@fdccc6e51b3a2deff8470483c567f6cdaf147e7d -
Branch / Tag:
refs/tags/v0.5.0 - Owner: https://github.com/JonathanHHenson
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@fdccc6e51b3a2deff8470483c567f6cdaf147e7d -
Trigger Event:
push
-
Statement type:
File details
Details for the file gummy_snake-0.5.0-cp312-cp312-macosx_10_12_x86_64.whl.
File metadata
- Download URL: gummy_snake-0.5.0-cp312-cp312-macosx_10_12_x86_64.whl
- Upload date:
- Size: 2.6 MB
- Tags: CPython 3.12, macOS 10.12+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8db6040cfcf7a491dc52d0ed1e76d477069da20883fc90293b453fba94bfca81
|
|
| MD5 |
163c5e77d6e9658e07abce9cfb3bea2b
|
|
| BLAKE2b-256 |
b5aa49c91da68eac893727016ec5385df7f3f7bd07d8d3acc2f44bb168923405
|
Provenance
The following attestation bundles were made for gummy_snake-0.5.0-cp312-cp312-macosx_10_12_x86_64.whl:
Publisher:
publish.yml on JonathanHHenson/gummy_snake
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
gummy_snake-0.5.0-cp312-cp312-macosx_10_12_x86_64.whl -
Subject digest:
8db6040cfcf7a491dc52d0ed1e76d477069da20883fc90293b453fba94bfca81 - Sigstore transparency entry: 1898377831
- Sigstore integration time:
-
Permalink:
JonathanHHenson/gummy_snake@fdccc6e51b3a2deff8470483c567f6cdaf147e7d -
Branch / Tag:
refs/tags/v0.5.0 - Owner: https://github.com/JonathanHHenson
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@fdccc6e51b3a2deff8470483c567f6cdaf147e7d -
Trigger Event:
push
-
Statement type: