Skip to main content

simplestate

Simplestate helps developers create and manage finite state machines in the simplest way possible—focusing solely on states and transitions, leaving out complex event systems.

Features

  • Focus on states and transitions.
  • Minimalistic and easy to use.
  • Supports entering-state handlers for additional functionality.

Installation

To install simplestate,

use poetry:

poetry add simplestate

use pip:

pip install simplestate

Usage Example

Here's a basic example of using simplestate:

m[state] + action >> next_state

from simplestate import StateMachine

m = StateMachine("loading")          # Define the machine with an initial state
m["loading"] + "error" >> "failed"   # Transition from loading to failed on "error"
m["loading"] + "ok"    >> "success"  # Transition from loading to success on "ok"
m["?"]       + "back"  >> "loading"  # Any state transitions to loading on "back"

# Start the machine
m.start()  # adjust inital state by this m.start(at_state="ok")
assert m.current == "loading"

# Trigger transitions
m.handle("ok")
assert m.current == "success"

m.handle("back")
assert m.current == "loading"

m.handle("back")
assert m.current == "loading"

# Trigger transitions with context
m.handle("error", error="Something went wrong")
assert m.current == "failed"

Why Simplestate?

The goal of simplestate is to keep finite state machines simple and focused. By eliminating complex event systems, you can easily manage states and transitions while keeping the code testable and maintainable.

Event Handling on State Entry

Simplestate allows event handling when entering a state using .add_callbacks(). These callbacks take previous and an optional **input_context.

# Add handlers for entering states
m.add_callbacks({
    "loading": lambda previous: print(f"{previous} >> loading"),
    "failed": lambda previous, **input_context: print(f"{previous} >> failed: {input_context['error']}"),
    "success": lambda previous: print(f"{previous} >> success"),
})

FAQ

Q: How can I handle state exit events?
A: You can use the entering handler for the next state to handle actions when leaving the previous state.

def on_state_x(previous, **input_context):
    if previous == "a":
        do_this()
    elif previous == "b":
        do_that()

Q: Can I represent the state machine as a class?
A: Yes! Think of simplestate as a state manager. You can compose it within your own class for handling side effects:

class TrafficLight:
    def __init__(self):
        m = StateMachine("red")
        m["red"]    + "next" >> "green"
        m["green"]  + "next" >> "yellow"
        m["yellow"] + "next" >> "red"
        m.start()

        self.machine = m

    def display(self) -> str:
        return self.machine.current

    def next(self) -> None:
        self.machine.handle("next")

if __name__ == '__main__':
    light = TrafficLight()

    while True:
        state = light.display()
        print(state)

        # pause for a few seconds
        match state:
            case "red" | "green":
                time.sleep(30)
            case "yellow":
                time.sleep(5)

        # transition
        light.next()

Tests

To run the tests:

poetry install --with test
poetry run pytest

Contribution

Contributions are welcome! Feel free to open an issue or submit a pull request.

  1. Install devcontainer
  2. Open this project in dev container
  3. Run poetry shell
  4. Run poetry install --with test
  5. Run poetry run pytest

License

This project is licensed under a free, open-source license.

Metadata

Release files for simplestate 0.1.5

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for simplestate 0.1.5
File Size Uploaded
simplestate-0.1.5.tar.gz 7.2 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for simplestate 0.1.5
File Interpreter ABI Platform
simplestate-0.1.5-py3-none-any.whl Python 3 none any Details

Total release size: 15.4 kB

Release files / simplestate-0.1.5.tar.gz

Download URL simplestate-0.1.5.tar.gz
Size 7.2 kB
Tags Source
SHA-256 checksum
How to use checksums
c07ee32da4220184d6718c245ef7ad642141741adb1f44282c3d98e494df713e
BLAKE2b-256 checksum
How to use checksums
d92d01f0b32ad2d7d30dab90431b3cf0026679a8532a6ea46498c3efd2ac8864
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/5.1.1 CPython/3.9.19

Release files / simplestate-0.1.5-py3-none-any.whl

Download URL simplestate-0.1.5-py3-none-any.whl
Size 8.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
bea93fbcaa758588257c79c56a28293ee753512e771971dcf10032d48b4d3993
BLAKE2b-256 checksum
How to use checksums
513fcb92fa4c159528531fdd74eac0f88453f5fac1f6ccd4cb7799b16da38c83
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/5.1.1 CPython/3.9.19

Release history Release notifications | RSS feed

This release

0.1.5 This release

2 release files

0.1.4

2 release files

0.1.3

2 release files

0.1.2

2 release files

0.1.1

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page