Skip to main content

Open Job Description - Models For Python

pypi python license

Open Job Description is a flexible open specification for defining render jobs which are portable between studios and render management solutions. This package provides a Python implementation of the data model for Open Job Description's template schemas. It can parse, validate, create JSON/Yaml documents for the Open Job Description specification, and more. A main use-case that this library targets is interoperability by creating applications to translate a Job from Open Job Description to the render management software of your choice.

For more information about Open Job Description and our goals with it, please see the Open Job Description Wiki on GitHub.

Compatibility

This library requires:

  1. Python 3.9 or higher; and
  2. Linux, MacOS, or Windows operating system.

Versioning

This package's version follows Semantic Versioning 2.0, but is still considered to be in its initial development, thus backwards incompatible versions are denoted by minor version bumps. To help illustrate how versions will increment during this initial development stage, they are described below:

  1. The MAJOR version is currently 0, indicating initial development.
  2. The MINOR version is currently incremented when backwards incompatible changes are introduced to the public API.
  3. The PATCH version is currently incremented when bug fixes or backwards compatible changes are introduced to the public API.

Contributing

We encourage all contributions to this package. Whether it's a bug report, new feature, correction, or additional documentation, we greatly value feedback and contributions from our community.

Please see CONTRIBUTING.md for our contributing guidelines.

Example Usage

Reading and Validating a Job Template

To validate a job template, you can read the JSON or YAML input into Python data structures and then pass the result to decode_job_template. By default, this will accept templates of any supported version number with no extensions enabled. Use decode_environment_template for environment templates.

To accept extensions in templates, provide the list of the names you support. See the Open Job Description 2023-09 specification for the list of extensions available.

from openjd.model import DocumentType, decode_job_template, document_string_to_object

# String containing the json of the job template
template_string = """specificationVersion: jobtemplate-2023-09
name: DemoJob
steps:
  - name: DemoStep
    script:
      actions:
        onRun:
          command: python
          args: ["-c", "print('Hello')"]
"""

# You can use 'json.loads' or 'yaml.safe_load' directly as well
template_object = document_string_to_object(
    document=template_string,
    document_type=DocumentType.YAML
)

# Raises a DecodeValidationError if it fails.
job_template = decode_job_template(template=template_object, supported_extensions=["TASK_CHUNKING"])

Once you have the Open Job Description model object, you can use the model_to_object function to convert it into an object suitable for converting to JSON or YAML.

import json
from openjd.model import model_to_object

obj = model_to_object(model=job_template)
print(json.dumps(obj, indent=2))

Creating Template Model Objects

As an alternative to assembling full job templates as raw data following the specification data model, you can use the library to construct model objects of components, such as for StepTemplates, and then assemble the result into a job template. The parse_model function provides a way to do this.

To call parse_model, you will need to provide the list of extensions you want to enable as the supported_extensions argument. Individual model objects can accept inputs differently depending on what extensions are requested in the job template, and the model parsing context holds that list. The functions decode_job_template and decode_environment_template create this context from top-level template fields, but when using parse_model to process interior model types you must provide it explicitly.

import json
from openjd.model import parse_model, model_to_object
from openjd.model.v2023_09 import StepTemplate

extensions_list = ["TASK_CHUNKING"]

step_template = parse_model(
    model=StepTemplate,
    obj={
        "name": "DemoStep",
        "script": {
            "actions": {"onRun": {"command": "python", "args": ["-c", "print('Hello world!')"]}}
        },
    },
    supported_extensions=extensions_list,
)

obj = model_to_object(model=step_template)
print(json.dumps(obj, indent=2))

You can also construct the individual elements of the template from the model object types. This can be more effort than using parse_model depending on how the enabled extensions affect processing. You will need to create a ModelParsingContext object to hold the extensions list, and pass it to any model object constructors that need it.

import json
from openjd.model import model_to_object
from openjd.model.v2023_09 import (
    StepTemplate,
    StepScript,
    StepActions,
    Action,
    ArgString,
    CommandString,
    ModelParsingContext,
)

context = ModelParsingContext(supported_extensions=["TASK_CHUNKING"])

