Skip to main content

Write AWS Step Function State Machines in python and export to AWS States Language JSON. Allows for easy reuse of states or state components as well as generating complex state machines from simple pieces. Integrates with other tools like Pulumi to easily have a single python definition of the state machine that can generate specific JSON for multiple AWS environments.

Project description

Step Scribe logo

A package to write AWS Step Function state machines using python and output valid AWS states language JSON or to various visualization formats.

Installation

pip install stepscribe

Examples

Here's a simple task example that invokes an existing lambda function:

from stepscribe import Task

if __name__ == "__main__":
    get_price = Task(
                    name="Get Current Price",
                    next_='Check Price',
                    resource="arn:aws:states:::lambda:invoke",
                    arguments={'Payload': {"product": "{% $states.context.Execution.Input.product %}"},
                        'FunctionName': "arn:aws:lambda:<region>:account-id:function:priceWatcher:$LATEST",
                    },
                    assign={'currentPrice': "{% $states.result.Payload.current_price %}"}
    )
    print(get_price)               

This python code generates the following Amazon states language JSON:

"Get Current Price": {
  "Type": "Task",
  "QueryLanguage" : "JSONata",
  "Resource": "arn:aws:states:::lambda:invoke",
  "Next": "Check Price",
  "Arguments": {
    "Payload": {
    "product": "{% $states.context.Execution.Input.product %}"
    },
    "FunctionName": "arn:aws:lambda:<region>:account-id:function:priceWatcher:$LATEST"
  },
  "Assign": {
    "currentPrice": "{% $states.result.Payload.current_price %}"
  }
}

The value of StepScribe comes from leveraging python to create or compose objects and then generate the corresponding JSON. For example, what if we wanted to get the current price of a product, check if it's on sale, and check our inventory. If each of these actions is a lambda, we now need 3 tasks like above, but with different names and lambda functions, and each of these to be a branch of a parallel state.

from stepscribe import Task, Parallel

def product_task(name: str, lambda_name: str) -> Task:
    output=name.lower().replace(' ', '_').replace('get_', '')

    return Task(
                name=name,
                next_='Check Price',
                resource="arn:aws:states:::lambda:invoke",
                arguments={'Payload': {"product": "{% $states.context.Execution.Input.product %}"},
                        'FunctionName': f"arn:aws:lambda:<region>:account-id:function:{lambda_name}:$LATEST",
                },
                assign={'currentPrice': f"{{% $states.result.Payload.{output} %}}"}
    )


if __name__ == "__main__":

    tasks = [("Get Current Price", "priceWatcher"), ("Check Sale", "isOnSale"), ("Get Current Inventory", "inventoryWatcher")]
    step_function = Parallel(
                        name="Product Check",
                        branches=[product_task(task[0], task[1]) for task in tasks)]
                        )
    print(step_function)

This allows for considerable consolidation of the boilerplate and becomes more valuable if custom retry, catcher, item readers, or other components are reused across large state machines.

Roadmap

Currently, StepScribe has python dataclasses for states and major components and assumes only JSONata is being used (not JSONPath state attributes or query language) and writes these objects to the corresponding states language JSON.

The following features are planned:

  • Test coverage and documentation
  • JSONPath support
  • Write state machine to mermaidJS diagram
  • Read state machine
  • JSONata expression validation

Usage, desired features, bug reports, bug fixes, and feature implementations are welcome.

Contributing

For feature requests or bug reports, please submit an issue in GitHub with as much information as possible.

For bug fixes or feature implementations, fork the repo and create a PR to merge your fork branch here and request a review from me. See the contributions guide for more information.

License

MIT

Origin

My first use of AWS Step Functions seemed simple: a small set of parallel branches, most being short sequences of distributed map states that invoked a lambda on particular items of a large JSON data set in S3 or did partical aggregation of results from previous states. The JSON defining the state machine quickly grew to over 1000 lines when formatted, with massive amount of duplication (each branch was basically the same but invoked a different set of lambdas - so the same item reader, processor, writer and internal states inside each distributed map, just different state names and lambda arns). Furthermore, I needed to have a dev and prod version of this that would stay in sync. I also needed visual versions that could be used in documentation and presentations.

It seemed like a better approach would be to use python to generate versions of the state machine json, allowing loops and f-strings to easily construct machine with redundant structures and to generate dev, prod, or visuals from the same base state machine definition.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

stepscribe-0.0.5.tar.gz (9.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

stepscribe-0.0.5-py3-none-any.whl (9.9 kB view details)

Uploaded Python 3

File details

Details for the file stepscribe-0.0.5.tar.gz.

File metadata

  • Download URL: stepscribe-0.0.5.tar.gz
  • Upload date:
  • Size: 9.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.9.21 {"installer":{"name":"uv","version":"0.9.21","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for stepscribe-0.0.5.tar.gz
Algorithm Hash digest
SHA256 58506c65e650611ffb6c3e27b9a0704fdb318ea4aea8fb936831390a03b72340
MD5 ddffb05135df5be5534912f1c4cc39e0
BLAKE2b-256 0a0d41d46940b433bc97d009dff67b794cd27b272936f65f67d3ac0db6652a77

See more details on using hashes here.

File details

Details for the file stepscribe-0.0.5-py3-none-any.whl.

File metadata

  • Download URL: stepscribe-0.0.5-py3-none-any.whl
  • Upload date:
  • Size: 9.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.9.21 {"installer":{"name":"uv","version":"0.9.21","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for stepscribe-0.0.5-py3-none-any.whl
Algorithm Hash digest
SHA256 21e470ffab1d4e5a7cf911e80bc523c889ce45d5e820defe4b5b73b2bfaa0c46
MD5 aab7e45d611904f2880e6616d680a8e4
BLAKE2b-256 edc6b64fb5b52d694738375489d74b5c34b46c2afc0f52091da86238ed2c081d

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page