Skip to main content

drawio-structurizr

Turn draw.io C4 diagrams into checked, version-controlled Structurizr models


Full documentation


🚀 Quick Start · 📋 Diagram Conventions · ⚠️ Limitations · 🧪 Examples · 📝 Changelog


License: MIT Python Output Output Input Tests Last commit


Overview

drawio-structurizr reads C4 diagrams drawn with draw.io's C4 shape library and:

  • checks them for missing descriptions, technologies and data flow details
  • repairs arrows that touch a shape without being attached to it
  • converts them to a Structurizr DSL workspace, with system landscape, system context, container and component views
  • exports elements and relationships to an Excel workbook

Both compressed and uncompressed .drawio files are supported, and every page of a file is read. Several files can be converted into one workspace. An element drawn on several pages or files (for example a context page and a container page) appears once.

Quick Start

git clone https://github.com/veritas-sovereign/drawio-structurizr.git
cd drawio-structurizr
python3 -m venv .venv && source .venv/bin/activate
pip install -e .
drawio-structurizr examples/shop.drawio -o shop.dsl

Paste shop.dsl into the Structurizr DSL editor to see the diagrams.

Initial setup

Prerequisites

Requirement Version Needed for
Python 3.9 or later everything
git any cloning the repository
draw.io desktop or web any drawing diagrams
structurizr-cli any optional --validate step (setup)
Java 17 or later structurizr-cli only

Install

  1. Clone the repository and enter it:

    git clone https://github.com/veritas-sovereign/drawio-structurizr.git
    cd drawio-structurizr
    
  2. Create and activate a virtual environment. .venv/ is already git-ignored.

    python3 -m venv .venv
    source .venv/bin/activate          # Windows: .venv\Scripts\activate
    
  3. Install the package. Add [dev] to also install pytest.

    pip install -e .                   # or: pip install -e '.[dev]'
    
  4. Check the install:

    drawio-structurizr --help
    
  5. Optional: install structurizr-cli to validate generated workspaces. See Validating with structurizr-cli for other platforms and Docker.

    brew install structurizr-cli       # macOS
    

To use the code without installing it, run pip install -r requirements.txt and prefix commands with PYTHONPATH=src.

Once a release is published, you can also install from PyPI with pip install drawio-structurizr, or use the Docker image, which needs neither Python nor Java.

Usage

The project provides three commands. Run them from any directory once the package is installed.

Convert to Structurizr DSL

drawio-structurizr <input.drawio>... [-o workspace.dsl] [-n NAME] [-s] [-d] [--strict]
                   [--check | --dry-run | --diff] [--validate | --validate-required] [--export FORMAT]... [--export-dir DIR]
                   [--no-context-views] [--report FILE]
Option Meaning
input one or more draw.io files; all pages of all files are merged into one workspace
-o, --output output DSL file (default workspace.dsl)
-n, --name workspace name (default Workspace)
-s, --stats print element and relationship counts
-d, --check-data also check that relationships name their input and return data
--strict treat warnings as errors too: do not write the output, exit with code 1
--dry-run print the generated DSL to stdout instead of writing it
--check only run the checks: write nothing, exit with code 1 if there are problems (used by the pre-commit hook)
--diff print a unified diff between the existing output file and the newly generated DSL, without writing
--validate check the output with structurizr-cli; skipped if it is not available
--validate-required like --validate, but if no validator is available, fail before writing anything and list what was checked. Cannot be combined with --check, --dry-run or --diff.
--export FORMAT also export the workspace with structurizr-cli; repeatable. json, plantuml, plantuml/c4plantuml, mermaid, dot, ilograph, websequencediagrams. Fails if structurizr-cli is not available.
--export-dir DIR folder for exported files (default: next to the output file)
--no-context-views do not add System Context views (see Views)
--report FILE write the problems and element and relationship counts as JSON

The checks always run. Problems are printed to stderr as a numbered list, each with a code and a severity, for example [C4-HIER-001] error: …. Errors always stop the output, because Structurizr would reject it; warnings stop it only with --strict.

Example:

