Skip to main content

tongflow

The Python SDK for TongFlow — an open-source, multi-modal GenAI workflow studio.

pip install tongflow gives you the tongflow import package. It has two uses:

  1. Run workflows — execute a workflow exported from the TongFlow canvas as an embedded engine, straight from Python (no desktop app needed).
  2. Author plugins — implement node capabilities against TongFlow's ABI contract.

Install

pip install tongflow

Requires Python 3.10+. The SDK is backend-neutral: it depends only on pydantic and typing_extensions, and never imports modal (or any other backend).

Run a workflow as an embedded engine

Build a flow on the TongFlow canvas, export it (Export Executable → *.executable.json), then run it from Python:

from tongflow import run_workflow

result = run_workflow(
    "my-flow.executable.json",
    inputs={"input_ab12cd34": {"texts": ["a cute cat"]}},  # keyed by WorkflowInput.name
    auto_install=True,   # clone missing plugins + provision a shared venv
)

print(result["status"])            # "success" | "failed"
print(result["outputs"])           # {nodeId -> ABI output}
print(result["outputs_by_name"])   # {output name -> [values]}

run_workflow reads the exported plan (already topologically sorted, with resolved bindings and output routes), materializes asset inputs, spawns each plugin's local entry.py, and returns each node's output. With auto_install=True it clones any missing plugins ({org}/{pluginId}.git, default org https://github.com/tong-io; override per plugin via plugin_git_urls=) and installs tongflow plus each plugin's requirements.txt into a shared venv. It stays backend-neutral — a deploy-first plugin's entry.py deploys-once and invokes its remote backend.

Outputs are inline by default (inline_outputs=True): outputs and intermediate assets stay in memory, and binary results come back as {bytesBase64, mime, filename} — nothing is written for them. Pass inline_outputs=False (optionally with out_dir=) to spill binaries to disk and get file_key paths instead.

From another process (any language)

python -m tongflow engine is the same engine behind an NDJSON bridge: write one JSON request to stdin, read events on stdout. This is how the TongFlow app — and any external host built on the tongflow npm package's exporter — runs workflows.

// stdin (one JSON document)
{"workflow": {...executable workflow...},
 "inputs": {"input_ab12cd34": {"texts": ["a cute cat"]}},
 "options": {"auto_install": true, "inline_outputs": false, "out_dir": "./out",
             "env": {"OPENAI_API_KEY": "..."}}}   // extra env for every plugin process
// stdout (NDJSON)
{"ready": {"version": "0.3.0"}}
{"event": {"type": "workflow_started", ...}}
{"event": {"type": "node_completed", "nodeId": "...", "output": {...}}}
{"result": {"status": "success", "outputs": {...}, "outputs_by_name": {...}}}

Other subcommands: python -m tongflow scan [--root plugins] [--abi file] prints the plugin registry JSON (the ABI defaults to the copy bundled with the SDK) and python -m tongflow version prints the SDK version.

Where it writes to disk

Defaults follow the desktop app's per-user directory, so the SDK and the app share plugins/venv and the SDK does not pollute your working directory:

What Default location Override
Cloned plugins <user-data>/plugins plugins_dir= / TONGFLOW_PLUGINS_DIR
Shared plugin venv <user-data>/data/.tongflow/plugin-venv data_dir= / TONGFLOW_DATA_DIR
Binary outputs none by default (kept in memory) inline_outputs=False, out_dir=

<user-data> is ~/Library/Application Support/TongFlow (macOS), %APPDATA%\TongFlow (Windows), or $XDG_DATA_HOME/TongFlow (Linux).

Author a plugin

A plugin is a small Python package that implements one or more ABI node slots. Annotate each slot method with the generated types and mark it with @node_slot:

from tongflow.slots import node_slot
from tongflow.node_slots import NodeSlots
from tongflow.models.gen_text import GenTextInput, GenTextOutput

@node_slot(NodeSlots.GEN_TEXT)
def gen_text(input: GenTextInput) -> GenTextOutput:
    answer = my_llm(input.text)              # attribute access; types come from the ABI
    return GenTextOutput(success=True, text=answer)

The platform runs each plugin's entry.py, exchanging ABI JSON over stdin/stdout. @node_slot deep-constructs the incoming dict into a typed BaseModel and dumps your returned model back to a dict — plugin code never sees or produces a raw dict.

A plugin comes in one of two shapes, decided purely by its files (the scanner detects them from code — it does not look at the plugin's name):

  • Self-contained — ships an entry.py that does the work in-process.
  • Deploy-first — ships a deploy.py whose handler class is marked @deploy, plus a thin entry.py bridge (identical across deploy-first plugins — copy it from any reference plugin) that deploys once and invokes the remote backend, plus a requirements.txt for that backend. Example using Modal:
import modal
from pathlib import Path
from tongflow import deploy
from tongflow.slots import node_slot
from tongflow.node_slots import NodeSlots
from tongflow.models.gen_text import GenTextInput, GenTextOutput

app = modal.App(Path(__file__).resolve().parent.name)

@deploy                      # tongflow's backend-neutral marker; the scanner detects it via AST
@app.cls(...)
class Inference:
    @modal.method()
    @node_slot(NodeSlots.GEN_TEXT)
    def gen(self, input: GenTextInput) -> GenTextOutput: ...

Naming is a separate convention, unrelated to the two shapes above. Where the work actually runs (locally, on Modal, on another cloud) is the plugin's own concern, and the name prefix carries no execution meaning. Plugin repos are named tongflow-<label>-<name> — for example tongflow-api-openai or tongflow-modal-ltx. These are only naming examples; the prefix does not decide whether a plugin is self-contained or deploy-first.

Pin the SDK in your plugin's image build (pip_install("tongflow==0.1.0")) to match the version you develop against.

👉 Full plugin guide — directory layout, the ABI, generated model conventions, and how to publish: docs/plugins.md.

Build & publish (maintainers)

From the repo root:

export TWINE_USERNAME=__token__
export TWINE_PASSWORD=pypi-xxxxxxxx   # https://pypi.org/manage/account/token/
pnpm tongflow:publish

Runs scripts/publish-tongflow-pypi.sh (clean, python -m build, twine check, twine upload). Dry-run to TestPyPI with TONGFLOW_UPLOAD_TESTPYPI=1 pnpm tongflow:publish.

License

AGPL-3.0 — see LICENSE. The whole project is dual-licensed under AGPL-3.0 / a commercial license; see COMMERCIAL-LICENSE.md or contact business@tongflow.com.

Release files for tongflow 0.3.3

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

Source distribution (sdist)

Source distribution for tongflow 0.3.3
File Size Uploaded
tongflow-0.3.3.tar.gz 90.5 kB Details

Built distribution (wheel)

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

Total release size: 196.2 kB

Release files / tongflow-0.3.3.tar.gz

Download URL tongflow-0.3.3.tar.gz
Size 90.5 kB
Tags Source
SHA-256 checksum
How to use checksums
73db52ae69559c565d2809370f479eb6ec4b1f8705cc1f86c17f220bf41439ec
BLAKE2b-256 checksum
How to use checksums
46a7fc2b2887f1ba997d1821bec597073b88547b9061124ad1834e441bda6e38
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.13

Release files / tongflow-0.3.3-py3-none-any.whl

Download URL tongflow-0.3.3-py3-none-any.whl
Size 105.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
3358055bb134f11739f36b05e39bf175a11db42da016430e638ae4f6e874df16
BLAKE2b-256 checksum
How to use checksums
48b86e615cc98a7289dbb9a04a0d915a1608a7f75fcca186d94fa3ecd34b542a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.13

Release history Release notifications | RSS feed

0.3.4

2 release files

This release

0.3.3 This release

2 release files

0.3.2

2 release files

0.3.1

2 release files

0.3.0

2 release files

0.2.20

2 release files

0.2.19

2 release files

0.2.18

2 release files

0.2.17

2 release files

0.2.16

2 release files

0.2.15

2 release files

0.2.14

2 release files

0.2.13

2 release files

0.2.12

2 release files

0.2.11

2 release files

0.2.10

2 release files

0.2.9

2 release files

0.2.8

2 release files

0.2.7

2 release files

0.2.6

2 release files

0.2.5

2 release files

0.2.4

2 release files

0.2.3

2 release files

0.2.2

2 release files

0.2.1

2 release files

0.2.0

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