Package: kiwi-cogs
Kiwi CogsA simple and easy to use state machine library.Github repository:https://github.com/mopeyjellyfish/KiwiCogs/Documentationhttps://mopeyjellyfish.github.io/KiwiCogs/InstallationPippipinstall-Ukiwi-cogsPoetrypoetryaddkiwi-cogsQuick startEventsExample configuration:light_config={"name":"lights","initial":"green","states":{"green":{"events":{"NEXT":{"target":"yellow"}},},"yellow":{"events":{"NEXT":{"target":"red"}}},"red":{"events":{"NEXT":{"target":"green"}}},},}Usage:light_machineawaitMachine.create(light_config)asserttraffic_light.initial_state.value=="green"yellow_state=awaittraffic_light.event("NEXT")assertyellow_state.value=="yellow"red_state=awaittraffic_light.event("NEXT")assertred_state.value=="red"green_state=awaittraffic_light.event("NEXT")assertgreen_state.value=="green"TransitionsExample configuration:asyncdefentered(_):print("entered state!")asyncdeflog(_):print("LOG!")defexited(_):print("exited!")defis_adult(context,_):age=context.get("age")returnageisnotNoneandage>=18defis_child(context,_):age=context.get("age")returnageisnotNoneandage<18deflog_age(context):age=context.get("age")print(f"User is{age}old!")defage_determined(context):age=context.get("age")print(f"Users age has been determined as:{age}")age_config={"name":"age","context":{"age":None},# age unknown"initial":"unknown","states":{"unknown":{"transitions":[{"target":"adult","cond":is_adult},{"target":"child","cond":is_child},],"entry":[log,entered],"exit":age_determined,},"adult":{"type":"final","entry":log_age},"child":{"type":"final","entry":log_age},},}Usage:age_machineawaitMachine.create(age_config)assertage_machine.state.value=="unknown"context={"age":18}awaitage_machine.with_context(context=context)assertage_machine.state.value=="adult"Hierarchical machineExample configuration:defis_walking(context,_):returncontext["speed"]<=11defis_running(context,_):returncontext["speed"]>11walk_states={"initial":"start","states":{"start":{"transitions":[# resolved in order{"target":"walking","cond":is_walking},{"target":"running","cond":is_running},],},"walking":{"events":{"CROSSED":{"target":"crossed"}}},"running":{"events":{"CROSSED":{"target":"crossed"}}},"crossed":{},},}pedestrian_states={"initial":"walk","states":{"walk":{"events":{"PED_COUNTDOWN":{"target":"wait"}},**walk_states},"wait":{"events":{"PED_COUNTDOWN":{"target":"stop"}}},"stop":{},"blinking":{},},}crossing_config={"name":"light","initial":"green","context":{"speed":10},"states":{"green":{"events":{"TIMER":{"target":"yellow"}}},"yellow":{"events":{"TIMER":{"target":"red"}}},"red":{"events":{"TIMER":{"target":"green"}},**pedestrian_states},},"events":{"POWER_OUTAGE":{"target":".red.blinking"},"POWER_RESTORED":{"target":".red"},},}Example usage:crossing=awaitMachine.create(crossing_config)assertcrossing.initial_state.value=="green"assertcrossing.state.type=="atomic"awaitcrossing.event("TIMER")assertcrossing.state.value=="yellow"assertcrossing.state.type=="atomic"awaitcrossing.event("TIMER")assertcrossing.state.value=={"red":{"walk":"walking"}}awaitcrossing.event("CROSSED")assertcrossing.state.value=={"red":{"walk":"crossed"}}assertcrossing.state.type=="compound"awaitcrossing.event("PED_COUNTDOWN")assertcrossing.state.value=={"red":"wait"}awaitcrossing.event("PED_COUNTDOWN")assertcrossing.state.value=={"red":"stop"}awaitcrossing.event("TIMER")assertcrossing.initial_state.value=="green"assertcrossing.state.type=="atomic"