Skip to main content

A minimal, reusable graph runtime for Python with bounded edges, fairness, and observability.

Project description

Meridian Runtime — A Minimal, Reusable Graph Runtime for Python

Owner: GhostWeasel (Lead: doubletap-dave)

CI Docs Docs Deploy

Meridian Runtime is a lightweight, framework-agnostic graph runtime for building real‑time dataflows in Python. Model your application as small, single‑responsibility nodes connected by typed edges with bounded queues. Meridian’s scheduler enforces backpressure, supports control‑plane priorities (e.g., kill switch), and emits rich observability signals by design.

Key features

  • Nodes, edges, subgraphs, scheduler — simple, composable primitives
  • Bounded edges with configurable overflow policies (block, drop, latest, coalesce)
  • Control‑plane priority for critical flows (kill switch, admin, rate‑limit signals)
  • First‑class observability (structured logs, metrics, trace hooks)
  • Small‑file, SRP/DRY‑friendly codebase (aim for ~200 lines per file)
  • uv‑native development workflow (fast, reproducible)

Use cases

  • Real‑time trading systems (market data, execution, risk)
  • Event processing pipelines and enrichment
  • Streaming ETL and log processing
  • Control planes with prioritized signals

Versioning & Deprecation Policy

Documentation

Quick start

Prereqs

  • Python 3.11+
  • uv (modern Python package manager)

Initialize environment

uv lock
uv sync
  1. Dev loop
# Lint
uv run ruff check .

# Format check
uv run black --check .

# Type-check
uv run mypy src

# Tests with coverage
uv run pytest
  1. Run an example
uv run python -m examples.hello_graph.main
  1. Project layout (M1 scaffold)
src/meridian/
  __init__.py
  core/
    __init__.py
  observability/
    __init__.py
  utils/
    __init__.py
examples/
  __init__.py
tests/
  unit/
    test_smoke.py
  integration/
    test_examples_smoke.py
pyproject.toml
ruff.toml
mypy.ini
.editorconfig
.github/workflows/ci.yml

Core Concepts

Node

  • Single‑responsibility processing unit with typed input/output ports
  • Lifecycle hooks: on_start, on_message, on_tick, on_stop
  • Emits Messages on output ports

Edge

  • Typed, bounded queue connecting node ports
  • Overflow policies: block (default), drop, latest, coalesce(fn)
  • Exposes queue depth, throughput, and backpressure metrics

Subgraph

  • Composition of nodes into a reusable unit
  • Exposes its own typed inputs/outputs
  • Validates internal wiring and contracts

Scheduler

  • Advances nodes based on readiness, priorities, and capacity
  • Drives ticks (timers/housekeeping), supports graceful shutdown
  • Prioritizes control‑plane edges/messages

Message

  • payload: Any (type tracked by PortSpec)
  • headers: {trace_id, timestamp, schema_version, content_type, ...}

PortSpec

  • name: str
  • schema/type: Python types, TypedDict, or Pydantic models (pluggable)
  • policy: overflow handling per edge (block/drop/latest/coalesce)

Observability

  • Structured logs (JSON) with correlation IDs
  • Metrics (Prometheus) for nodes/edges/scheduler
  • Optional tracing (OpenTelemetry hooks)

Minimal Example

producer.py

from meridian.core import Node, Message

class Producer(Node):
    def __init__(self, n=5):
        self._n = n
        self._i = 0

    def name(self): return "producer"
    def inputs(self): return {}
    def outputs(self): return {"out": int}

    def on_start(self):
        self._i = 0

    def on_tick(self):
        if self._i < self._n:
            self.emit("out", Message(payload=self._i))
            self._i += 1

consumer.py

from meridian.core import Node

class Consumer(Node):
    def name(self): return "consumer"
    def inputs(self): return {"in": int}
    def outputs(self): return {}

    def on_message(self, port, msg):
        print(f"got: {msg.payload}")

main.py

from meridian.core import Subgraph, Scheduler
from producer import Producer
from consumer import Consumer

g = Subgraph()
g.add_node(Producer(n=3))
g.add_node(Consumer())
g.connect(("producer", "out"), ("consumer", "in"), capacity=16)

sch = Scheduler()
sch.register(g)
sch.run()

Run:

uv run python -m examples.hello_graph.main

Patterns and Guidance

File size and modularity

  • Target ~200 lines per file. Split responsibilities into multiple nodes or utilities.
  • SRP and DRY: nodes do one thing; share common helpers in utils/.
  • Prefer small subgraphs over monolith graphs for composition and reuse.

