maf-sandbox-drawio
Experimental. This package warns on import with
MafSandboxDrawioExperimentalWarning. Releases before 1.0 may change or remove APIs without notice.
Create an editable diagram.drawio file from model-supplied XML. The create_drawio(xml: str) tool validates native draw.io cells, applies automatic layout when needed, and delivers the file through the host's OutputSink.
This package is experimental and not yet released. It requires Python 3.12 or newer. Install it from this workspace with uv sync --all-packages until its first release.
Attach the tool
from maf_sandbox_drawio import make_drawio_tools
tools = make_drawio_tools(
router,
agent_id="diagram-designer",
context=context,
sink=sink,
image="drawio-sandbox:local",
preserve_layout=True,
direction="TB",
)
The host supplies a SandboxRouter, CallerContext, and OutputSink, just as it does for other sandbox kinds. Use make_file_system_sink(output_directory, existing="replace") to keep the most recent diagram, or a sink with per_call=True to distinguish outputs from different calls. The tool returns the sink's display reference after successful delivery. The model supplies neither a storage path nor layout settings.
Build the image from the repository root:
docker build -t drawio-sandbox:local images/drawio-sandbox
Verify all four layout-policy combinations through a real Docker backend without a model:
uv run python scripts/check_drawio_docker.py --image drawio-sandbox:local --output out/drawio
The image provides python3 and Graphviz dot. The kind uploads its fixed converter with each call; no package installation or network access occurs in the guest. It requires a POSIX guest with EXEC, FILES_IN, and FILES_OUT, and declares closed egress. Use a backend that declares POSIX and provides all three capabilities. For Docker, construct the backend with await DockerSandboxBackend.create(config) so it declares the daemon's guest family. Confinement is undeclared, so default cleanup disposes the sandbox.
Model input
Supply an uncompressed mxfile or a bare mxGraphModel. For example, this input has no layout and produces two connected native shapes:
<mxGraphModel>
<root>
<mxCell id="0" />
<mxCell id="1" parent="0" />
<mxCell id="agent" value="Agent" vertex="1" parent="1" style="rounded=1;whiteSpace=wrap;html=1;" />
<mxCell id="file" value="diagram.drawio" vertex="1" parent="1" style="shape=document;whiteSpace=wrap;html=1;" />
<mxCell id="creates" edge="1" parent="1" source="agent" target="file" style="endArrow=block;" />
</root>
</mxGraphModel>
Labels, styles, IDs, object metadata, layer membership, and endpoint references survive conversion. A matching ID repeated on an object wrapper's inner cell is retained on the wrapper only; other duplicate XML IDs within a page are rejected. The converter writes an uncompressed UTF-8 file with native vertices and connectors. It does not render a preview or fetch images, links, fonts, or other resources mentioned in the XML. Such references remain in the artifact for its eventual consumer; XML validation is not content sanitization.
Layout policy
preserve_layout |
Page has complete vertex geometry | Behavior |
|---|---|---|
True (default) |
Yes | Preserve geometry, including connector waypoints. |
True |
No | Apply automatic layout to the page. |
False |
Either | Apply automatic layout to the page. |
The decision is per page. A vertex needs an mxGeometry with positive width and height; omitted x/y coordinates default to zero. Coordinates at the origin and overlapping shapes are valid supplied layout. Missing connector waypoints do not trigger layout. An attached edge without geometry receives the standard relative edge geometry without moving its vertices. Missing dimensions trigger layout; invalid supplied dimensions or non-finite coordinates are errors in both modes.
Automatic layout supports flat flowcharts and component graphs, including multiple layers, disconnected nodes, cycles, self-loops, and parallel edges. All layer vertices participate in one layout, retaining their layer membership. Graphviz determines placement and polyline connector routes, reserving each vertex's rotated bounds when its style sets rotation. Supplied dimensions and rotation are retained and missing dimensions default to 160 by 80 units. direction="TB" flows top to bottom; "LR" flows left to right. Routing styles, including sourcePort and targetPort, and old waypoints are replaced; embedded childLayout hints are removed on automatically laid-out pages. Colors, arrowheads and other appearance attributes remain.
Nested groups, relative ports, edge-label vertices, collapsed cells and detached edges require complete supplied geometry and preserve_layout=True. Automatic mode rejects those structures with a diagnostic. It does not infer sequence, BPMN, or ER-specific layout rules, fit arbitrary labels, or promise collision-free text. Large labels may need explicit dimensions. Preservation retains geometry values, not the exact XML byte formatting.
Validation and limits
Validation checks XML structure, unique page/XML IDs, parent references and cycles, edge endpoints, and finite geometry before and after layout. Numbers use ASCII decimal or scientific notation; underscores and Unicode digits are refused. Geometry elements accept only their supported attributes: position/dimensions, the appropriate as role, and relative on mxGeometry. Waypoint arrays contain unnamed points and cannot declare their own length. Put custom metadata on object wrappers. DTDs, entity declarations, compressed pages, and unsupported cell/geometry elements are refused. A malformed later page prevents the whole output from being written.
Input is capped at 1 MiB, 8 pages and 1000 cells per page, with XML depth and element limits. Automatic layout accepts up to 200 vertices and 600 edges per page. Output is capped at 2 MiB and one file. The host sets exec_timeout_seconds (default 60, maximum 300); layout shares one deadline across pages and bounds retained subprocess output. Failure diagnostics are limited to 2048 characters and remain untrusted. Transport details stay in host logs.
The result explicitly declares SourceIntegrity.UNTRUSTED: both file content and validation diagnostics derive from model input. The host chooses the output sink and any outward confidentiality policy.
See the kind design, sandbox host wiring, and kind authoring guide.
Release files for maf-sandbox-drawio 0.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| maf_sandbox_drawio-0.2.0.tar.gz | 14.4 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| maf_sandbox_drawio-0.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 30.5 kB
Release files / maf_sandbox_drawio-0.2.0.tar.gz
| Download URL | maf_sandbox_drawio-0.2.0.tar.gz |
|---|---|
| Size | 14.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
e2c11e7ea14734350a69e38453ec493aba3ae6995a12d139886dfcc6732bed25
|
|
BLAKE2b-256 checksum How to use checksums |
7fa01a858632d83442bb94fb22276f5bf9b116a24d7fa52ad0d90380d6eed611
|
| 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 Sep 19, 2026.
Transparency logRelease files / maf_sandbox_drawio-0.2.0-py3-none-any.whl
| Download URL | maf_sandbox_drawio-0.2.0-py3-none-any.whl |
|---|---|
| Size | 16.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
78043074e4bec11f5614a47e639eef824eb072f325ac56db640596d0340992c9
|
|
BLAKE2b-256 checksum How to use checksums |
725156b9b36091e4e7feab1f925985ad0b4168c5690ebf5e2f47d217dd04e87f
|
| 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 Sep 19, 2026.
Transparency log