drawio-structurizr examples/shop.drawio -o shop.dsl -n "Online Shop" -s --validate
drawio-structurizr examples/broken.drawio -d --strict      # 7 problems, exit code 1, nothing written
drawio-structurizr context.drawio containers.drawio -o workspace.dsl   # merge several files
drawio-structurizr examples/shop.drawio -o shop.dsl --diff   # review changes before overwriting

Problems, statistics and the "Wrote" line never go to stdout with --dry-run or --diff, so their output can be redirected to a file or piped.

More examples:

drawio-structurizr model.drawio -o workspace.dsl --export mermaid --export plantuml/c4plantuml --export-dir diagrams
drawio-structurizr model.drawio --check -d --report report.json

--report writes:

{
  "inputs": ["model.drawio"],
  "elements": 4,
  "relationships": 2,
  "problemCount": 1,
  "errorCount": 0,
  "warningCount": 1,
  "problems": [
    { "number": 1, "code": "C4-ELEM-002", "severity": "warning", "message": "Container \"Web App\" has no technology" }
  ]
}

Validate and export to Excel

python -m drawio_structurizr.parser -i <input.drawio> -o <output.xlsx> -d -s
Option Meaning
-i draw.io file to read
-o Excel file to write elements and relationships to
-d also check that relationships name their input and return data
-s print element and relationship counts

Problems are printed as a numbered list. This command also writes workspace.dsl to the current directory, using the parser's own DSL exporter.

Example, using the sample that contains deliberate mistakes:

python -m drawio_structurizr.parser -i examples/broken.drawio -o broken.xlsx -d -s

Dump cell values

python -m drawio_structurizr.dump -i <input.drawio>

Prints the raw cell values of an uncompressed diagram. Useful for debugging.

Views

Every workspace gets these views, all with autoLayout:

View When Key
systemLandscape always generated by Structurizr
systemContext for each top-level software system that has a relationship crossing its boundary, from itself or from anything inside it. Turn off with --no-context-views. <identifier>-context, for example online_shop-context
container for each software system that contains containers generated by Structurizr
component for each container that contains components generated by Structurizr

Typical workflow

  1. Draw the diagram in draw.io with the C4 shapes (see Diagram conventions).
  2. Review what would change: drawio-structurizr model.drawio -o workspace.dsl --diff
  3. Generate the workspace with every check enforced, and fix what it reports until it succeeds: drawio-structurizr model.drawio -o workspace.dsl -d --strict --validate
  4. In the repository that holds your architecture, commit the .drawio file and the generated workspace.dsl together.

Pre-commit hook

This repository is also a pre-commit hook. In the repository that holds your diagrams, add to .pre-commit-config.yaml:

repos:
  - repo: https://github.com/veritas-sovereign/drawio-structurizr
    rev: v0.2.0   # a released tag
    hooks:
      - id: drawio-structurizr-check
        args: [-d]   # optional: also check input and return data

The hook runs drawio-structurizr --check on the changed .drawio files and blocks the commit if any problem is found.

Note: this hook checks diagrams, not DSL. It never runs structurizr-cli, so a syntax error in a hand-edited workspace.dsl passes it. Add one of the hooks below to validate .dsl files too.

Validate .dsl files with Docker (no Java needed; requires Docker and a published image):

  - repo: local
    hooks:
      - id: structurizr-validate
        name: validate Structurizr workspaces
        language: docker_image
        entry: >-
          --entrypoint sh ghcr.io/veritas-sovereign/drawio-structurizr:0.2
          -c 'for f in "$@"; do structurizr-cli validate -workspace "$f" || exit 1; done' --
        files: \.dsl$

Validate .dsl files with a local structurizr-cli:

  - repo: local
    hooks:
      - id: structurizr-validate
        name: validate Structurizr workspaces
        language: system
        entry: >-
          sh -c 'for f in "$@"; do structurizr-cli validate -workspace "$f" || exit 1; done' --
        files: \.dsl$

structurizr-cli validates one workspace per run, so both hooks loop over the changed files and stop at the first invalid one. With docker_image, pre-commit mounts the repository into the container and runs it as your user. Use structurizr.sh in place of structurizr-cli if you installed the CLI from the zip.

Docker

The image contains Python, Java and a pinned structurizr-cli (v2025.11.09, checked against its SHA-256), so --validate and --export work without installing anything else:

