Skip to main content

Graphite

Graphite is a Python toolkit for describing, validating, matching, and rewriting Heterograph-based intermediate representations (IRs). It also provides contracts for checking the output of a graph workflow. Graphite has no Loom dependency; any object with an output attribute can be verified.

Install

Graphite requires Python 3.10+, Heterograph, Pydantic 2, and graph-tool for graph matching. For local development:

conda env create graphite
conda activate graphite
conda install -c conda-forge graph-tool=3.0 graphviz python-graphviz
pip install -e .

The runnable examples are in examples/. validation and processor_tests require Graphite only; lowering and agent are Graphite and Loom integration examples.

IR schemas

GraphSchema defines the accepted graph, vertex, and edge metadata with Pydantic models. It constructs correctly typed graph elements and returns a ValidationReport instead of failing at the first invalid element. Each graph element uses _type to select its model.

from typing import Literal

from pydantic import BaseModel, Field
from graphite import GraphSchema


class ConstantProps(BaseModel):
    type_: Literal["Constant"] = Field(alias="_type")
    value: float


class NegateProps(BaseModel):
    type_: Literal["Negate"] = Field(alias="_type")


class DataEdgeProps(BaseModel):
    type_: Literal["data"] = Field(alias="_type")


ir = GraphSchema(
    name="ArithmeticIR",
    vertex={"Constant": ConstantProps, "Negate": NegateProps},
    edge={"data": DataEdgeProps},
)

graph = ir.new_graph()
constant = ir.new_vertex(graph, "Constant", value=3.0)
negate = ir.new_vertex(graph, "Negate")
ir.new_edge(graph, constant, negate, "data")

report = ir.validate(graph)
assert report.ok

Pass rules to GraphSchema for structural validation such as arity, acyclicity, or required inputs and outputs. A rule receives the HGraph and returns a list of Issue values. update_vertex() and update_edge() apply the same Pydantic validation when metadata changes.

Graph processor

GraphProcessor finds AQL patterns and applies one in-place rewrite pass. A result contains matches, the parsed pattern, and a modified flag.

from heterograph import HGraph
from graphite import GraphProcessor

graph = HGraph()
graph.add_vx(3)
graph.add_edge(0, 1)
graph.add_edge(1, 2)

processor = GraphProcessor(snapshot=False)
result = processor.run(
    graph,
    select="a => b => c",
    rewrite="a => c",
)

assert result["modified"]
assert set(graph.edges) == {(0, 2)}

Use where(graph, **match) to filter matches and finalize(graph, **match) to initialize created vertices or metadata. finalize must return a boolean. Rewrites require disjoint matches; Graphite rejects overlapping matches before mutating the graph. Rewire annotations preserve boundary connections when a matched vertex is replaced:

processor.run(
    graph,
    select="a => b => c",
    rewrite="a => x {rewire: b} => c",
)

GraphProcessor(snapshot=True) is the default and records graphs in a Heterograph WebView. Use snapshot=False for scripts and tests without a viewer.

Contracts

Contract evaluates one object with an output attribute and returns a ContractResult. Verifier runs a collection of contracts, retaining all results; if any fail, it raises ContractException with the individual failures.

GraphSchemaContract validates a result's graph output against a schema:

from dataclasses import dataclass

from graphite import GraphSchemaContract, Verifier


@dataclass
class BuildResult:
    output: object


checks = Verifier([GraphSchemaContract(ir)])
contract_results = checks.verify(BuildResult(output=graph))
assert contract_results["valid-ArithmeticIR"].passed

Custom contracts can check domain-specific properties:

from graphite import Contract, ContractResult


class HasVertices(Contract):
    def __init__(self):
        super().__init__(name="has-vertices")

    def evaluate(self, result):
        count = len(result.output.vertices)
        return ContractResult(
            passed=count > 0,
            output=result.output,
            metrics={"vertex_count": count},
        )

For complete examples, see examples/validation, examples/processor_tests, and the Loom-backed examples/lowering workflow.

Download files

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

Source Distribution

graphite_ir-0.1.0.tar.gz (13.3 kB view details)

Uploaded Source

Built Distribution

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

graphite_ir-0.1.0-py3-none-any.whl (13.6 kB view details)

Uploaded Python 3

File details

Details for the file graphite_ir-0.1.0.tar.gz.

File metadata

  • Download URL: graphite_ir-0.1.0.tar.gz
  • Upload date:
  • Size: 13.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.12.13

File hashes

Hashes for graphite_ir-0.1.0.tar.gz
Algorithm Hash digest
SHA256 f1b959e17812b770d309958cc4db049a84fe128e316e85dab2122e5bf4de3157
MD5 137044bc1ac305d48a65c7d25004adc0
BLAKE2b-256 c924b1dd0acb7fd698b9d32864a318338ea34098681c3f778795b0dc3c21908e

See more details on using hashes here.

File details

Details for the file graphite_ir-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: graphite_ir-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 13.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.12.13

File hashes

Hashes for graphite_ir-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 7b412585b28db9b9648e80513584960ccee42e6a5755423fd05cc8c044e54bfb
MD5 25545aa23e6faf24da760a6bf316860f
BLAKE2b-256 24eaecd6a2858a97a7bb9cd15fe00a86ccd7482da0467c91b09cdf96fa5028b0

See more details on using hashes here.

Supported by

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