Skip to main content

SignalSafe TreeSpec wire contract for Python: models, parsing, lint, and patch helpers.

Project description

signalsafe-tree-spec (Python)

Python implementation of the TreeSpec wire contract: Pydantic models, parsing, lint, patch helpers, and constants. Backend counterpart to @signalsafe/tree-spec on npm.

PyPI distribution name signalsafe-tree-spec
Import path deliveryplus_tree_spec (stable; historical name)
GitHub SignalSafeSoftware/tree-spec-python
Python 3.12+ (requires-python >=3.12,<4.0)
Runtime dependency Pydantic v2 (pydantic>=2.11.3,<3)

License: MIT — see LICENSE. See SECURITY.md for vulnerability reporting.

What this package does

  • Validate and parse TreeSpec wire JSON into typed Pydantic models (TreeSpec, Node, Transition, …).
  • Lint wire payloads (lint_tree_spec) with structured issues.
  • Build wire documents programmatically (TreeSpecBuilder).
  • Apply JSON patches to wire dicts (apply_patch_to_spec_dict).
  • Expose wire constants (END_NODE_ID, TREESPEC_WIRE_VERSION).

See docs/compatibility.md for how unknown JSON fields are handled (extra="ignore") and how that compares to TypeScript compile/decompile.

What this package does not do

  • HTTP APIs, authentication, persistence, or training UI.
  • Scenario simulation (use @signalsafe/simulator-core / simulator-react in TypeScript stacks).
  • Graph editor UI (use @signalsafe/tree-spec-editor-* packages).
  • General sandboxing or authorization — contract validation only; host apps decide trust and access control.

Install

pip install signalsafe-tree-spec

Development (this repo uses uv):

uv sync --extra dev
uv run pytest

Distribution name vs import path

pip install signalsafe-tree-spec
import deliveryplus_tree_spec
from deliveryplus_tree_spec import TreeSpec, lint_tree_spec, TreeSpecBuilder

The PyPI name (signalsafe-tree-spec) differs from the import path (deliveryplus_tree_spec) for backward compatibility with existing backends.

Quick start

from deliveryplus_tree_spec import (
    END_NODE_ID,
    TREESPEC_WIRE_VERSION,
    TreeSpec,
    TreeSpecBuilder,
    lint_tree_spec,
)

wire = {
    "wire_version": TREESPEC_WIRE_VERSION,
    "start_node": "start",
    "nodes": {
        "start": {
            "type": "prompt",
            "prompt": "Verify the sender before clicking?",
            "choices": [{"id": "inspect", "label": "Inspect sender"}],
        }
    },
    "transitions": [
        {"from": ["start", "inspect"], "to": END_NODE_ID, "outcome": "safe"},
    ],
}

issues = lint_tree_spec(wire)
assert not issues

spec = TreeSpec.model_validate(wire)
builder = TreeSpecBuilder()
# builder.add_node(...) — see tests/ for full builder flows

Public API

All symbols below are exported from the top-level deliveryplus_tree_spec package:

Category Symbols
Constants END_NODE_ID, TREESPEC_WIRE_VERSION
Models TreeSpec, Node, Transition, Choice, Delta, MicroFeedback, ABMeta, ABVariant, …
Lint lint_tree_spec, TreeSpecIssue
Builder TreeSpecBuilder, TreeSpecError
Patch apply_patch_to_spec_dict, PatchApplyError, PatchDict, ReplacePatch, …

There are no subpath exports — import from deliveryplus_tree_spec only.

Wire contract (high level)

  • wire_version: optional; omit for implicit v1. Constant TREESPEC_WIRE_VERSION documents the current version string.
  • start_node: entry node id.
  • nodes: map of node id → node object (type, prompt, choices or legacy options, optional render_hints).
  • transitions: list of { from: [nodeId, choiceId], to, outcome? }. Terminal transitions target END_NODE_ID and require outcome.
  • _meta: optional tree-level metadata (for example graph-editor viewport persisted by editor packages).

Legacy payloads may use options instead of choices and legacy terminal ids; the TypeScript package normalizes these on compile/decompile. Python lint validates the wire shape your backend accepts.

Python / TypeScript parity

Concern Python (tree-spec-python) TypeScript (@signalsafe/tree-spec)
Wire models & lint Pydantic models, lint_tree_spec TreeSpecWire, lintTreeSpecWire
Authoring graph compile compileTreeSpec / decompileTreeSpec
Cross-language fixtures Share JSON fixtures in your product repo or CI Same

Keep fixture JSON in sync when changing wire rules in either language. Full compile/decompile parity lives in TypeScript today; Python focuses on validation, lint, builder, and patch flows used by backends.

Development

uv sync --extra dev
uv run pytest
uv run flake8 .
uv run python -m build   # wheel/sdist smoke — full artifact tests in Batch 6

Security

See SECURITY.md. TreeSpec parsing is contract validation, not a sandbox. Validate and authorize TreeSpec JSON in your application layer before treating content as trusted.

Changelog and releases

Related packages

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

signalsafe_tree_spec-0.1.2.tar.gz (12.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

signalsafe_tree_spec-0.1.2-py3-none-any.whl (12.7 kB view details)

Uploaded Python 3

File details

Details for the file signalsafe_tree_spec-0.1.2.tar.gz.

File metadata

  • Download URL: signalsafe_tree_spec-0.1.2.tar.gz
  • Upload date:
  • Size: 12.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.13

File hashes

Hashes for signalsafe_tree_spec-0.1.2.tar.gz
Algorithm Hash digest
SHA256 e31ffa7dc00e1f1117fd4d5f766d18611fbde17cdaa4de2265286d1012ed9f9d
MD5 48d51d2a6d2489ee7766890765c720d7
BLAKE2b-256 e8d2560e6d124f493cd329719a3efdfa2e23e48db1d9bd3936ddb9a8835343fe

See more details on using hashes here.

Provenance

The following attestation bundles were made for signalsafe_tree_spec-0.1.2.tar.gz:

Publisher: ci.yml on SignalSafeSoftware/tree-spec-python

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file signalsafe_tree_spec-0.1.2-py3-none-any.whl.

File metadata

File hashes

Hashes for signalsafe_tree_spec-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 071684e7422687bd36dcfc9fab2d72708f26fa9d2ee5df2e5de56cffdd3e3722
MD5 3850bd4d4653ff9fb446cddd9a10050f
BLAKE2b-256 7e42f089909e3e350a51cce46668e990e7ea0045cfb47d08825d24d780168a56

See more details on using hashes here.

Provenance

The following attestation bundles were made for signalsafe_tree_spec-0.1.2-py3-none-any.whl:

Publisher: ci.yml on SignalSafeSoftware/tree-spec-python

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page