docker run --rm -v "$PWD:/work" ghcr.io/veritas-sovereign/drawio-structurizr:0.2 \
  model.drawio -o workspace.dsl --validate --export mermaid

On Linux, add --user "$(id -u):$(id -g)", otherwise the files are written as user 10001.

Images are published to GitHub Container Registry for linux/amd64 and linux/arm64 when a v* tag is pushed, each with an SBOM (software bill of materials) attached. To build locally: docker build -t drawio-structurizr .

What is pinned

Part Pinned to Kept up to date by
Base image python:3.12-slim-bookworm by digest Dependabot, weekly pull request for a new digest (stays on Python 3.12)
structurizr-cli v2025.11.09 and the SHA-256 of its zip (ARG defaults in the Dockerfile) by hand: the upstream project is archived, so no new releases are expected
GitHub Actions used by the workflows major version tags (@v4, @v6, …) Dependabot, weekly grouped pull request
Java (default-jre-headless) and Debian packages not pinned whatever Debian bookworm ships when the image is built

Because Debian packages are not pinned, two builds of the same commit can differ in OS packages. Each published image tag is fixed once pushed, so pull a released tag (or its digest) when you need the exact same toolchain later.

To change the structurizr-cli version, download the new structurizr-cli.zip, run shasum -a 256 structurizr-cli.zip, and update both ARG lines. The build fails if the checksum does not match, including when the upstream file is changed or removed.

Validating with structurizr-cli

structurizr-cli is the official command-line tool for Structurizr DSL workspaces. The --validate option uses it to check that the generated .dsl file parses and is a valid model.

Is it free?

Yes. structurizr-cli is open source under the Apache 2.0 license and can be used commercially. validate and export run entirely on your machine and need no account. Only its push and pull commands talk to the paid Structurizr cloud service or on-premises server, and this project does not use them.

Note: the upstream repository, structurizr/cli, is archived. The last release is v2025.11.09, which still works. Homebrew has deprecated the formula and will disable it on 2027-02-17; after that, use the manual download or Docker. --validate falls back to Docker automatically, so it keeps working without a local install.

Newer builds of structurizr-cli print a banner saying it will get no further updates and pointing to its successor, Structurizr vNext (Docker image structurizr/structurizr). This project targets structurizr-cli 2025.11.09 and does not use vNext yet. drawio-structurizr only shows the CLI's output when validation or export fails, so the banner does not appear on success.

Install

All options except Docker need Java 17 or later. Check with java -version.

macOS (Homebrew):

brew install structurizr-cli
structurizr-cli --help

macOS, Linux or Windows (manual download):

  1. Download structurizr-cli.zip from the latest release.

  2. Unzip it, for example to ~/tools/structurizr-cli.

  3. Add that folder to your PATH. On macOS or Linux:

    echo 'export PATH="$HOME/tools/structurizr-cli:$PATH"' >> ~/.zshrc
    source ~/.zshrc
    structurizr.sh --help
    

    On Windows, add the folder to PATH in System Properties and run structurizr.bat --help.

Docker (no Java needed):

docker pull structurizr/cli:2025.11.09
docker run --rm -v "$PWD:/usr/local/structurizr" structurizr/cli:2025.11.09 validate -workspace shop.dsl

--validate uses this image automatically when no local CLI is installed and Docker is running. The first run downloads the image.

How --validate finds it

drawio-structurizr tries these in order and uses the first that is available:

  1. A local CLI on PATH, named structurizr-cli, structurizr.sh or structurizr:

    <cli> validate -workspace <output.dsl>
    
  2. Docker, if docker is on PATH and the Docker daemon is running. It uses structurizr/cli:2025.11.09, the same version as this project's image, not latest. The first run downloads the image. The output file's folder is mounted into the container:

    docker run --rm -v <output folder>:/usr/local/structurizr structurizr/cli:2025.11.09 validate -workspace <output file name>
    
  3. Neither: validation is skipped.

Result What you see Exit code
No CLI and Docker not running structurizr-cli not found and Docker not running; skipping validation 0
No CLI and Docker not running, with --validate-required an error listing what was checked; nothing is written 1
Workspace is valid Validated <output.dsl> 0
Workspace is invalid the CLI's error message 1

