Skip to main content

fluss

PyPI version Maintenance Maintainer PyPI pyversions PyPI download month

The python client for fluss, the Arkitekt workflow service: designing, storing and running workflows (flows) that wire the actions of your apps together.

Installation

pip install fluss

The flow executor is an optional extra, because it needs rekuest while the plain client does not:

pip install "fluss[engine]"   # run flows (fluss.engine)
pip install "fluss[python]"   # also run flows written as Python source

With arkitekt, pip install "arkitekt[rekuest,fluss]" brings it in.

Design

A flow is a graph: argument nodes feed reactive and action nodes, whose outputs reach return nodes. Flows live in workspaces, and every execution of a flow is a run. fluss is the client for that graph — it queries and mutates flows, workspaces and runs on the fluss server — and fluss.engine is what executes one.

Usage

Every fluss operation is a method of the Fluss client, in a blocking and an a-prefixed async flavour (fluss.get_flow(id), await fluss.aget_flow(id)).

In an arkitekt app

Add the service to your app and ask for fluss: Fluss; the client is injected by annotation. Flows and runs travel between actions by id (@fluss/flow, @fluss/run, @fluss/pythonflow, @fluss/pythonrun), so an action can take and return them directly:

from arkitekt import App, run
from fluss import Fluss, fluss_service
from fluss.api.schema import Flow

app = App("flow-inspector", "0.1.0", services=[fluss_service])


@app.action
def describe_flow(flow: Flow, fluss: Fluss) -> str:
    """Describe Flow"""
    return f"{flow.title} in workspace {flow.workspace.id}"


if __name__ == "__main__":
    run(app)

An app built with the fluss service also offers the generic Run Flow action (interface run_flow), so it can execute any flow it is handed (Run Python Flow too, with the python extra).

From a script

from arkitekt import easy
from fluss import fluss_service

with easy("my-script", fluss_service) as fluss:
    for flow in fluss.flows(limit=10):
        print(flow.id, flow.title)

The engine

fluss.engine executes a flow as a generic rekuest action: given a flow and a dict of arguments it yields the flow's returns, so a workflow can be called like any other action.

A flow run is registered as a rekuest workflow: if the agent running it dies, it is resumed, and the node calls that already finished return their recorded results instead of running again. Each call is keyed by its node and how often that node ran, so concurrent branches are found again whichever order they finish in.

from fluss.engine import run_flow, arun_flow

It imports rekuest at module level, so install fluss[engine] to use it. Importing plain fluss never requires rekuest.

Python flows

fluss.engine.python (the python extra) validates and runs flows written as Python source in a Monty sandbox: async def main(...) calls the actions of its manifest by alias.

  • Run Python Flow is a workflow too. Each action call is keyed by the action, a digest of its arguments and how often that exact call was made before, so a resumed run finds its calls again without depending on how its gathered calls interleave. The sandbox's random seed is fixed per run, so the run makes the same calls again. One case remains: identical calls in parallel branches may trade results on resume. The calls downstream of them then run again, which repeats an IRREVERSIBLE action if one is among them.
  • Its actor shares one Monty worker pool across runs. print output reaches the task log while the run goes on. A cancelled run cancels the calls it has in flight and ends CANCELLED.
  • Publishing a version makes it runnable, not an action. To call a version like any action, deploy it onto an agent that hosts run_python_flow:
from fluss.engine.python.client import acreate_python_flow_from_source, adeploy_python_flow, amanifest

actions = await amanifest({"segment": segment_hash}, rekuest)
flow = await acreate_python_flow_from_source(source, actions, fluss, title="Segment", publish=True)
await adeploy_python_flow(flow, rekuest, runner=run_python_flow_implementation_id)

Testing

uv run pytest -m "not integration"   # no server needed
uv run pytest -m integration          # a real fluss server via dokker

See RELEASING.md for how versions are cut.

Metadata

Release files for fluss 6.0.0

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

Source distribution (sdist)

Source distribution for fluss 6.0.0
File Size Uploaded
fluss-6.0.0.tar.gz 91.0 kB Details

Built distribution (wheel)

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

Total release size: 201.3 kB

Release files / fluss-6.0.0.tar.gz

Download URL fluss-6.0.0.tar.gz
Size 91.0 kB
Tags Source
SHA-256 checksum
How to use checksums
6fd2fc43a38d121b310e01d73d70ff5616c6809f3c8daee79785936293ce907d
BLAKE2b-256 checksum
How to use checksums
c22c279c459f240d26fb866f7a5ad6cce482389d99167bdb9e83b6e2f56e4250
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.13.1 {"installer":{"name":"uv","version":"0.13.1","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / fluss-6.0.0-py3-none-any.whl

Download URL fluss-6.0.0-py3-none-any.whl
Size 110.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
fcf91ef97b0555179e1bd0a15fd8d83851d5892586f7cd2767b70091478a2ff0
BLAKE2b-256 checksum
How to use checksums
fd222a87998e3732231e9dd98a810c327ad63d7211881c80da4be5ef3fd30d87
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.13.1 {"installer":{"name":"uv","version":"0.13.1","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release history Release notifications | RSS feed

This release

6.0.0 This release

2 release files

5.0.0

2 release files

4.3.2

2 release files

4.3.1

2 release files

4.3.0

2 release files

4.2.0

2 release files

4.1.0

2 release files

4.0.0

2 release files

3.1.0

2 release files

3.0.0

2 release files

2.0.1

2 release files

2.0.0

2 release files

0.1.61

2 release files

0.1.60

2 release files

0.1.59

2 release files

0.1.58

2 release files

0.1.57

2 release files

0.1.55

2 release files

0.1.54

2 release files

0.1.53

2 release files

0.1.52

2 release files

0.1.51

2 release files

0.1.46

2 release files

0.1.45

2 release files

0.1.44

2 release files

0.1.43

2 release files

0.1.42

2 release files

0.1.41

2 release files

0.1.39

2 release files

0.1.36

2 release files

0.1.35

2 release files

0.1.33

2 release files

0.1.32

2 release files

0.1.31

2 release files

0.1.30

2 release files

0.1.29

2 release files

0.1.28

2 release files

0.1.27

2 release files

0.1.26

2 release files

0.1.25

2 release files

0.1.24

2 release files

0.1.21

2 release files

0.1.20

2 release files

0.1.17

2 release files

0.1.16

2 release files

0.1.13

2 release files

0.1.12

2 release files

0.1.11

2 release files

0.1.10

2 release files

0.1.9

2 release files

0.1.8

2 release files

0.1.7

2 release files

0.1.6

2 release files

0.1.5

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

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