step_template = StepTemplate(
    name="DemoStep",
    script=StepScript(
        actions=StepActions(
            onRun=Action(
                command=CommandString("python", context=context),
                args=[
                    ArgString("-c", context=context),
                    ArgString("print('Hello world!')", context=context),
                ],
            )
        )
    ),
)

obj = model_to_object(model=step_template)
print(json.dumps(obj, indent=2))

Creating a Job from a Job Template

import os
from pathlib import Path
from openjd.model import (
    DecodeValidationError,
    create_job,
    decode_job_template,
    preprocess_job_parameters
)

job_template_path = Path("/absolute/path/to/job/template.json")
job_template = decode_job_template(
    template={
        "name": "DemoJob",
        "specificationVersion": "jobtemplate-2023-09",
        "parameterDefinitions": [
            { "name": "Foo", "type": "INT" }
        ],
        "steps": [
            {
                "name": "DemoStep",
                "script": {
                    "actions": {
                        "onRun": { "command": "python", "args": [ "-c", "print(r'Foo={{Param.Foo}}')" ] }
                    }
                }
            }
        ]
    }
)
try:
    parameters = preprocess_job_parameters(
        job_template=job_template,
        job_parameter_values={
            "Foo": "12"
        },
        job_template_dir=job_template_path.parent,
        current_working_dir=Path(os.getcwd())
    )
    job = create_job(
        job_template=job_template,
        job_parameter_values=parameters
    )
except (DecodeValidationError, RuntimeError) as e:
    print(str(e))

If any of the job's steps declares a template-scope let that the step's script references, then this Job is not sufficient to run the step: step-level let bindings are evaluated once during instantiation and kept in the step's symbol table rather than lowered onto the script, so a session created from the Job alone has no binding for the name and the action fails with Undefined variable. Use create_job_with_symbol_tables instead and forward the step's entry from the returned step_symbol_tables to the session that runs it. The two examples below only inspect the Job at creation time, so plain create_job is correct there.

Working with Step dependencies

from openjd.model import (
    StepDependencyGraph,
    create_job,
    decode_job_template
)

job_template = decode_job_template(
    template={
        "name": "DemoJob",
        "specificationVersion": "jobtemplate-2023-09",
        "steps": [
            {
                "name": "Step1",
                "script": {
                    "actions": {
                        "onRun": { "command": "python", "args": [ "-c", "print('Step1')" ] }
                    }
                }
            },
            {
                "name": "Step2",
                "dependencies": [ { "dependsOn": "Step1" }, { "dependsOn": "Step3" }],
                "script": {
                    "actions": {
                        "onRun": { "command": "python", "args": [ "-c", "print('Step2')" ] }
                    }
                }
            },
            {
                "name": "Step3",
                "script": {
                    "actions": {
                        "onRun": { "command": "echo", "args": [ "Step3" ] }
                    }
                }
            },
        ]
    }
)
job = create_job(job_template=job_template, job_parameter_values={})
dependency_graph = StepDependencyGraph(job=job)

for step in job.steps:
    step_node = dependency_graph.step_node(stepname=step.name)
    if step_node.in_edges:
        name_list = ', '.join(edge.origin.step.name for edge in step_node.in_edges)
        print(f"Step '{step.name}' depends upon: {name_list}")
    if step_node.out_edges:
        name_list = ', '.join(edge.dependent.step.name for edge in step_node.out_edges)
        print(f"The following Steps depend upon '{step.name}': {name_list}")

print(f"\nSteps in topological order: {[step.name for step in dependency_graph.topo_sorted()]}")
# The following Steps depend upon 'Step1': Step2
# Step 'Step2' depends upon: Step1, Step3
# The following Steps depend upon 'Step3': Step2

# Steps in topological order: ['Step1', 'Step3', 'Step2']

Working with a Step's Tasks

from openjd.model import (
    StepParameterSpaceIterator,
    create_job,
    decode_job_template
)