The .dsl file is written in every case. With --validate, a missing validator skips the check rather than failing, so CI jobs without Java or Docker still pass. Use --validate-required when validation must happen.

Run it directly

structurizr-cli validate -workspace shop.dsl                       # check the workspace
structurizr-cli export -workspace shop.dsl -format plantuml        # export to PlantUML
structurizr-cli export -workspace shop.dsl -format mermaid         # export to Mermaid

Use structurizr.sh instead of structurizr-cli if you installed it manually.

Diagram conventions

In draw.io, open More Shapes, enable C4, and build the diagram from those shapes. Shapes from other libraries are ignored unless you give them C4 properties (see Using shapes from other libraries).

C4 shape (c4Type) Structurizr DSL
Person person
Software System softwareSystem
Container container
Component component
SystemScopeBoundary softwareSystem that holds the shapes drawn inside it
ContainerScopeBoundary container that holds the shapes drawn inside it
Relationship ->
  • Nesting comes from position. A shape drawn inside another shape's box on the same page becomes its child. If it sits inside several boxes, the smallest one is its parent.

  • The same element on several pages or files is merged. See Merging.

  • Attach every arrow to a shape at both ends. Arrows that only touch a shape are repaired where possible.

  • Relationship descriptions name the data passed in each direction:

    action name (passed data): returned data [technologies]
    

    For example: Register order (subscriber, product): order [gRPC]. Put the technology in the relationship's c4Technology field, or end the description with [technology]: when c4Technology is empty, a trailing [...] is moved into it.

    This format is only checked when you pass -d to the parser, and only produces warnings. Conversion to DSL works with any description.

Optional properties

Add these with Edit Data on any C4 shape or relationship:

Property On Effect
c4Id elements and relationships identifies the element or relationship when merging (see Merging). On elements it is also the DSL identifier instead of one made from the name, so renaming the element does not change it. Characters other than letters, digits, _ and - become _.
c4Tags elements and relationships comma-separated tags, for styles and filtered views. Tags from merged shapes are combined.

Merging

When the same element or relationship is drawn more than once (on several pages or in several files), it appears once in the workspace.

Elements are the same when:

  1. both shapes have a c4Id and the c4Ids match, whatever their names; or
  2. otherwise, their kind, name and parent match. Names are compared ignoring case and surrounding spaces. A boundary and a software system count as the same kind. Parents are compared after merging, so two containers called "API" in different systems stay separate. If only one of the shapes has a c4Id, the element takes it.

The first shape found supplies the name, description and technology; later shapes fill gaps. Tags are combined.

Relationships are the same when they have the same c4Id, or the same source, target and description. That is how Structurizr identifies relationships, so two arrows between the same elements with the same description always become one, even if their technologies or tags differ. Tags are combined and the first technology is kept. Relationships sharing a c4Id are merged even if their ends or descriptions differ, with a C4-MERGE-006 warning.

Conflicts are reported:

Code Severity Meaning
C4-IDENT-001 error one c4Id is used for elements of different kinds
C4-IDENT-002 warning an element with a c4Id is drawn inside different parents; the first parent is kept
C4-MERGE-001 error two elements (or relationships) would collide but have different c4Ids; Structurizr rejects duplicate names
C4-MERGE-002 warning different descriptions for one element; the first is kept
C4-MERGE-003 warning different technologies for one element; the first is kept
C4-MERGE-004 warning different technologies for one relationship; the first is kept
C4-MERGE-005 warning different names for one c4Id; the first is kept
C4-MERGE-006 warning relationships with one c4Id have different sources, targets or descriptions; the first is kept

Output order

The output does not depend on the order shapes, pages or arrows were drawn in: shuffling them gives byte-identical DSL, so diffs between runs only show real changes.

  • Elements: people, then software systems, containers and components, each sorted by name, nested under their parents.
  • Identifiers: assigned in that order, so when two elements need the same name, which one gets the _2 suffix is stable.
  • Relationships: outer ones first (Structurizr rejects an explicit relationship that a nested one has already implied), then by source, target and description.
  • Tags: alphabetical.

Merging still happens in drawing order, so when shapes conflict, "the first is kept" means the first one drawn, and the conflict is reported. When you pass several files, their order on the command line is the drawing order.

Using shapes from other libraries

