| ==================== |
| Applications |
| ==================== |
| |
| .. _applications: |
| |
| Applications form the core representation of the state machine. You build them with the ``ApplicationBuilder``. |
| |
| The ``ApplicationBuilder`` is a class that helps you build an application. Here is the minimum that is required: |
| |
| 1. A ``**kwargs`` of actions passed to ``with_actions(...)`` |
| 2. Any relevant transitions (with conditions) |
| 3. An entry point |
| |
| This is shown in the example from :ref:`getting started <simpleexample>` |
| |
| .. code-block:: python |
| |
| from burr.core import ApplicationBuilder, default, expr |
| app = ( |
| ApplicationBuilder() |
| .with_state(counter=0) # initialize the count to zero |
| .with_actions( |
| count=count, # add the counter action with the name "counter" |
| done=done # add the printer action with the name "printer" |
| ).with_transitions( |
| ("count", "count", expr("counter < 10")), # Keep counting if the counter is less than 10 |
| ("count", "done", default) # Otherwise, we're done |
| ).with_entrypoint("counter") # we have to start somewhere |
| .build() |
| ) |
| |
| |
| ------- |
| Running |
| ------- |
| |
| There are three APIs for executing an application. |
| |
| ``step``/``astep`` |
| ------------------ |
| |
| Returns the tuple of the action, the result of that action, and the new state. Call this if you want to run the application step-by-step. |
| |
| .. code-block:: python |
| |
| action, result, state = application.step() |
| |
| If you're in an async context, you can run `astep` instead: |
| |
| .. code-block:: python |
| |
| action, result, state = await application.astep() |
| |
| ``iterate``/``aiterate`` |
| ------------------------ |
| |
| Iterate just runs ``step`` in a row, functioning as a generator: |
| |
| .. code-block:: python |
| |
| for action, result, state in application.iterate(until=["final_action_1", "final_action_2"]): |
| print(action.name, result) |
| |
| You can also run ``aiterate`` in an async context: |
| |
| .. code-block:: python |
| |
| async for action, result, state in application.aiterate(): |
| print(action.name, result) |
| |
| In the synchronous context this also has a return value of a tuple of: |
| 1. the final state |
| 2. A list of the actions that were run, one for each result |
| |
| You can access this by looking at the ``value`` variable of the ``StopIteration`` exception that is thrown |
| at the end of the loop, as is standard for python. |
| See the function implementation of ``run`` to show how this is done. |
| |
| In the async context, this does not return anything |
| (asynchronous generators are not allowed a return value). |
| |
| ``run``/``arun`` |
| ---------------- |
| |
| Run just calls out to ``iterate`` and returns the final state. |
| |
| .. code-block:: python |
| |
| final_state, results = application.run(until=["final_action_1", "final_action_2"]) |
| |
| Currently the ``until`` variable is a ``or`` gate (E.G. ``any_complete``), although we will be adding an ``and`` gate (E.G. ``all_complete``), |
| and the ability to run until the state machine naturally executes (``until=None``). |