simplestate


Namesimplestate JSON
Version 0.1.5 PyPI version JSON
download
home_pagehttps://pypi.org/project/simplestate
SummaryA simple stupid, declarative finite state machine for Python.
upload_time2024-08-19 04:38:21
maintainerNone
docs_urlNone
authorpanupong-puttarathamrongkul
requires_python<4.0,>=3.10
licenseApache-2.0
keywords finite state machine simplestate
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # 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:

```bash
poetry add simplestate
```

use pip:
```bash
pip install simplestate
```

## Usage Example

Here's a basic example of using **simplestate**:

m[`state`] + `action` >> `next_state`

```python
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`.
```python
# 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.

```python
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:

```python
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:

```bash
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](https://code.visualstudio.com/docs/devcontainers/containers)
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.


            

Raw data

            {
    "_id": null,
    "home_page": "https://pypi.org/project/simplestate",
    "name": "simplestate",
    "maintainer": null,
    "docs_url": null,
    "requires_python": "<4.0,>=3.10",
    "maintainer_email": null,
    "keywords": "finite state machine, simplestate",
    "author": "panupong-puttarathamrongkul",
    "author_email": "54784627+panupong-puttarathamrongkul@users.noreply.github.com",
    "download_url": "https://files.pythonhosted.org/packages/d9/2d/01f0b32ad2d7d30dab90431b3cf0026679a8532a6ea46498c3efd2ac8864/simplestate-0.1.5.tar.gz",
    "platform": null,
    "description": "# simplestate\n\n**Simplestate** helps developers create and manage finite state machines in the simplest way possible\u2014focusing solely on states and transitions, leaving out complex event systems.\n\n## Features\n\n- Focus on states and transitions.\n- Minimalistic and easy to use.\n- Supports entering-state handlers for additional functionality.\n\n## Installation\n\nTo install simplestate, \n\nuse poetry:\n\n```bash\npoetry add simplestate\n```\n\nuse pip:\n```bash\npip install simplestate\n```\n\n## Usage Example\n\nHere's a basic example of using **simplestate**:\n\nm[`state`] + `action` >> `next_state`\n\n```python\nfrom simplestate import StateMachine\n\nm = StateMachine(\"loading\")          # Define the machine with an initial state\nm[\"loading\"] + \"error\" >> \"failed\"   # Transition from loading to failed on \"error\"\nm[\"loading\"] + \"ok\"    >> \"success\"  # Transition from loading to success on \"ok\"\nm[\"?\"]       + \"back\"  >> \"loading\"  # Any state transitions to loading on \"back\"\n\n# Start the machine\nm.start()  # adjust inital state by this m.start(at_state=\"ok\")\nassert m.current == \"loading\"\n\n# Trigger transitions\nm.handle(\"ok\")\nassert m.current == \"success\"\n\nm.handle(\"back\")\nassert m.current == \"loading\"\n\nm.handle(\"back\")\nassert m.current == \"loading\"\n\n# Trigger transitions with context\nm.handle(\"error\", error=\"Something went wrong\")\nassert m.current == \"failed\"\n```\n\n## Why Simplestate?\n\nThe 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.\n\n### Event Handling on State Entry\n\nSimplestate allows event handling when entering a state using `.add_callbacks()`. These callbacks take `previous` and an optional `**input_context`.\n```python\n# Add handlers for entering states\nm.add_callbacks({\n    \"loading\": lambda previous: print(f\"{previous} >> loading\"),\n    \"failed\": lambda previous, **input_context: print(f\"{previous} >> failed: {input_context['error']}\"),\n    \"success\": lambda previous: print(f\"{previous} >> success\"),\n})\n```\n\n## FAQ\n\n**Q: How can I handle state exit events?**  \nA: You can use the entering handler for the next state to handle actions when leaving the previous state.\n\n```python\ndef on_state_x(previous, **input_context):\n    if previous == \"a\":\n        do_this()\n    elif previous == \"b\":\n        do_that()\n```\n\n**Q: Can I represent the state machine as a class?**  \nA: Yes! Think of simplestate as a state manager. You can compose it within your own class for handling side effects:\n\n```python\nclass TrafficLight:\n    def __init__(self):\n        m = StateMachine(\"red\")\n        m[\"red\"]    + \"next\" >> \"green\"\n        m[\"green\"]  + \"next\" >> \"yellow\"\n        m[\"yellow\"] + \"next\" >> \"red\"\n        m.start()\n\n        self.machine = m\n\n    def display(self) -> str:\n        return self.machine.current\n\n    def next(self) -> None:\n        self.machine.handle(\"next\")\n\nif __name__ == '__main__':\n    light = TrafficLight()\n\n    while True:\n        state = light.display()\n        print(state)\n\n        # pause for a few seconds\n        match state:\n            case \"red\" | \"green\":\n                time.sleep(30)\n            case \"yellow\":\n                time.sleep(5)\n\n        # transition\n        light.next()\n```\n\n## Tests\n\nTo run the tests:\n\n```bash\npoetry install --with test\npoetry run pytest\n```\n\n## Contribution\n\nContributions are welcome! Feel free to open an issue or submit a pull request.\n\n1. Install [devcontainer](https://code.visualstudio.com/docs/devcontainers/containers)\n2. Open this project in dev container\n3. Run `poetry shell`\n4. Run `poetry install --with test`\n5. Run `poetry run pytest`\n\n## License\n\nThis project is licensed under a free, open-source license.\n\n",
    "bugtrack_url": null,
    "license": "Apache-2.0",
    "summary": "A simple stupid, declarative finite state machine for Python.",
    "version": "0.1.5",
    "project_urls": {
        "Homepage": "https://pypi.org/project/simplestate",
        "Repository": "https://github.com/panupong-develop/simplestate"
    },
    "split_keywords": [
        "finite state machine",
        " simplestate"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "513fcb92fa4c159528531fdd74eac0f88453f5fac1f6ccd4cb7799b16da38c83",
                "md5": "cf9beb125c55ed04617b4b227d1b0ac5",
                "sha256": "bea93fbcaa758588257c79c56a28293ee753512e771971dcf10032d48b4d3993"
            },
            "downloads": -1,
            "filename": "simplestate-0.1.5-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "cf9beb125c55ed04617b4b227d1b0ac5",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": "<4.0,>=3.10",
            "size": 8163,
            "upload_time": "2024-08-19T04:38:20",
            "upload_time_iso_8601": "2024-08-19T04:38:20.364920Z",
            "url": "https://files.pythonhosted.org/packages/51/3f/cb92fa4c159528531fdd74eac0f88453f5fac1f6ccd4cb7799b16da38c83/simplestate-0.1.5-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "d92d01f0b32ad2d7d30dab90431b3cf0026679a8532a6ea46498c3efd2ac8864",
                "md5": "8bf8e0257e48c20b4bf087a0663032ae",
                "sha256": "c07ee32da4220184d6718c245ef7ad642141741adb1f44282c3d98e494df713e"
            },
            "downloads": -1,
            "filename": "simplestate-0.1.5.tar.gz",
            "has_sig": false,
            "md5_digest": "8bf8e0257e48c20b4bf087a0663032ae",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": "<4.0,>=3.10",
            "size": 7202,
            "upload_time": "2024-08-19T04:38:21",
            "upload_time_iso_8601": "2024-08-19T04:38:21.708341Z",
            "url": "https://files.pythonhosted.org/packages/d9/2d/01f0b32ad2d7d30dab90431b3cf0026679a8532a6ea46498c3efd2ac8864/simplestate-0.1.5.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-08-19 04:38:21",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "panupong-develop",
    "github_project": "simplestate",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "lcname": "simplestate"
}
        
Elapsed time: 0.76338s