🚀 Big News: Socket Acquires Coana to Bring Reachability Analysis to Every Appsec Team.Learn more
Socket
Book a DemoInstallSign in
Socket

action-trees

Package Overview
Dependencies
Maintainers
1
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

action-trees

Action decomposition and execution framework

2.0.1
PyPI
Maintainers
1

Action Trees

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

Summary

Action Trees is an asyncio-based Python library for managing hierarchical and asynchronous tasks. It breaks down complex tasks into simpler, independent steps that can be run sequentially or in parallel.

Functionality

  • ActionItem Class: Central class for representing tasks, supporting states like INITIALIZING, RUNNING, PAUSED, and FAILED.
  • Task Management: Provides APIs to start, pause, resume, and cancel tasks asynchronously.
  • Hierarchical Actions: Actions can have child actions, supporting structured, tree-like task management.
  • Parallel Execution: Supports running child tasks concurrently using asyncio.
  • State and Exception Handling: Handles task state transitions and exceptions, ensuring proper state flow.

Example

The following example illustrates a high-level task to prepare and make a cappuccino using the ActionItem class:

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) -> None:
        await asyncio.sleep(self._duration)

class PrepareMachineAction(ActionItem):
    """Prepare the machine."""
    def __init__(self) -> None:
        super().__init__(name="prepare")
        self.add_child(AtomicAction(name="initialize"))
        self.add_child(AtomicAction(name="clean"))

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

class MakeCappuccinoAction(ActionItem):
    """Make cappuccino."""
    def __init__(self) -> None:
        super().__init__(name="make_cappuccino")
        self.add_child(AtomicAction(name="boil_water"))
        self.add_child(AtomicAction(name="grind_coffee"))

    async def _on_run(self) -> None:
        await self.run_children_parallel()

class CappuccinoOrder(ActionItem):
    """High-level action to make a cappuccino."""
    def __init__(self) -> None:
        super().__init__(name="cappuccino_order")
        self.add_child(PrepareMachineAction())
        self.add_child(MakeCappuccinoAction())

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

async def main() -> None:
    order = CappuccinoOrder()
    await order.start()
    order.display_tree()

if __name__ == "__main__":
    asyncio.run(main())

This code creates a hierarchical task to prepare a machine and make a cappuccino, with some actions running sequentially and others in parallel.

More examples : see examples

State transitions

ActionItem contains a state machine with these transitions. (spec from VDA5050)

FAQs

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts