Skip to main content

A JSON-based serialization of SCXML (State Chart XML) for modern tooling, interoperability, and education, with execution engine and trace tools for SCXML/SCML.

Project description

scjson logo

scjson Python Package

This directory contains the Python implementation of scjson, a format for representing SCXML state machines in JSON. The package provides a command line interface and utility functions to convert between .scxml and .scjson files and to validate documents against the project's schema.

The package includes generated Pydantic and dataclass model variants for the schema objects and enumerations in both standard and strict forms.

For current SCJSON representation and converter authority, see the semantic baseline and converter concepts docs: SCJSON-00-CONCEPTS.md and SCJSON-CONV-00-CONCEPTS.md. For language status and parity notes, see docs/COMPATIBILITY.md.

Installation

pip install scjson

You can also install from a checkout of this repository:

cd py && pip install -e .

Source Code - Multi-Language Support

[https://github.com/SoftOboros/scjson/]

  • csharp
  • go
  • java
  • javascript / typescript
  • lua
  • python
  • ruby
  • rust
  • swift

Python Engine — User Guide

For end‑to‑end usage of the Python execution engine (tracing, comparing against a reference, generating vectors, sweeping corpora), see:

  • docs/ENGINE-PY.md (in this repository)

Online: https://github.com/SoftOboros/scjson/blob/main/docs/ENGINE-PY.md

SCION Reference Dependency

Several comparison tests (py/tests/test_exec_compare_advanced.py) and the exec_compare tooling invoke the Node-based SCION runner bundled under tools/scion-runner. Node.js must be able to resolve the SCION packages (scxml, jsdom, and regenerator-runtime) via its module loader. Install them once before running comparisons:

cd tools/scion-runner
npm ci  # or npm install

When running the Python tests or CLI comparisons, ensure node can load these modules (for example by keeping the installation above in place or by adding their location to NODE_PATH). Without the SCION packages, comparisons fall back to the Python engine.

Command Line Usage

After installation the scjson command is available:

# Convert a single file
scjson json path/to/machine.scxml

# Convert back to SCXML
scjson xml path/to/machine.scjson - o path/to/output.scxml

# Validate recursively
scjson validate path/to/dir -r

# Genrate typescript Types
scjson  typescript -o dir/of/output

# Genrate scjson.schema.json
scjson  schema -o dir/of/output

FastAPI example Usage

This is a minimal FastAPI endpoint as an example usage of the SCXMLDocumentHandler class.

import json
from fastapi import FastAPI, Request, HTTPException, Response
from scjson.SCXMLDocumentHandler import SCXMLDocumentHandler

app = FastAPI()
handler = SCXMLDocumentHandler(schema_path=None)

# In-memory store for demo
store = {}

@app.get("/xml/{slug}")
async def get_xml(slug: str):
    """Return the SCXML document as XML."""
    data = store.get(slug)
    if not data:
        raise HTTPException(status_code=404, detail="Document not found")
    xml_str = handler.json_to_xml(json.dumps(data))
    return Response(content=xml_str, media_type="application/xml")

@app.post("/xml/{slug}")
async def post_xml(slug: str, request: Request):
    """Accept an SCXML document and convert it to scjson."""
    xml_bytes = await request.body()
    xml_str = xml_bytes.decode("utf-8")
    json_str = handler.xml_to_json(xml_str)
    data = json.loads(json_str)
    data.setdefault("name", slug)
    store[slug] = data
    return data

Importing Objects.

This imports the definitions of individual types. See below for lib variats. Class varaints available for pydantic and dataclasses implementing both the standard and strict xsd variants.

from scjson.pydantic import Scxml, State, Transition, Onentry # etc.

SCJSON Caveats

The SCXML conversion helpers normalize data so it can be stored as JSON. During asdict() serialization the generated dataclasses may contain Decimal values and enumeration instances (e.g. AssignTypeDatatype).

  • Decimal values are converted to floating point numbers.
  • Enum values are stored using their .value string.

These conversions allow the JSON representation to be serialized by json.dumps and then converted back via the _to_dataclass helper.

Known Issues

None at this time.

Operational conformance testing is performed via uber_test.py

/py# python uber_test.py -l python 2>&1 | tee test.log

Note: uber_test.py applies all scxml files in Zhornyak's ScxmlEditor-Tutorial which provides a robest set of scxml test vectors useful for standard compliance verification. This is the only file in the test suite which fails to verify round-trip.

Uber Test Harness

Run across all languages or a single language with alias support:

# All languages detected on PATH
python py/uber_test.py

# Single language (aliases allowed): py, python, js, ts, javascript, rs, rust, swift, java, csharp
python py/uber_test.py -l js
python py/uber_test.py -l swfit   # typo tolerated → swift

# Limit the corpus and treat consensus as warnings only
python py/uber_test.py -l swift -s "Examples/Qt/StopWatch/*.scxml" --consensus-warn
  • -s/--subset filters SCXML files by a glob relative to tutorial/.
  • --consensus-warn downgrades mismatches to warnings when reference languages (Python/JavaScript/Rust) match the canonical structure.
  • The harness normalizes structural differences according to the active converter and compatibility docs to produce actionable diffs and prints a triage line with a recommendation.

Model Variants

The Python package exposes four sets of generated models that mirror the SCJSON schema. They all share the same field names and enumerations, but offer different runtime characteristics.

Enums

Each enumeration represents a restricted string set used by SCXML. The values shown below mirror those defined in the SCJSON schema.

  • AssignTypeDatatype – how the <assign> element manipulates the datamodel. Values: replacechildren, firstchild, lastchild, previoussibling, nextsibling, replace, delete, addattribute.
  • BindingDatatype – determines if datamodel variables are bound early or late during execution.
  • BooleanDatatype – boolean attribute values true or false.
  • ExmodeDatatype – processor execution mode, either lax or strict.
  • HistoryTypeDatatype – type of <history> state: shallow or deep.
  • TransitionTypeDatatype – whether a <transition> is internal or external.

Common Types

Several generated classes share generic helper fields:

  • other_attributes: extension attributes from foreign namespaces. Pydantic model variants use dict[str, Any] so JSON tooling can preserve typed metadata; dataclass variants intentionally use dict[str, str] for XML serialization.
  • other_element: list[object] allowing untyped child nodes from other namespaces to be preserved.
  • content: list[object] used when elements permit mixed or wildcard content.

Model Generation Maintenance

The checked-in generated models are refreshed from the repository checkout with py/gen_models.sh, which applies py/patch_scxml_forward_ref.py and py/patch_other_attributes_any.py after generation. These scripts are repository maintenance tools, not installed runtime commands or Python package entry points.

scjson.dataclasses

Plain Python dataclasses without runtime validation.

  • Assign – update a datamodel location with an expression or value.
  • Cancel – cancel a pending <send> operation.
  • Content – inline payload used by <send> and <invoke>.
  • Data – represents a single datamodel variable.
  • Datamodel – container for one or more <data> elements.
  • Donedata – payload returned when a <final> state is reached.
  • Else – fallback branch for <if> conditions.
  • Elseif – conditional branch following an <if>.
  • Final – marks a terminal state in the machine.
  • Finalize – executed after an <invoke> completes.
  • Foreach – iterate over items within executable content.
  • History – pseudostate remembering previous active children.
  • If – conditional execution block.
  • Initial – starting state within a compound state.
  • Invoke – run an external process or machine.
  • Log – diagnostic output statement.
  • Onentry – actions performed when entering a state.
  • Onexit – actions performed when leaving a state.
  • Parallel – coordinates concurrent regions.
  • Param – parameter passed to <invoke> or <send>.
  • Raise – raise an internal event.
  • Script – inline executable script.
  • Scxml – root element of an SCJSON document.
  • Send – dispatch an external event.
  • State – basic state node.
  • Transition – edge between states triggered by events.

scjson.dataclasses_strict

The same dataclasses as above but configured for stricter type checking.

scjson.pydantic

Pydantic BaseModel classes generated from the SCJSON schema. They provide data validation and convenient .model_dump() helpers.

scjson.pydantic_strict

Pydantic models with strict validation settings.

Other Resources

github: [https://github.com/SoftOboros/scjson]

git clone https://github.com/SoftOboros/scjson.git

git clone git@github.com:SoftOboros/scjson.git

gh repo clone SoftOboros/scjson

npm: [https://www.npmjs.com/package/scjson]

npm install scjson

cargo: [https://crates.io/crates/scjson]

cargo install scjson

dockerhub: [https://hub.docker.com/r/iraa/scjson] (Full development environment for all supported languages)

docker pull iraa/scjson:latest

License

All source code in this directory is released under the BSD 1-Clause license. See LICENSE and LEGAL.md for details.

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

scjson-0.4.2.tar.gz (179.6 kB view details)

Uploaded Source

Built Distribution

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

scjson-0.4.2-py3-none-any.whl (144.1 kB view details)

Uploaded Python 3

File details

Details for the file scjson-0.4.2.tar.gz.

File metadata

  • Download URL: scjson-0.4.2.tar.gz
  • Upload date:
  • Size: 179.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for scjson-0.4.2.tar.gz
Algorithm Hash digest
SHA256 45e504a70e670aaa1dfe81c192698369a494d75369fafacc25d104459d71fd01
MD5 dab83157097adc5975f163ca26f9f528
BLAKE2b-256 ba0c6837386ffc8326ba2e71b4c22a79ad719d3237df78d003f60ef040871950

See more details on using hashes here.

Provenance

The following attestation bundles were made for scjson-0.4.2.tar.gz:

Publisher: publish.yml on SoftOboros/scjson

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

File details

Details for the file scjson-0.4.2-py3-none-any.whl.

File metadata

  • Download URL: scjson-0.4.2-py3-none-any.whl
  • Upload date:
  • Size: 144.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for scjson-0.4.2-py3-none-any.whl
Algorithm Hash digest
SHA256 88ea1d42a481f6d70758a67afaf8e90d92c6245b95a556c067edd5a6dfd8cc59
MD5 f014855e6f715bb58cf625849529772a
BLAKE2b-256 c0d1a0ad436d81239634a43f76773d1ac8f19d26ea029f51629537714960994b

See more details on using hashes here.

Provenance

The following attestation bundles were made for scjson-0.4.2-py3-none-any.whl:

Publisher: publish.yml on SoftOboros/scjson

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