Backpressure and overflow

  • Default policy: block (applies backpressure upstream).
  • For sporadic spikes: latest policy can drop stale data in favor of the newest.
  • For aggregations: coalesce can compress bursts (e.g., merge updates).

Priorities

  • Assign higher priority to control‑plane edges (e.g., kill switch, cancel_all).
  • Keep control messages small and fast; avoid heavy work in control nodes.

Message schemas

  • Use precise Python types or TypedDicts for ports.
  • Optionally integrate Pydantic for richer validation without coupling the runtime.

Error handling

  • Prefer local handling in nodes; escalate via dead‑letter subgraph if needed.
  • Use retries with jitter and circuit‑breaker patterns for external IO nodes.

Observability

Logs

  • JSON‑structured logs with timestamps and correlation IDs (trace_id)
  • Node lifecycle events, exceptions, tick durations

Metrics (Prometheus)

  • Node: tick latency, messages processed, errors
  • Edge: queue depth, enqueue/dequeue rate, drops, backpressure time
  • Scheduler: runnable nodes, loop latency, priority applications

Tracing (optional)

  • Hook into OpenTelemetry: annotate message paths and node spans
  • Keep tracing optional to avoid overhead where unnecessary

Dashboards and alerts

  • Track queue depths and backpressure saturation
  • Alert on sustained scheduler latency or starved nodes
  • Monitor error rates per node and dropped messages per edge

Roadmap

v1 (initial release)

  • In‑process runtime, asyncio‑friendly
  • Nodes, edges (bounded queues), subgraphs, scheduler (fair scheduling)
  • Observability: logs, metrics, basic trace hooks
  • Examples and scaffolding scripts

v1.x

  • Schema adapters (Pydantic), richer overflow policies
  • More node templates and utilities
  • Improved testing harness and fixtures

v2+

  • Multi‑process edges (shared memory/IPC)
  • Distributed graphs (brokers + codecs)
  • Visual tooling and hot‑reload for graphs

Development (with uv)

Install and sync

uv init
uv lock
uv sync

Run tests

uv run pytest

Lint and type‑check (example)

uv run ruff check .
uv run mypy src

Run an example

uv run python -m examples.hello_graph.main

Contributing

  • Keep files small (~200 lines) and responsibilities focused.
  • Include unit tests for core changes; add integration tests for subgraph behavior.
  • Update examples and docs for user‑facing features.
  • Follow SemVer and add entries to CHANGELOG for notable changes.

License

  • BSD 3-Clause (recommended) or your organization’s standard OSS license.

FAQ

See our FAQ page for answers to common questions about Meridian Runtime.


Happy building with Meridian Runtime.

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

meridian_runtime-1.0.0rc1.tar.gz (50.8 kB view details)

Uploaded Source

Built Distribution

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

meridian_runtime-1.0.0rc1-py3-none-any.whl (61.7 kB view details)

Uploaded Python 3

File details

Details for the file meridian_runtime-1.0.0rc1.tar.gz.

File metadata

  • Download URL: meridian_runtime-1.0.0rc1.tar.gz
  • Upload date:
  • Size: 50.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.12.9

File hashes

Hashes for meridian_runtime-1.0.0rc1.tar.gz
Algorithm Hash digest
SHA256 0fe2bba24a0cfbc736e829d3b370d7d7de12cf83e1cb751340624d25e663a174
MD5 60fb70f3cf664d54fec7c01a3f6e1817
BLAKE2b-256 6aa511a164e27ef92145112f6da1babe183c632ac7efea80bf4c840db8cba9f2

See more details on using hashes here.

Provenance

The following attestation bundles were made for meridian_runtime-1.0.0rc1.tar.gz:

Publisher: release.yml on ghostweasellabs/meridian-runtime

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

File details

Details for the file meridian_runtime-1.0.0rc1-py3-none-any.whl.

File metadata

File hashes

Hashes for meridian_runtime-1.0.0rc1-py3-none-any.whl
Algorithm Hash digest
SHA256 e5bb9e3d7879749a43ea90e86492d28e6d2f38356e839dc26b4761795bd35b07
MD5 d918f697bb80fcbdf65fb20a01ef5a24
BLAKE2b-256 cddaf3bdab01c24bfc584bd40393d3266f498c6a884f01b17f489758c94d5e61

See more details on using hashes here.

Provenance

The following attestation bundles were made for meridian_runtime-1.0.0rc1-py3-none-any.whl:

Publisher: release.yml on ghostweasellabs/meridian-runtime

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