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 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 pydantic and dataclasses types for the associated objects / enums in both standard and strict forms.
For details on how SCXML elements are inferred during conversion see INFERENCE.md. In python, inference for conversion is handled by the dataclasses models. See below.
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).
Decimalvalues are converted to floating point numbers.- Enum values are stored using their
.valuestring.
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/--subsetfilters SCXML files by a glob relative totutorial/.--consensus-warndowngrades mismatches to warnings when reference languages (Python/JavaScript/Rust) match the canonical structure.- The harness normalizes structural differences (see INFERENCE.md) 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 boundearlyorlateduring execution.BooleanDatatype– boolean attribute valuestrueorfalse.ExmodeDatatype– processor execution mode, eitherlaxorstrict.HistoryTypeDatatype– type of<history>state:shallowordeep.TransitionTypeDatatype– whether a<transition>isinternalorexternal.
Common Types
Several generated classes share generic helper fields:
other_attributes:dict[str, str]capturing additional XML attributes from foreign namespaces.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.
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
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
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 scjson-0.3.5.tar.gz.
File metadata
- Download URL: scjson-0.3.5.tar.gz
- Upload date:
- Size: 155.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.11.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
55f91f4aff40aa067bb86e4c38902d0d891605e775f479ffd93f5e92e5738da6
|
|
| MD5 |
d1a13afbaccd706cdd305d627ec85de8
|
|
| BLAKE2b-256 |
604cc785d8d34417c899c6396758e95f2129c0b7ef912875df171b1b07270f0c
|
File details
Details for the file scjson-0.3.5-py3-none-any.whl.
File metadata
- Download URL: scjson-0.3.5-py3-none-any.whl
- Upload date:
- Size: 73.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.11.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3a7289146660f3180be4be160ff115de2366fc2769342db748a57877178d3976
|
|
| MD5 |
0f68aec0abb8462304d923bfa26f75f7
|
|
| BLAKE2b-256 |
582296ba1f7adc92739c5ad21850bb52092ef27facdcfe4b615aef9cc1fed429
|