The tool reads a shape only if it has a c4Type property. Shapes from other libraries (AWS, Azure, Kubernetes, plain boxes) have none and are skipped. You can add the properties to any shape:

  1. Select the shape and choose Edit Data from the right-click menu (Cmd+M on macOS, Ctrl+M elsewhere).

  2. Add these properties, then click Apply:

    Property Example
    c4Type Container (or Person, Software System, Component)
    c4Name Order Handler
    c4Description Processes orders
    c4Technology AWS Lambda
  3. The shape keeps its icon and is now converted like a C4 shape.

To avoid repeating this, set up one shape per type, save them to a custom library (File → New Library), and draw from that library.

Plain draw.io arrows (not the C4 Relationship shape) are accepted if both ends are attached to C4 shapes. Their label becomes the description, and a trailing [...] becomes the technology.

Checks

Code Severity Check Applies to
C4-HIER-001 error A container is drawn inside a software system or system boundary containers
C4-HIER-002 error A component is drawn inside a container or container boundary components
C4-HIER-003 error People and software systems are not drawn inside another element people, software systems, system boundaries
C4-TYPE-001 warning The c4Type is one the tool knows; other shapes are skipped all C4 shapes
C4-ELEM-001 warning Description is filled in elements, except people and boundaries
C4-ELEM-002 warning Technology is filled in containers and components
C4-ELEM-003 warning Has at least one relationship, directly or through a parent elements, except people and boundaries
C4-REL-001 warning Technology is filled in relationships not involving a person
C4-REL-002 warning Input data ( … ) is named relationships not involving a person (with -d)
C4-REL-003 warning Return data ): … is named relationships not involving a person (with -d)
C4-REL-004 warning Both ends are C4 elements; otherwise the relationship is dropped relationships
C4-REL-005 warning Arrow is attached at both ends or can be repaired; otherwise it is dropped C4 relationships
C4-IDENT-*, C4-MERGE-* error or warning Conflicts found while merging; see Merging elements and relationships drawn more than once

Errors mean Structurizr would reject the output, so nothing is written. The known c4Type values are Person, Software System, Container, Component, SystemScopeBoundary and ContainerScopeBoundary.

Limitations

  • Layout is not preserved. Structurizr DSL describes the model, not positions, and the generated views use autoLayout. Element placement from draw.io does not carry over; only elements, nesting and relationships do. You can arrange the views again in Structurizr after import. Views use Structurizr's default styling; no theme is set, so validation needs no network access.
  • Only C4 properties are read. Shapes without a c4Type are skipped. Diagrams drawn from another template need their shapes updated first (see Using shapes from other libraries), or the tool extended: parser.py to read the extra shapes and mapper.py to map them.
  • Nesting is based on position. A shape must sit fully inside its parent's box on the same page.
  • Merging is by name unless you use c4Id. Two different elements with the same kind, name and parent are merged into one. Give them different names, or different c4Ids (which then reports C4-MERGE-001, because Structurizr does not allow the duplicate name either).
  • structurizr-cli is archived upstream. See the note above; Docker keeps --validate working.
  • Two DSL exporters. python -m drawio_structurizr.parser still writes workspace.dsl with its older exporter. Prefer the drawio-structurizr command, whose output this README describes.

Examples

File What it shows
shop.drawio A clean diagram that passes every check
shop-compressed.drawio The same diagram in compressed format
multipage.drawio A context page and a container page, merged into one workspace; uses c4Id and c4Tags
broken.drawio Seven warnings and one repaired arrow; still produces valid DSL

Testing

pip install -e '.[dev]'
pytest

The tests run the samples in examples/ end to end and cover the mapper and emitter on their own.

Project structure

