Skip to main content

operaton-contracts

Pydantic task contracts for Robot Framework packages served as Operaton (Camunda 7) external tasks, for example by purjo.

Documentation: https://datakurre.github.io/operaton-contracts/

One model per external task topic is the source of truth for what the task accepts and returns:

  • At runtime each Robot task validates and normalizes its process variables with Validate Task Input.
  • At build time operaton-contracts generate renders one bpmn.io element template per topic from the same models, and operaton-contracts check verifies that the templates, [tool.purjo.topics], and the Robot suites agree.
uv add "operaton-contracts[robot]"   # runtime: pydantic + robotframework
uv add --group dev "operaton-contracts[templates]"   # uv-only: jsonschema for validate

When using devenv, provide jsonschema and development tools through devenv.nix instead of duplicating them in uv's dev group.

Contracts

# OperatonTasks.py
from datetime import date
from typing import Any

from pydantic import Field
from OperatonContracts import TaskContract, template_hints


class ProcessRecordsInput(TaskContract):
    record_ids: list[str] = Field(
        alias="recordIds",
        title="Record IDs",
        min_length=1,
        json_schema_extra=template_hints(value=["${recordId}"]),
    )
    effective_date: date = Field(
        alias="effectiveDate", title="Effective date", strict=False
    )
    dry_run: bool = Field(alias="dryRun", title="Dry run", default=False)


class ProcessRecordsOutput(TaskContract):
    result: dict[str, Any] = Field(alias="result", title="Result variable")

TaskContract is strict, forbids extra fields, and strips strings. Every field needs an alias (the process variable name) and a title (the template label). Use Literal[...] for choices; Enum, Optional, and nested models are not supported in template inputs. template_hints(value=..., type=...) sets template-only defaults and property types.

Robot tasks

*** Settings ***
Library     OperatonContracts    OperatonTasks

*** Variables ***
${BPMN:TASK}    local
@{recordIds}    @{EMPTY}
${effectiveDate}    ${EMPTY}
${dryRun}    ${False}

*** Tasks ***
Process Records
    ${input}=    Validate Task Input    ProcessRecordsInput
    Log    ${input}[recordIds]
    VAR    ${result}=    ${{{}}}    scope=${BPMN:TASK}

Validate Task Input reads ${alias} for every field, validates, and returns the values JSON-compatible (dates as YYYY-MM-DD), keyed by alias. Declare typed suite defaults (${False}, ${0}, @{EMPTY}): strict contracts reject the string "0" or "false". The library imports the contracts module from sys.path, falling back to the running suite's directory.

Element templates

# pyproject.toml of the robot package
[tool.operaton-contracts]
specs = "OperatonTasks:TEMPLATES"               # module:attribute
icon = "logo.svg"                               # optional SVG icon
reserved-topics = ["legacy.topic"]              # optional
# schema-url = "…"                              # optional; pinned default
# Append to OperatonTasks.py, after the task contracts.
from OperatonContracts.templates import TaskTemplate, TemplateGroup

TEMPLATES = (
    TaskTemplate(
        topic="records.process",
        template_id="org.example.records-process",
        name="Process Records",
        description="Process selected records.",
        filename="records-process.json",
        inputs=ProcessRecordsInput,
        outputs=ProcessRecordsOutput,
        groups=(TemplateGroup("main", "Processing"),),
        input_group="main",
        output_group="main",
    ),
)

Co-locating the specs adds no package dependency when tasks already use OperatonContracts for TaskContract and Validate Task Input. Alternatively, put the declarations in a root-level OperatonTemplates.py and set specs = "OperatonTemplates:TEMPLATES"; list that file in .wrapignore so pur wrap leaves it out of the robot package.

operaton-contracts generate   # write .operaton/element-templates/*.json
operaton-contracts check      # offline: drift and package consistency
operaton-contracts validate   # against the pinned upstream schema (network)

The generated .operaton/ templates do not have to be committed. Robot packages may add .operaton/ to .gitignore and run the operaton-contracts generate command when the modeler needs the templates. If using check in CI, generate the files first because check verifies that the on-disk templates match the contracts.

check fails when on-disk templates differ from the generated ones, when specs and [tool.purjo.topics] differ, when a topic is reserved or lacks process-variables = false, or when the suite defining a topic's task lacks a typed default for an input, the Validate Task Input call, or a VAR … scope=${BPMN:TASK} for an output. Names are matched the way Robot matches them, suites are collected recursively (skipping hidden directories, tests/, lib/, examples/, and test_*.robot), and a task name defined in more than one suite is an error.

Agent skill

The package bundles an agent skill for building robot packages with these conventions. Install it into .agents/skills/ of your project, and refresh it after upgrades with --force:

uv run operaton-contracts install-skill

See the Agent skill page.

Development

uv run --group dev --group docs make test check docs   # with uv
devenv shell -- make test check docs                   # or with devenv
make build

make docs-serve previews the documentation site, which is published to GitHub Pages from main by .github/workflows/docs.yml. The uv dependency groups provide test and documentation tools for uv-only development. When using devenv, those tools come from devenv.nix; project dependencies still come from uv.

License

Apache License 2.0; see LICENSE.

Releases are published to PyPI by .github/workflows/release.yml with trusted publishing when a v* tag matching the project version is pushed.

Metadata

Release files for operaton-contracts 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 operaton-contracts 0.2.0
File Size Uploaded
operaton_contracts-0.2.0.tar.gz 50.7 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for operaton-contracts 0.2.0
File Interpreter ABI Platform
operaton_contracts-0.2.0-py3-none-any.whl Python 3 none any Details

Total release size: 107.4 kB

Release files / operaton_contracts-0.2.0.tar.gz

Download URL operaton_contracts-0.2.0.tar.gz
Size 50.7 kB
Tags Source
SHA-256 checksum
How to use checksums
daa040010ab66ed4697e1cdc686c689efd9e1a1b0a0205e2e66df11192678653
BLAKE2b-256 checksum
How to use checksums
2b435ab67be3b363dbe2da5600cd21ca19be51417bcaec3be95ca538fd1bc9e8
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 9, 2026.

Transparency log

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

Download URL operaton_contracts-0.2.0-py3-none-any.whl
Size 56.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
2618fff6fe5fc334f63e06b1aa39cef9e69617cf511d3c2122f2a17df1142718
BLAKE2b-256 checksum
How to use checksums
734087c6a929fa6fb68f2f676ca253c4885e3b6593da1ab9e45414a63bfbd8cf
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 9, 2026.

Transparency log

Release history Release notifications | RSS feed

0.4.0

2 release files

0.3.0

2 release files

This release

0.2.0 This release

2 release files

0.1.0

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