Skip to main content

fancy-flow (Python)

The Python runtime for fancy-flow workflow graphs — the third twin of its headless TypeScript engine, alongside fancy-flow-php.

A graph an agent or human authors in <FlowEditor> runs unchanged on Python. Same JSON in, same outputs out. The editor stays the one authoring surface; Python becomes a peer runtime alongside Node and PHP.

Zero runtime dependencies. Everything the built-in nodes reach for — HTTP, an LLM, a vector store, a queue — is an injected protocol with a deterministic offline default, so a workflow app that never calls a model does not inherit a provider SDK, and every test runs without a network.

from fancy_flow import FlowRunner, RunOptions, builtin, import_workflow

builtin.register()  # install the built-in kinds
result = import_workflow(schema_json)  # WorkflowSchema v1

run = FlowRunner().run(
    result.graph,
    builtin.executors(),  # or your own bindings
    options=RunOptions(initial_inputs={"trigger-1": {"payload": body}}),
)

run.ok  # bool
run.outputs  # {node_id: value}
run.error  # str | None

Async, without two engines

Executors may be synchronous or async. The graph walk is written once and driven two ways, so branching, skipping and port routing cannot drift between them.

run = await FlowRunner().arun(graph, executors)  # awaits awaitable executors

The synchronous runner refuses an awaitable rather than storing it: a coroutine object in outputs looks like success and reaches every downstream node as a value nothing can read.

Custom nodes

Two halves, kept in sync — exactly the path every built-in takes.

from fancy_flow import ConfigField, NodeKind, ExecutorRegistry, default_registry

default_registry().register(
    NodeKind(
        name="@acme/send_invoice",
        category="io",
        label="Send invoice",
        aliases=("send_invoice",),
        config_schema=(ConfigField(type="text", key="to", label="To", required=True),),
        side_effects="unsafe-to-replay",  # a durable run gives this ONE attempt
    )
)


def send_invoice(ctx):
    return {"sent": ctx.option("to")}


executors = builtin.executors().bind("@acme/send_invoice", send_invoice)

An executor may be a callable, an object with .execute(ctx), or a class resolved through your container.

Durable runs, with no queue library

Durability is checkpoint-per-node, keyed by node id. The core owns the hard part — which node may run, and with what inputs — and a queue supplies transport and nothing else.

from fancy_flow.durable import Coordinator

flow = Coordinator(graph=graph, executors=executors, run=run_id, store=store)

ready = flow.advance()  # what is unblocked right now -> dispatch these
flow.run_node(node_id)  # claim, run through the real engine, checkpoint
flow.run_to_completion()  # or drive both, here, in this process

advance() and run_node() are the two operations a Celery / Dramatiq / Taskiq job wraps. Coordinator.run_to_completion() over a persistent NodeClaimStore is already a real durable runner: a crash resumes from the same place a crashed worker would, because the resume behaviour lives in the checkpoints rather than in the loop.

Human gates fail closed: user_input and human_approval pause because they are human nodes, not because their input port happens to be empty. Only a recorded answer for that node resumes the run.

Accepting a graph you did not write

import_workflow answers is this graph coherent? GraphPolicy answers is it safe to accept? — kind allowlists (resolved across every id a kind answers to), size caps, byte hygiene, structure, and host rules.

from fancy_flow.security import GraphPolicy

GraphPolicy.untrusted(allow=["manual_trigger", "transform", "output"]).assert_safe(schema)

Parity

The guarantee is asserted, not asserted-to. The suite runs the shared shared/expr and shared/satisfies-range tables from fancy-conformance, the 23 golden WorkflowSchema fixtures, and — because a queued run derives readiness from the opposite end — every one of those fixtures a second time through the per-node durable driver.

python -m pip install -e . --group dev
pytest

Status

Pre-1.0: breaking changes land in minor releases. See CHANGELOG.md and, for how the package is built and what is staged next, AGENTS.md.

MIT.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

fancy_flow-0.2.0.tar.gz (122.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

fancy_flow-0.2.0-py3-none-any.whl (101.9 kB view details)

Uploaded Python 3

File details

Details for the file fancy_flow-0.2.0.tar.gz.

File metadata

  • Download URL: fancy_flow-0.2.0.tar.gz
  • Upload date:
  • Size: 122.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for fancy_flow-0.2.0.tar.gz
Algorithm Hash digest
SHA256 8181d30771b5f5b75e886d1a741810a373652e0c20f309044d8d103fd5f01d5a
MD5 eecb5ffb2fd47f42d133d798c1e21f24
BLAKE2b-256 5dae41346be2acb57a8dfcf45523681736eeee8de383fdfa58f23d8f59762248

See more details on using hashes here.

Provenance

The following attestation bundles were made for fancy_flow-0.2.0.tar.gz:

Publisher: publish.yml on Particle-Academy/fancy-flow-py

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file fancy_flow-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: fancy_flow-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 101.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for fancy_flow-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 9433303fda44aebcb56e9b53ac721941de2b5dbf2e1b32c682d8ebc5a9caa877
MD5 e6f761cc76ca0e4ab8c3246e69bf03d2
BLAKE2b-256 4554898f52f2c7490e0b9c45a3b496089cf12e04854cbbeb6868ea447c98a8a6

See more details on using hashes here.

Provenance

The following attestation bundles were made for fancy_flow-0.2.0-py3-none-any.whl:

Publisher: publish.yml on Particle-Academy/fancy-flow-py

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

0.3.0

2 files

This release

0.2.0 This release

2 files

0.1.0

2 files

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page