drawio-structurizr/
├── src/
│   └── drawio_structurizr/      Python package
│       ├── __init__.py          package version
│       ├── main.py              drawio-structurizr command
│       ├── parser.py            reads .drawio files, runs checks, exports Excel and legacy DSL
│       ├── mapper.py            maps C4 shapes to Structurizr DSL constructs and merges duplicates
│       ├── problems.py          the coded error and warning records
│       ├── emitter.py           writes a .dsl file from the mapped model
│       ├── validate.py          optional structurizr-cli validation
│       └── dump.py              prints the cell values of a diagram
├── examples/
│   ├── README.md                what each sample covers
│   ├── shop.drawio              clean sample
│   ├── shop-compressed.drawio   same sample, compressed
│   ├── multipage.drawio         two pages merged into one workspace
│   └── broken.drawio            sample with deliberate mistakes
├── tests/
│   ├── fixtures/
│   │   ├── hierarchy/           diagrams that break the C4 nesting rules
│   │   ├── identity/            elements and relationships drawn more than once
│   │   └── views/               diagrams for System Context view generation
│   ├── test_examples.py         end-to-end tests on the samples
│   ├── test_emitter.py          mapper and emitter unit tests
│   ├── test_hierarchy.py        nesting errors and unknown shape types
│   ├── test_identity.py         merging and merge conflicts
│   ├── test_ordering.py         output order does not depend on drawing order
│   ├── test_validate.py         choice of local CLI, Docker or skip
│   ├── test_validate_required.py  --validate-required
│   └── test_views.py            System Context views
├── .github/
│   ├── dependabot.yml           weekly updates for the base image digest and GitHub Actions
│   └── workflows/
│       ├── test.yml             runs pytest on Python 3.9 and 3.13
│       ├── publish-image.yml    builds and smoke-tests the Docker image; pushes it to GHCR on v* tags
│       └── publish-pypi.yml     builds the package; publishes it to PyPI on v* tags
├── Dockerfile                   image with Python, Java and a pinned structurizr-cli, on a digest-pinned base
├── .dockerignore
├── .pre-commit-hooks.yaml       the drawio-structurizr-check pre-commit hook
├── pyproject.toml               package metadata and drawio-structurizr command
├── requirements.txt             runtime dependencies
├── CHANGELOG.md
├── LICENSE
├── .editorconfig
├── .gitattributes
└── .gitignore

The package lives under src/ so it can only be imported once installed, and so it is not mistaken for a second copy of the repository folder.

Output you generate while trying the tool in this repository (.dsl files at the top level or in examples/, and any .xlsx) is git-ignored.

How a conversion works

.drawio ──► parser.py ──► mapper.py ──► emitter.py ──► workspace.dsl ──► validate.py (optional)
             read,          C4 shapes      DSL text                       structurizr-cli
             repair,        to model
             check

Naming conventions

  • Repository, distribution and command: drawio-structurizr (kebab-case)
  • Python package: drawio_structurizr (snake_case), in src/
  • Modules: short snake_case nouns, without a drawio_ prefix, since the package name already provides it
  • Product name in prose: "draw.io"; in code and file extensions: drawio
  • C4 terms: element, relationship, software system, container, component, person

Contributing

Issues and pull requests are welcome at veritas-sovereign/drawio-structurizr. Run pytest before opening a pull request (GitHub Actions runs it too), and add a sample to examples/ when you change how diagrams are read.

License

Released under the MIT License.

Metadata

Release files for drawio-structurizr 0.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for drawio-structurizr 0.2.0
File Size Uploaded
drawio_structurizr-0.2.0.tar.gz 54.5 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for drawio-structurizr 0.2.0
File Interpreter ABI Platform
drawio_structurizr-0.2.0-py3-none-any.whl Python 3 none any Details

Total release size: 85.3 kB

Release files / drawio_structurizr-0.2.0.tar.gz

Download URL drawio_structurizr-0.2.0.tar.gz
Size 54.5 kB
Tags Source
SHA-256 checksum
How to use checksums
5a54d6ed84002439035299a723b26de905f55f586655190b43bfc2da41c070fd
BLAKE2b-256 checksum
How to use checksums
bf30eb58408b4778f8c05ed1cf34e4281beb12240299a96a2e55b9be5abaa7fa
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 Oct 5, 2026.

Transparency log

Release files / drawio_structurizr-0.2.0-py3-none-any.whl

Download URL drawio_structurizr-0.2.0-py3-none-any.whl
Size 30.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
64c75a6eead62ca9937d4f6731f320965cf2a23bfc8e623aaa4b269040c467e1
BLAKE2b-256 checksum
How to use checksums
44f702c7c45a69025221c7f750b7765d91745ccc65a9d2b5feaf69772f13f67c
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 Oct 5, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.2.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page