Skip to main content

PyO3-backed Manyfold RFC scaffolding and in-memory runtime.

Project description

manyfold

A schematic logical board with overlapping graph regions and circuit-style routes

Manyfold is a component library for execution graphs.

It helps make graph-shaped programs easier to build, inspect, and explain. Routes, schemas, buffers, demand, time, payload access, writes, taints, and lineage are modeled as graph concerns instead of being hidden in callback code or queue configuration.

Think of it as a logical board: routes are traces, ports are pads, components shape execution, and overlapping regions show where ownership, policy, and data flow meet.

This repository is an RFC-stage Python package with a PyO3/Rust extension. It is not a production runtime yet, but the package is runnable and the examples exercise the supported surface.

Start Fast

uv sync
uv run python examples/simple_latest.py
uv run python -m unittest tests.test_examples

A Small Graph in Motion

Publish Values

from dataclasses import dataclass

from manyfold.architecture import PubSub


@dataclass(frozen=True)
class Temperature:
    degrees: float
    unit: str


temperature = PubSub()

temperature.publish(Temperature(degrees=72.4, unit="F"))
temperature.publish(Temperature(degrees=72.9, unit="F"))
latest = temperature.latest()
latest_row = temperature.query_one(
    """
    SELECT pad_name, offset + 1 AS seq_source, degrees, unit
    FROM stream
    ORDER BY event_time DESC, process_sequence DESC
    LIMIT 1
    """
)
if latest is not None and latest_row is not None:
    print(f"latest #{latest_row['seq_source']}: {latest.degrees}{latest.unit}")

Output:

latest #2: 72.9F

When a topic matters, pass it explicitly. Dotted topics keep the same ownership shape as a route name:

  • owner is the component or subsystem responsible for the signal.
  • family groups related streams.
  • stream names this specific signal.

PubSub is a stream backed by PubSub delivery and a Rust SQL stream processor, so latest() is an ordinary ordered query_one(...) under the hood. If no topic is provided, the stream gets an ephemeral UUID5 topic. latest() returns a row object, so SQL-backed fields can be read as latest.degrees or latest["degrees"]. The SQL table exposes pad_name for filtering and joins. If no schema is provided, the first structured model publish fixes the stream schema lazily. Pydantic models work through their model_fields and model_dump() surface; dataclasses work through type annotations. The current runtime encodes those values as FlatBuffer bytes in payload and materializes the logical fields as typed SQL columns during Rust ingestion. Callers may still pass generated FlatBuffer bytes, builder Output(), or table objects. The queue assigns a default event_time when callers do not provide one, and key defaults to None; distributed queue implementations own their ordering contract.

Manyfold-native architecture elements remain available from manyfold.architecture.native for lower-level topology descriptions, but PubSub is the primary application stream surface. Behavior-heavy substrates stay backed by the runtime implementation.

Stats: Compute Values

temperature = route(
    owner="sensor",
    family="environment",
    stream="temperature",
    schema=Schema.float(name="Temperature"),
)
average_temperature = temperature.derivative_route(
    stream="average_temperature",
    schema=Schema.float(name="AverageTemperature"),
)

subscription = graph.observe(temperature, replay_latest=False).moving_average(
    window_size=3
).connect(average_temperature)
for reading in (72.4, 72.9, 73.7):
    graph.publish(temperature, reading)
subscription.dispose()

latest_average = graph.latest(average_temperature)
assert latest_average is not None
print(f"average: {latest_average.value:.1f}F")

node = next(
    node
    for node in graph.diagram_nodes()
    if dict(node.metadata).get("statistic") == "moving_average"
)
print(dict(node.metadata))

Output:

average: 73.0F
{'statistic': 'moving_average', 'storage': 'sliding_capacitor', 'window_size': '3'}

The shape is the same: computed values are just values published to another typed route. The moving average also renders as a graph-visible node backed by a sliding capacitor, so derived state and operational inspection stay in the same vocabulary.

Model Consensus

from manyfold import Consensus

consensus = Consensus.install(graph, nodes=("node-a", "node-b"))
consensus.tick(1)
consensus.tick(2)
consensus.propose(1, "set mode=auto")
consensus.propose(2, "set temp=21")

print(consensus.latest_leader())
print(consensus.latest_log())

Output:

('node-a', 3, True)
((1, 'set mode=auto'), (2, 'set temp=21'))

The consensus component uses Raft-shaped leader election and replicated-log concepts from Diego Ongaro and John Ousterhout's “In Search of an Understandable Consensus Algorithm” (USENIX ATC 2014).

Read Next

What It Models

  • Typed routes for logical signals.
  • Replayable latest-value reads and Rx-style observation.
  • Graph-visible node thread placement for main, background, pooled, or isolated execution.
  • Graph-visible capacitors, resistors, watchdogs, mailboxes, windows, and joins.
  • Explicit demand, retention, lazy payload access, and write-shadow state.
  • Lineage, taints, route audit snapshots, and topology queries.
  • Local file-backed stores and a small consensus component scaffold.

The public Python surface is intentionally narrow at the top level. Advanced helpers live under manyfold.graph, and the examples are the best way to see which parts are supported today.

Examples

The examples/ directory is organized as a short path through the mental model. Start with a route, derive values, add explicit demand, then move into joins, watermarks, planning, consensus, and taint-aware runtime behavior. The supported examples are validated by the regular unittest run so they do not drift away from the API.

