Skip to content

Package structure: core vs optional

PyStator is split into a core FSM library and optional layers (REST API, DB, UI, schedulers). You can use the core alone; add extras when you need them.

Core (always installed)

The core is the state machine library. Everything you need to define and run FSMs lives here.

Area Modules / components Purpose
Machine & instance StateMachine, EntitySession Load FSM from YAML/dict; run stateless process() or stateful instance.send().
Events & types Event, State, Transition, TransitionResult, GuardSpec, ActionSpec, etc. Events and immutable FSM value types.
Guards & actions GuardRegistry, GuardEvaluator, ActionRegistry, ActionExecutor Register and run guards and actions by name.
Config config.loader, config.models, config.converter, config.validator Load/validate YAML or dict and convert to internal types.
Stores StateStore, AsyncStateStore, InMemoryStateStore (in stores/) Protocol and in-memory implementation for persistence.
Orchestrator Orchestrator Sandwich loop: load state by entity ID → process → persist → run actions (optional scheduler).
Hooks TransitionObserver, LoggingHook, MetricsCollector Observability and metrics.
Visualization to_mermaid, to_dot, etc. Generate diagrams from FSM config.
Errors FSMError, ConfigurationError, InvalidTransitionError, etc. Exception hierarchy.

Internal implementation details (not part of the public API) live in modules prefixed with _: _types, _engine, _hierarchy, _parallel. You typically use the public classes and functions only.

Install: pip install pystator (core is always present).


Optional (extras)

These components build on the core and are optional. Install them only if you need REST API, DB persistence, web UI, or specific schedulers.

Extra Install What it adds
API pip install pystator[api] REST API server (pystator api): validate config, process events, CRUD machines. Uses FastAPI, optional DB.
Worker (included with base install; requires DB at runtime) Long-running event processor (pystator worker): polls worker_events table, claims events, runs Orchestrator, persists state. Use submit_event() to enqueue from API or scripts. See Worker.
DB / migrations (included with base install; optional at runtime) Alembic migrations and SQLAlchemy models for storing machine definitions, entity state, and worker_events. Used by the API and Worker when a DB is configured.
UI (served by API when running pystator api) Web UI for editing FSM config and triggering events.
Schedulers (included in base install) scheduler/: AsyncioScheduler, RedisScheduler, CeleryScheduler for delayed transitions (after: "5s"). Use with the Orchestrator.
Postgres pip install pystator[postgres] PostgreSQL driver for postgresql:// DB URLs.
Recipes pip install pystator[recipes] Helpers such as inline guard expression evaluation (e.g. expr: "fill_qty >= order_qty").
Dev pip install pystator[dev] Testing and release tooling.

Directory layout in the source tree:

  • Core: machine.py, instance.py, event.py, errors.py, guards.py, actions.py, hooks.py, orchestrator.py, visualization.py, _types.py, _engine.py, _hierarchy.py, _parallel.py, config/, stores/.
  • Optional: api/ (REST API), worker/ (event-processing service, worker_events, submit_event), db/ (migrations, models), ui/ (frontend), scheduler/ (scheduler adapters; code is in base install but you only need it for delayed transitions).

When to use what

  • Only core: Define FSMs in YAML, use StateMachine.from_yaml() and either machine.process() (stateless) or machine.create()EntitySession.send() (stateful in memory). Add a StateStore and Orchestrator when you need persistence by entity ID.
  • Core + API: Run pystator api to expose validate/process and optional machine CRUD over HTTP. Requires pystator[api].
  • Core + Worker: Run pystator worker to process events from the worker_events queue; enqueue events with submit_event(). Requires a database (migrations for worker_events and entity_states). See Worker.
  • Core + schedulers: Use an Orchestrator with AsyncioScheduler, RedisScheduler, or CeleryScheduler for delayed transitions. Scheduler code is in the base package; Redis/Celery may need extra dependencies.

See Concepts for the three ways to run a machine (EntitySession, stateless process, Orchestrator).