job_template = decode_job_template(
    template={
        "name": "DemoJob",
        "specificationVersion": "jobtemplate-2023-09",
        "steps": [
            {
                "name": "DemoStep",
                "parameterSpace": {
                    "taskParameterDefinitions": [
                        { "name": "Foo", "type": "INT", "range": "1-5" },
                        { "name": "Bar", "type": "INT", "range": "1-5" }
                    ],
                    "combination": "(Foo, Bar)"
                },
                "script": {
                    "actions": {
                        "onRun": {
                            "command": "python",
                            "args": [ "-c", "print(f'Foo={{Task.Param.Foo}}, Bar={{Task.Param.Bar}}"]
                        }
                    }
                }
            },
        ]
    }
)
job = create_job(job_template=job_template, job_parameter_values={})
for step in job.steps:
    iterator = StepParameterSpaceIterator(space=step.parameterSpace)
    print(f"Step '{step.name}' has {len(iterator)} Tasks")
    for param_set in iterator:
        print(param_set)
# Step 'DemoStep' has 5 Tasks
# {'Foo': ParameterValue(type=<ParameterValueType.INT: 'INT'>, value='1'), 'Bar': ParameterValue(type=<ParameterValueType.INT: 'INT'>, value='1')}
# {'Foo': ParameterValue(type=<ParameterValueType.INT: 'INT'>, value='2'), 'Bar': ParameterValue(type=<ParameterValueType.INT: 'INT'>, value='2')}
# {'Foo': ParameterValue(type=<ParameterValueType.INT: 'INT'>, value='3'), 'Bar': ParameterValue(type=<ParameterValueType.INT: 'INT'>, value='3')}
# {'Foo': ParameterValue(type=<ParameterValueType.INT: 'INT'>, value='4'), 'Bar': ParameterValue(type=<ParameterValueType.INT: 'INT'>, value='4')}
# {'Foo': ParameterValue(type=<ParameterValueType.INT: 'INT'>, value='5'), 'Bar': ParameterValue(type=<ParameterValueType.INT: 'INT'>, value='5')}

Downloading

You can download this package from:

Verifying GitHub Releases

See Verifying GitHub Releases for more information.

Security

We take all security reports seriously. When we receive such reports, we will investigate and subsequently address any potential vulnerabilities as quickly as possible. If you discover a potential security issue in this project, please notify AWS/Amazon Security via our vulnerability reporting page or directly via email to AWS Security. Please do not create a public GitHub issue in this project.

License

This project is licensed under the Apache-2.0 License.

Metadata

Release files for openjd-model 0.11.13

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

Source distribution (sdist)

Source distribution for openjd-model 0.11.13
File Size Uploaded
openjd_model-0.11.13.tar.gz 269.9 kB Details

Built distributions (wheels)

Table of built distributions (wheels) for openjd-model 0.11.13
File
openjd_model-0.11.13-cp39-abi3-win_arm64.whl CPython 3.9 abi3 Windows ARM64 Details
openjd_model-0.11.13-cp39-abi3-win_amd64.whl CPython 3.9 abi3 Windows x86-64 Details
openjd_model-0.11.13-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl CPython 3.9 abi3 Linux glibc 2.17+ x86-64 Details
openjd_model-0.11.13-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl CPython 3.9 abi3 Linux glibc 2.17+ ARM64 Details
openjd_model-0.11.13-cp39-abi3-macosx_11_0_arm64.whl CPython 3.9 abi3 macOS 11.0+ ARM64 Details
openjd_model-0.11.13-cp39-abi3-macosx_10_12_x86_64.whl CPython 3.9 abi3 macOS 10.12+ x86-64 Details

Total release size: 30.1 MB

Release files / openjd_model-0.11.13.tar.gz

Download URL openjd_model-0.11.13.tar.gz
Size 269.9 kB
Tags Source
SHA-256 checksum
How to use checksums
c237178c68ce9e4596b069ce0864c05e9e3b88c9d066e7d8aff21a6dbbc5228c
BLAKE2b-256 checksum
How to use checksums
bfe12ad175195650be1594ac73cf770ba0c63907177a7c2f7246e4ead3a63ce5
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 16, 2026.

Transparency log

Release files / openjd_model-0.11.13-cp39-abi3-win_arm64.whl

