Metadata-Version: 2.4
Name: scjson
Version: 0.4.0
Summary: A JSON-based serialization of SCXML (State Chart XML) for modern tooling, interoperability, and education, with execution engine and trace tools for SCXML/SCML.
Author-email: Ira Abbott <ira@mycloud.blue>
License-Expression: BSD-1-Clause
Requires-Python: >=3.8
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: pydantic
Requires-Dist: lxml
Requires-Dist: jsonschema
Requires-Dist: click
Requires-Dist: py-sandboxed
Requires-Dist: jinja2
Requires-Dist: xmlschema
Requires-Dist: xsdata
Dynamic: license-file

<p align="center"><img src="https://raw.githubusercontent.com/SoftOboros/scjson/main/scjson.png" alt="scjson logo" width="200"/></p>

# 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](https://github.com/SoftOboros/scjson/blob/main/docs/concepts/SCJSON-00-CONCEPTS.md)
and
[SCJSON-CONV-00-CONCEPTS.md](https://github.com/SoftOboros/scjson/blob/main/docs/concepts/SCJSON-CONV-00-CONCEPTS.md).
For language status and parity notes, see
[docs/COMPATIBILITY.md](https://github.com/SoftOboros/scjson/blob/main/docs/COMPATIBILITY.md).

## Installation

```bash
pip install scjson
```

You can also install from a checkout of this repository:

```bash
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](https://www.npmjs.com/package/scion) runner bundled under
`tools/scion-runner`. Node.js must be able to resolve the [SCION](https://www.npmjs.com/package/scion) packages
(`scxml`, `jsdom`, and `regenerator-runtime`) via its module loader. Install
them once before running comparisons:

```bash
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](https://www.npmjs.com/package/scion) packages, comparisons fall
back to the Python engine.

## Command Line Usage

After installation the `scjson` command is available:

```bash
# 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.

```python
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.

```python
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](https://github.com/SoftOboros/scjson/blob/engine/py/uber_test.py)
```bash
/py# python uber_test.py -l python 2>&1 | tee test.log
```
Note: [uber_test.py](https://github.com/SoftOboros/scjson/blob/main/py/uber_test.py) applies all scxml files in [Zhornyak's ScxmlEditor-Tutorial](https://alexzhornyak.github.io/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:

```bash
# 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]
```bash
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]
```bash
npm install scjson
```

cargo: [https://crates.io/crates/scjson]
```bash
cargo install scjson
```

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

## License

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