Skip to main content

Action decomposition and execution framework

Project description

Action Trees

coverage build status


Documentation: https://roxautomation.gitlab.io/action-trees

Source Code: https://gitlab.com/roxautomation/action-trees


Summary

Action Trees is a Python framework for orchestrating hierarchical, asynchronous actions. It enables the structuring of complex processes into manageable, interdependent tasks that can be executed sequentially or in parallel, simplifying the management and execution of multi-step workflows.

Action Trees vs. Behavior Trees

Behavior Trees (BTs) and Action Trees (ATs) use a tree-like structure but have different goals. BTs make choices about what to do next based on current situations, which is great for tasks needing quick decisions. ATs are about executing complex tasks efficiently, with a focus on robust error-handling errors and asynchronous operation. In short, BTs are for making decisions, while ATs are for carrying out tasks effectively.

Example - Coffee maker

Let's simulate a coffee-making machine using the following action hierarchy:

- cappuccino_order
    - prepare
        - initialize
        - clean
    - make_cappuccino
        - boil_water
        - grind_coffee

An implementation would look like this:

import asyncio
from action_trees import ActionItem


class AtomicAction(ActionItem):
    """Basic machine action with no children."""

    def __init__(self, name: str, duration: float = 0.1):
        super().__init__(name=name)
        self._duration = duration

    async def _on_run(self):
        await asyncio.sleep(self._duration)


class PrepareMachineAction(ActionItem):
    """Prepare the machine."""

    def __init__(self):
        super().__init__(name="prepare")
        self.add_child(AtomicAction(name="initialize"))
        self.add_child(AtomicAction(name="clean"))

    async def _on_run(self):
        # sequentially run children
        await self.get_child("initialize").start()
        await self.get_child("clean").start()


class MakeCappuccinoAction(ActionItem):
    """Make cappuccino."""

    def __init__(self):
        super().__init__(name="make_cappuccino")
        self.add_child(AtomicAction(name="boil_water"))
        self.add_child(AtomicAction(name="grind_coffee"))

    async def _on_run(self):
        # simultaneously run children
        await self.start_children_parallel()


class CappuccinoOrder(ActionItem):
    """High-level action to make a cappuccino."""

    def __init__(self):
        super().__init__(name="cappuccino_order")
        self.add_child(PrepareMachineAction())
        self.add_child(MakeCappuccinoAction())

    async def _on_run(self):
        for child in self.children:
            await child.start()


# create root order
order = CappuccinoOrder()
# start tasks in the background
await order.start()

Development

Please develop inside the container, this will ensure all the required checks (pylint & mypy) as well as formatting (black)

If you are not familiar with devcontainers, read Developing inside a Container first

  1. Clone this repository
  2. open dir in VS Code vscode .
  3. rebuild and reopen in container (you'll need Dev Containers extension)

note: if a container with devcontainer name already exists, an error will occur. You can remove it with docker container prune -f

What goes where

  • gitlab-ci.yml - gitlab ci script
  • init_container.sh script to initialize container for development.
  • setup.py - main packge setup file
  • docs - documentation, uses mkdocs
  • install - scripts for preparing host system

Version control

Version control is done with git tags using setuptools_scm

use git tag v1.2.3 to update version number. Use git describe to show current version.

Documentation

The documentation is automatically generated from the content of the docs directory and from the docstrings of the public signatures of the source code.

run serve_docs.sh from inside the container to build and serve documentation.

note: pyreverse creates images of packages and classes in docs/uml/..

Pre-commit

optional. Add precommit install to init_container.sh if required.

This project was forked from cookiecutter template template.

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

action_trees-0.3.1.tar.gz (88.7 kB view details)

Uploaded Source

Built Distribution

action_trees-0.3.1-py3-none-any.whl (10.1 kB view details)

Uploaded Python 3

File details

Details for the file action_trees-0.3.1.tar.gz.

File metadata

  • Download URL: action_trees-0.3.1.tar.gz
  • Upload date:
  • Size: 88.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.2 CPython/3.12.1

File hashes

Hashes for action_trees-0.3.1.tar.gz
Algorithm Hash digest
SHA256 9838d749497b96b04d3d0e3148f24206d270675501f3329991df6b653dcc83f7
MD5 a8b5d66d59b282d49cb0e6a05e74bd89
BLAKE2b-256 fc1339535cb0d3888f193df14bfb68872bce2e269d6198e9477073be635a7397

See more details on using hashes here.

File details

Details for the file action_trees-0.3.1-py3-none-any.whl.

File metadata

  • Download URL: action_trees-0.3.1-py3-none-any.whl
  • Upload date:
  • Size: 10.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.2 CPython/3.12.1

File hashes

Hashes for action_trees-0.3.1-py3-none-any.whl
Algorithm Hash digest
SHA256 2f876b447faceb894595438932c5b1de15ae41ee217660cb863b0b0d2ac474c0
MD5 1d63a314bfa0b51e991b42da7e3d6afc
BLAKE2b-256 9d85f2451e8b38e362731ce8c681430367769e96cd9341fe04c1d9e6f25286bc

See more details on using hashes here.

Supported by

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