Counter¶
Let’s build a simple counter using Burr. When the counter terminates, print the count and the current time.
Imports¶
import datetime
from burr.core import action, State, ApplicationBuilder, expr
Define actions¶
We define the function increment()
that has a State
as input and outputs a new State
. The decorator @action
specifies it’s a Burr action and it will need to read and write from the counter
attribute in State
.
@action(reads=["counter"], writes=["counter"])
def increment(state: State) -> State:
"""Increment the counter by 1"""
# get the value from the `state`
current_count = state["counter"]
current_count += 1
print("Count: ", current_count)
# use `.update()` to create a new `State`
return state.update(counter=current_count)
@action(reads=["counter"], writes=[])
def exit_counter(state: State) -> State:
"""Print the current count and the current time"""
current_count = state["counter"]
print(f"Finished counting to {current_count} at {datetime.datetime.now():%H:%M:%S %Y-%m-%d}")
return state
Build the Application
¶
We pass the action to the ApplicationBuilder
via .with_actions()
. Then, we specify the valid transitions between actions: increment -> increment
and increment -> exit_counter
. The expr
ession construct specifies to use the transition increment -> increment
whenever the counter
value in state is under ten. Then, default to increment -> exit_counter
to terminate the application. We also use .with_entrypoint()
to define where to start and .with_state()
to set the starting state value.
app = (
ApplicationBuilder()
.with_actions(increment, exit_counter)
.with_transitions(
("increment", "increment", expr("counter < 10")),
("increment", "exit_counter"),
)
.with_state(counter=0)
.with_entrypoint("increment")
.build()
)
app.visualize(include_conditions=True)
action_obj, result, state = app.run(halt_after=["exit_counter"])
Count: 1
Count: 2
Count: 3
Count: 4
Count: 5
Count: 6
Count: 7
Count: 8
Count: 9
Count: 10
Finished counting to 10 at 18:44:29 2024-08-26