Start here: publish changing state and read the latest value

Layer computation: publish derived values

Control the flow: make downstream demand visible

Fuse streams: coordinate independent sensors

Reason in time: release data by watermark progress

Scale the graph: plan repartition work explicitly

Capstone: wire a Raft-shaped consensus component

Audit the hard parts: mark nondeterminism on purpose

More involved operator, query, transport, mesh, and security coverage stays in tests/test_graph_reactive.py, with archived exploratory scripts kept under examples/archived/. The example manifest, README featured-example list, and RFC reference suite all derive from the shared example catalog, so supported versus archived status lives in one place.

Verify

Use uv run for Python commands.

cargo test
uv run ruff check
uv run python -m unittest discover -s tests -p 'test_*.py'
uv run python -m manyfold.rfc_checklist_gen --check
uv run manyfold-example-catalog --check
uv run python -m examples.catalog --check-readme

Repo Map

  • python/manyfold/: Python wrapper API.
  • src/: Rust in-memory runtime and PyO3 extension.
  • examples/: runnable examples covered by tests.
  • tests/: unittest suite.
  • docs/: onboarding, usage, performance notes, release notes, and RFC docs.

Project details


Download files

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

Source Distribution

manyfold-0.1.41.tar.gz (2.7 MB view details)

Uploaded Source

Built Distributions

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

manyfold-0.1.41-cp310-abi3-win_amd64.whl (2.8 MB view details)

Uploaded CPython 3.10+Windows x86-64

manyfold-0.1.41-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (10.5 MB view details)

Uploaded CPython 3.10+manylinux: glibc 2.17+ x86-64

manyfold-0.1.41-cp310-abi3-macosx_11_0_arm64.whl (2.9 MB view details)

Uploaded CPython 3.10+macOS 11.0+ ARM64

manyfold-0.1.41-cp310-abi3-macosx_10_12_x86_64.whl (3.1 MB view details)

Uploaded CPython 3.10+macOS 10.12+ x86-64

File details

Details for the file manyfold-0.1.41.tar.gz.

File metadata

  • Download URL: manyfold-0.1.41.tar.gz
  • Upload date:
  • Size: 2.7 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for manyfold-0.1.41.tar.gz
Algorithm Hash digest
SHA256 ee9ddf61281ed7287f5c19b661ad2a94d9287ed4d50bb8a34cfacb18f7811b79
MD5 8ede4864fc6bf549c1fa249094b10fb8
BLAKE2b-256 edb5c477aaf00ffd111d492ccb1f0ec566159542361c8675c7fd166310068191

See more details on using hashes here.

Provenance

The following attestation bundles were made for manyfold-0.1.41.tar.gz:

Publisher: pypi.yml on Organization5762/manyfold

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

File details

Details for the file manyfold-0.1.41-cp310-abi3-win_amd64.whl.

File metadata

  • Download URL: manyfold-0.1.41-cp310-abi3-win_amd64.whl
  • Upload date:
  • Size: 2.8 MB
  • Tags: CPython 3.10+, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for manyfold-0.1.41-cp310-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 5c4e685244985ebb6b088c753eb1ae1ab6c0cbdf51dea2ce89362fe907c7f6a2
MD5 d7bcc20c7403718c372db0869ed9879c
BLAKE2b-256 4fe8a983cf13f7c61ddc6083fe7340216950c8eed0dcf5c197636433bedf7a95

See more details on using hashes here.

Provenance

The following attestation bundles were made for manyfold-0.1.41-cp310-abi3-win_amd64.whl:

Publisher: pypi.yml on Organization5762/manyfold

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

File details

Details for the file manyfold-0.1.41-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for manyfold-0.1.41-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 211263102af535d4207f3e6d6c7daf0bde3c9d42ba4f1e8542f9d37db2e9fe63
MD5 edf736883e7cce088a02ba594814bb8e
BLAKE2b-256 6d8c71df67a87e447c898bf87a4dd35907bf0079dffbfd0cc55a1f887ef354b3

See more details on using hashes here.

Provenance

The following attestation bundles were made for manyfold-0.1.41-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: pypi.yml on Organization5762/manyfold

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

File details

Details for the file manyfold-0.1.41-cp310-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for manyfold-0.1.41-cp310-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 4dbf0622c1f10d751574b73119be0741905080cccf841536e24716e3c2fe9cc2
MD5 51b405304efaaac48b9f1c297c643cce
BLAKE2b-256 3043ed37b813d78a0f98cf5dbfe45a4b7f32f012c71ae128961f0612f79526e2

See more details on using hashes here.

Provenance

The following attestation bundles were made for manyfold-0.1.41-cp310-abi3-macosx_11_0_arm64.whl:

Publisher: pypi.yml on Organization5762/manyfold

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

File details

Details for the file manyfold-0.1.41-cp310-abi3-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for manyfold-0.1.41-cp310-abi3-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 9ed48a89071bdf6f7bdef21d7fb422f5ea26547901be70879910cecbc6d6751d
MD5 2c0546d6d4bdc671dcd6af4d24ed7a6c
BLAKE2b-256 e9af928f519d284870be5edbf39b23ad65cfe1b9c1329d011a1d1ae0de32fe9d

See more details on using hashes here.

Provenance

The following attestation bundles were made for manyfold-0.1.41-cp310-abi3-macosx_10_12_x86_64.whl:

Publisher: pypi.yml on Organization5762/manyfold

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

Supported by

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