Skip to main content

Tensnap Python Bindings

Python bindings for the TenSnap protocol v0.3 runtime.

Installation

pip install tensnap

Quick Start

import asyncio

from tensnap import (
    SimulationScenario,
    agent,
    agent_layer,
    chart,
    env,
    grid_layer,
    params,
)


@agent(x="position[0]", y="position[1]")
class Bird:
    def __init__(self, bird_id: int, position: tuple[int, int]):
        self.id = bird_id
        self.position = position


@grid_layer()
@agent_layer("birds")
@env(id="main")
class Aviary:
    def __init__(self):
        self.width = 20
        self.height = 10
        self.birds = [Bird(1, (2, 3)), Bird(2, (4, 5))]

    def step(self) -> None:
        for bird in self.birds:
            x, y = bird.position
            bird.position = (x + 1, y)

    @chart("population", "Population")
    def population(self) -> int:
        return len(self.birds)


@params(include=["speed"])
class Config:
    speed = 1.0


scenario = SimulationScenario(port=8765)
model = Aviary()
config = Config()

scenario.add_all(model)
scenario.add_all(config)


async def main() -> None:
    await scenario.register_model_handler(model_step=model.step)
    await scenario.run()


if __name__ == "__main__":
    asyncio.run(main())

tensnap.bindings is the unified attach/readback surface for Python bindings. Use it for decorators such as env, grid_layer, and agent_layer, and for readback helpers such as environment_binding, layer_bindings, and bindings.

Layer and item binding fields now support these common forms:

  • omitted fields, None, or auto() for one-time same-name discovery from the class or initialized instance
  • selector strings such as x="pos[0]" or item_iterable_projector="agents" when the source path differs from the output field or layer id
  • literal values such as coord_offset="float" or icon="circle"; arbitrary strings still default to selectors unless they match a known literal value, CSS-like string such as "#3498db", or JSON-like string
  • explicit helpers such as attr("pos[0]"), value("red"), auto(), and skip()
  • direct callables such as size=lambda agent: agent.radius

None/auto() field discovery is resolved once when instances initialize or when layer_bindings(instance) materializes an instance-specific binding, so fields assigned in __init__ are picked up without scanning during projection:

from tensnap import agent, agent_layer, grid_layer, value


@agent(x="position[0]", y="position[1]", color=value("red"))
class Bird:
    def __init__(self, bird_id: int, position: tuple[int, int]):
        self.id = bird_id
        self.position = position


@grid_layer()
@agent_layer("birds")
class Aviary:
    def __init__(self):
        self.width = 20
        self.height = 10
        self.birds = [Bird(1, (2, 3))]

SimulationScenario registers the renderer-driven built-in actions start, step, and reset during construction. The initial synchronized state is always time 0, and the first simulated tick emitted by start or step is 1. For most targets, use scenario.add_all(target) to register available environment/layer, chart, and action bindings. Parameters are opt-in with @params(...) or an explicit config.

register_model_handler(model_init=None, model_step=None, model_reset=None) lets you keep reset distinct from init. If model_reset is omitted, the default handler falls back to model_init.

Reset reconciles declarations with strict CRUD, deletes the previous agent set before creating reset state, clears chart history, and preserves stable trajectory configuration so the renderer can apply on_reset.

add_all(..., dry_run=True) and the targeted add_* dry-run modes report registry ids without mutating the scenario. Mesa lifecycle helpers use this to unregister and rebuild model-owned registrations cleanly.

Trajectory layers expose length, width, color, z_index, on_agent_delete, on_state_sync, and on_reset as first-class decorator arguments. See the Python API reference for their lifecycle semantics.

Model-owned mappings, matrices, and indexed columns can use map_agent_layer, matrix_agent_layer, and indexed_agent_layer without creating visual agent wrappers. Built-in layer metadata goes in direct decorator keywords; custom metadata goes in metadata={...}. Source layers also accept direct color, icon, and size shortcuts. See the Python API reference for the conflict rules, projection forms, and restore behavior.

Monitors use explicit create/update/delete protocol operations. Scene checkpoint callbacks work with model data only: provide both checkpoint_capture and checkpoint_restore, and the binding infers the wire encoding. Pass restore=None to @scene_restore(...) for checkpoint-only models. Every connection starts with a simulator_info handshake containing stable model identity, per-instance identity, schema compatibility, and declared capabilities.

For Mesa models, prefer BoundModelReinitializer from tensnap or tensnap.bindings.lifecycle. Use bind_kwargs(...) to expose constructor keyword arguments as resettable parameters when needed. When a constructor kwarg and a model-owned parameter publish the same source field during register_model(), the model parameter keeps UI ownership and the reinitializer aliases its reset value from the model field instead of registering a duplicate kwarg parameter. configure_reinit(...) now applies the default Mesa cleanup automatically when no explicit cleanup callback is provided.

Examples

Example simulations are located in the repository root:

  • examples/python/ - Standard Python examples (flock, hk, sirs)
  • examples/python_mesa/ - Mesa-based examples (cgol, sugarscape, mushroom)

Documentation

Full documentation: https://github.com/billstark001/tensnap

License

See LICENSE file in the repository root.

Metadata

Release files for tensnap 0.3.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for tensnap 0.3.2
File Size Uploaded
tensnap-0.3.2.tar.gz 124.9 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for tensnap 0.3.2
File Interpreter ABI Platform
tensnap-0.3.2-py3-none-any.whl Python 3 none any Details

Total release size: 235.6 kB

Release files / tensnap-0.3.2.tar.gz

Download URL tensnap-0.3.2.tar.gz
Size 124.9 kB
Tags Source
SHA-256 checksum
How to use checksums
6f97750eb8b11d84ac083e0bd940833f2834416a9f000e5526f217d5901aedca
BLAKE2b-256 checksum
How to use checksums
31d210d0a8a7b8653a6effdfc37517ae6bb4f87e71760aa7a66e5610e0989968
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 Oct 4, 2026.

Transparency log

Release files / tensnap-0.3.2-py3-none-any.whl

Download URL tensnap-0.3.2-py3-none-any.whl
Size 110.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
13adbe952711bb95ff94e54425e3b04178fb70ca06013889bb97513b3ab1acf9
BLAKE2b-256 checksum
How to use checksums
b82c58fdf792e6fb9bbf9bf5d252fba787defc4e8147014f0b2ae1f0da9a53ec
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 Oct 4, 2026.

Transparency log

Release history Release notifications | RSS feed

0.3.3

2 release files

This release

0.3.2 This release

2 release files

0.3.1

2 release files

0.3.0

2 release files

0.2.4

2 release files

0.2.3

2 release files

0.2.2

2 release files

0.2.1

2 release files

0.2.0

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page