Download URL openjd_model-0.11.13-cp39-abi3-win_arm64.whl
Size 4.5 MB
Tags CPython 3.9 Windows ARM64 abi3
SHA-256 checksum
How to use checksums
2aed8d78f7e5d9c67710970c8b0dbb00035673a4d96635c105c89354b186cbec
BLAKE2b-256 checksum
How to use checksums
a5fe85c8158b31bff67bca3d4b004aa6725c9d18608368c6b156a84c39e6b8a0
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 16, 2026.

Transparency log

Release files / openjd_model-0.11.13-cp39-abi3-win_amd64.whl

Download URL openjd_model-0.11.13-cp39-abi3-win_amd64.whl
Size 4.8 MB
Tags CPython 3.9 Windows x86-64 abi3
SHA-256 checksum
How to use checksums
ba88ae4361a5970e1e417729b38cbd323ead2506b5dca26504b60713f0f037ca
BLAKE2b-256 checksum
How to use checksums
f1867b1f0c604025574f2110f8ed4160abd7f1dae840e4358b72d6a108b8ea6a
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 16, 2026.

Transparency log

Release files / openjd_model-0.11.13-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl

Download URL openjd_model-0.11.13-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Size 5.3 MB
Tags CPython 3.9 Linux glibc 2.17+ x86-64 abi3
SHA-256 checksum
How to use checksums
7dca9e85cd9fe93ab71f41f8919a278c800c6472d19f4d7247d941094d450fa8
BLAKE2b-256 checksum
How to use checksums
c2a5cc400466d53b4caec280d68c5470f3ddd332a699efb84b9f883d165a6575
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 16, 2026.

Transparency log

Release files / openjd_model-0.11.13-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl

Download URL openjd_model-0.11.13-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Size 5.3 MB
Tags CPython 3.9 Linux glibc 2.17+ ARM64 abi3
SHA-256 checksum
How to use checksums
2564e4581d637b0358b514c553ba6cfe99fe087f0bee9062a077b8bd672d60e5
BLAKE2b-256 checksum
How to use checksums
3995c42f289807fcf1b708c78357df73fd95db9db98021008fcaa8dc8e06fdf5
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 16, 2026.

Transparency log

Release files / openjd_model-0.11.13-cp39-abi3-macosx_11_0_arm64.whl

Download URL openjd_model-0.11.13-cp39-abi3-macosx_11_0_arm64.whl
Size 4.9 MB
Tags CPython 3.9 abi3 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
9a04cd8be36022f66c1f039d0cddf4833738a23638c88873da3d14e4e9454408
BLAKE2b-256 checksum
How to use checksums
b1687a9da6bef4d27725151ad114b147c383d105805ef9fdd6ba811b8af0ad8b
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 16, 2026.

Transparency log

Release files / openjd_model-0.11.13-cp39-abi3-macosx_10_12_x86_64.whl

Download URL openjd_model-0.11.13-cp39-abi3-macosx_10_12_x86_64.whl
Size 5.0 MB
Tags CPython 3.9 abi3 macOS 10.12+ x86-64
SHA-256 checksum
How to use checksums
a3e81ea3703e9efaaa90a0b34c83d4fd5f6dd5b5d23fc0a1f04105e036a68c5e
BLAKE2b-256 checksum
How to use checksums
f5d6ac405fa114c068154ff5bb60ba3013070c9fed20cf66ce8f7e0d46a99a6a
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 16, 2026.

Transparency log

Release history Release notifications | RSS feed

0.12.0

7 release files

This release

0.11.13 This release

7 release files

0.11.6

7 release files

0.11.5

7 release files

0.11.4

7 release files

0.11.3

7 release files

0.11.1

7 release files

0.10.1

6 release files

0.10.0

6 release files

0.9.0

2 release files

0.8.7

2 release files

0.8.6

2 release files

0.8.5

2 release files

0.8.4

2 release files

0.8.3

2 release files

0.8.2

2 release files

0.8.0

2 release files

0.7.0

2 release files

0.6.0

2 release files

0.5.1

2 release files

0.5.0

2 release files

0.4.4

2 release files

0.4.3

2 release files

0.4.2

2 release files

0.4.1

2 release files

0.4.0

2 release files

0.0.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