Groggy - A Graph Language Engine for dynamic graphs and versioned state
Project description
groggy
a graph analytics library for Python with a Rust core
👀 What is groggy?
groggy is a modern graph analytics library that combines graph topology with tabular data operations. Built with a high-performance Rust core and intuitive Python API, groggy lets you seamlessly work with graph data using familiar table-like operations.
At groggy, we believe structure is computation.
Quick Start:
Installation
pip install groggy
Features
High-Performance Algorithms
11 Rust-native algorithms, exposed via Python:
- Centrality: PageRank, Betweenness, Closeness
- Community: LPA, Louvain, Leiden, Connected Components
- Pathfinding: BFS, DFS, Dijkstra, A*
from groggy.algorithms.centrality import pagerank
result = graph.view().apply(pagerank(damping=0.85))
scores = result.nodes["pagerank"]
Builder DSL — Custom Algorithms with Batch Executor
Compose algorithms in Python; iterative loops get 10-100x speedup via the Batch Executor.
import groggy as gr
b = gr.builder("my_algorithm")
values = b.init_nodes(default=1.0)
with b.iterate(20): # batched when compatible
neighbor_sum = b.map_nodes(
"sum(values[neighbors(node)])",
inputs={"values": values},
)
values = b.core.add(b.core.mul(neighbor_sum, 0.85), 0.15)
b.attach_as("result", values)
algo = b.build()
result = graph.view().apply(algo)
Documentation
- Algorithms Guide: https://rollingstorms.github.io/groggy/guide/algorithms/
- Builder DSL: https://rollingstorms.github.io/groggy/guide/builder/
- Tutorials: https://rollingstorms.github.io/groggy/builder/tutorials/
- API Reference: https://rollingstorms.github.io/groggy/api/
Example Python Usage
import groggy as gr
from groggy.algorithms.centrality import pagerank
from groggy.algorithms.community import label_propagation
# Create a new graph
g = gr.Graph()
# Add nodes and edges
alice = g.add_node(name="Alice", age=29)
bob = g.add_node(name="Bob", club="Purple", active=True, age=55)
carol = g.add_node(name="Carol", club="Blue", active=True, age=31)
g.add_edge(alice, bob, weight=5)
g.add_edge(alice, carol, weight=2)
g.add_edge(bob, carol, weight=1)
# Inspect the graph
print(g.nodes.table().head())
print(g.edges.table().head())
# Query the graph
purple_nodes = g.nodes[g.nodes["club"] == "Purple"]
younger_nodes = g.nodes[g.nodes["age"] < 30]
# Run a graph algorithm
g.connected_components(inplace=True, label='component')
# Pipeline-style algorithms with g.apply()
g.apply(pagerank(max_iter=10, output_attr="pagerank_score"))
print(g.nodes.table().sort_by("pagerank_scorescore").tail(10))
# Run another algorithm - Label Propagation
g.apply(label_propagation(max_iter=10, output_attr="label"))
print("Number of Communities Found:", g.nodes["label"].nunique())
# Viz. the graph
g.viz.show(node_color="label",
edge_color="pagerank_score",
node_label="node_id")
Structural Computing
groggy isn’t just another graph library — it’s the beginning of a broader idea called structural computing.
In structural computing, relationships themselves become the language of computation. It treats tables, graphs, and matrices not as separate data models, but as different views of the same structure — the same underlying memory, reinterpreted through context.
Here, structure and signal are equal — both are first-class citizens. Computation flows naturally across form, where structure is computation.
groggy makes a home for that idea — the brick from which the building will rise.
A Little Graph Theory:
A graph is composed of nodes and edges…or is it vertices and edges? or maybe nodes and links?
At its core, a graph is a network - a collection of entities (nodes) and the relationships (edges) between them. Those are the first truths of graph theory:
Everything is connected, and connections carry meaning.
Edges aren't just lines on a diagram — they represent interactions, flows, dependencies, or influence. And when you map those connections, entire hidden structures begin to reveal themselves:
- Communities of related entities
- Bridges between otherwise disconnected groups
- Patterns that point to anomalies, generalizations, or insights
groggy builds on these ideas and takes them further: every node and edge can have attributes that are stored in a equally efficient format. That means your "graph" isn't just dots and lines — it's a rich, living dataset:
- Nodes can store labels, features, embeddings, or metadata
- Edges can carry weights, timestamps, permissions, or scores
- You can analyze both structure and data, as a graph or as a table, together.
Whether you're exploring dynamic networks, running graph algorithms, or building machine learning pipelines, groggy aims to be a modular, high-performance foundation. It's designed for thinking in graphs — not only visualizing them, but querying, transforming, and learning from them.
⸻
1) A first graph
Start tiny. Let the structure grow as needed.
import groggy as gr
g = gr.Graph()
alice = g.add_node(label="Alice", age=29) # any kwargs become attributes
bob = g.add_node(label="Bob", club="Red")
g.add_edge(alice, bob, weight=5) # edges use the returned node IDs
print(len(g.nodes)) # 2 (accessor, not a method)
print(len(g.edges)) # 1
Nodes return an integer ID. Keep it, reuse it. Any keyword you invent becomes a stored attribute.
⸻
2) Exploring real data
Use a built-in generator to play with something non-toy:
g = gr.generators.karate_club()
print(g.table()) # GraphTable summary (sizes of nodes/edges tables)
Grab a whole attribute column straight from the graph and peek:
names = g["name"] # BaseArray of node names
print(names.head(5))
⸻
3) Attributes are the heart and soul of the graph
You can define attributes at creation time (kwargs), or later with set_attrs. Make up any attribute names; groggy persists them.
# At creation:
carol = g.add_node(label="Carol", role="Analyst", active=True)
# Later, in bulk:
g.nodes.set_attrs({
carol: {"club": "Blue", "age": 31}
})
# Edges too:
g.edges.set_attrs({
0: {"weight": 0.7, "type": "friendship"}
})
⸻
4) From graphs to tables — and back
Under the hood is columnar storage you can inspect, export, and rebuild from.
nodes = g.nodes.table()
edges = g.edges.table()
print(nodes.head())
print(edges.head())
# Round-trip: build a GraphTable explicitly, then convert back to a Graph
gt = gr.GraphTable(nodes=nodes, edges=edges)
g2 = gt.to_graph()
Export to files or Pandas:
nodes.to_parquet("nodes.parquet")
edges.to_csv("edges.csv")
df = nodes.to_pandas()
⸻
5) Columns & boolean filters (Pandas-style)
Masks feel familiar:
blue_nodes = g.nodes[g.nodes["club"] == "Blue"]
older_nodes = g.nodes[g.nodes["age"] > 30]
⸻
6) Subgraphs (the quick way)
Slices and selections give you instant working sets:
g_small = g.nodes[:10] # first 10 nodes → subgraph view
subset = g.nodes[[1, 5, 9]] # arbitrary indices
g_sub = g.subgraph(nodes=subset.node_ids()) # explicit subgraph if you want it materialized
⸻
7) Delegation & chaining
Think in steps; write in steps. Keep it expressive and compact.
(
g.connected_components()
.filter(lambda comp: len(comp.nodes) > 3)
.table()
.head()
)
We're keeping algorithms light in the README while the foundation settles, but the chain shows where it's headed.
⸻
8) Saving & loading
Save whole graphs as bundles, or export tables individually.
# Full graph bundle
g.save_bundle("graph.bundle")
g2 = gr.GraphTable.load_bundle("graph.bundle")
# Tables as files
g.nodes.table().to_parquet("nodes.parquet")
g.edges.table().to_csv("edges.csv")
⸻
9) Core Architecture
Three tiers: • Rust Core — memory-safe performance, columnar ops, and core graph/state machinery. • FFI Bridge — a slim foreign-function interface that exposes Rust capabilities safely. • Python API — the user-facing surface that reads like you think, with chains, masks, and friendly data interchange.
This separation keeps groggy fast, composable, and future-proof while still feeling Pythonic.
⸻
Installation & Building
From Source
git clone https://github.com/rollingstorms/groggy.git
cd groggy/python-groggy
# Install dependencies
pip install maturin
# Build and install
maturin develop --release
Quick Test
import groggy as gr
print("groggy installed successfully! 🎉")
⸻
Development
Project Structure
groggy/
├── src/ # Rust core library
│ ├── algorithms/ # Algorithm registry, pipeline steps, builders
│ ├── api/ # High-level graph API surface
│ ├── core/ # Core data structures and engines
│ ├── temporal/ # Temporal snapshots, index, context helpers
│ ├── viz/ # Visualization adapters
│ └── … # (query, storage, traits, utils, etc.)
├── python-groggy/
│ ├── src/ffi/ # PyO3 FFI bindings (marshalling only)
│ └── python/groggy/
│ ├── algorithms/ # Python algorithm shims & DSL
│ ├── builder.py # Pipeline builder entry points
│ ├── graph.py # Graph facade over the Rust core
│ └── … # Display helpers, viz, generators, widgets
├── docs/ # MkDocs documentation site
├── notes/ # Architecture plans, personas, experiments
└── tests/ # Python integration + cross-language suites
Building & Testing
# Build development version
maturin develop
# Build release version
maturin develop --release
# Run formatting
cargo fmt
# Run Rust tests
cargo test
# Run Python tests
python tests/test_documentation_validation.py
⸻
Contributing
groggy is open and evolving. We'd love your ideas, experiments, and critiques. • Open an issue to propose features, UX improvements, or docs tweaks. • Send a PR for bug fixes, performance wins, or new generators/datasets. • Share how you're using groggy — real examples shape the roadmap.
Before contributing, please: • Run the tests locally (unit + integration where applicable). • Add/adjust docs for any user-visible change. • Keep examples small and narrative-friendly (we teach by showing).
Thanks for being here. Let's build a graph engine that feels as natural as drawing a line between two ideas.
⸻
License
MIT License - see LICENSE for details.
⸻
Acknowledgments
groggy builds on the excellent work of:
- Rust ecosystem: Especially PyO3 for Python bindings
- Graph libraries: NetworkX, igraph, and others for inspiration
- Data science tools: Pandas, NumPy for API design patterns
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
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file groggy-0.5.2.tar.gz.
File metadata
- Download URL: groggy-0.5.2.tar.gz
- Upload date:
- Size: 2.9 MB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
afa9102299df1c4084db75dd13b7dc8ece11831576fdbb62931c81492d39f638
|
|
| MD5 |
131256b7fee94d3047b93b105b3ba704
|
|
| BLAKE2b-256 |
91e8d54f3d259516a34434b0fe0263678a294c23bae5ae033c047208b64bd2c8
|
Provenance
The following attestation bundles were made for groggy-0.5.2.tar.gz:
Publisher:
publish.yml on rollingstorms/groggy
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
groggy-0.5.2.tar.gz -
Subject digest:
afa9102299df1c4084db75dd13b7dc8ece11831576fdbb62931c81492d39f638 - Sigstore transparency entry: 743474541
- Sigstore integration time:
-
Permalink:
rollingstorms/groggy@94f369ab7676efbe8ed74b7e3fb7757fe2496ef7 -
Branch / Tag:
refs/tags/v0.5.2 - Owner: https://github.com/rollingstorms
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@94f369ab7676efbe8ed74b7e3fb7757fe2496ef7 -
Trigger Event:
release
-
Statement type:
File details
Details for the file groggy-0.5.2-pp39-pypy39_pp73-macosx_10_12_x86_64.whl.
File metadata
- Download URL: groggy-0.5.2-pp39-pypy39_pp73-macosx_10_12_x86_64.whl
- Upload date:
- Size: 4.9 MB
- Tags: PyPy, macOS 10.12+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
53279087d8681dde65818810fef60cf5b881b5ca98483c7b3a2a22e353bfc65f
|
|
| MD5 |
386fbab3aef8f9728064b6a347b922b8
|
|
| BLAKE2b-256 |
4191fe910e3f307b7f088caa8e032ad496ac0fc837be1409ed7ec61dcefc9fb0
|
Provenance
The following attestation bundles were made for groggy-0.5.2-pp39-pypy39_pp73-macosx_10_12_x86_64.whl:
Publisher:
publish.yml on rollingstorms/groggy
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
groggy-0.5.2-pp39-pypy39_pp73-macosx_10_12_x86_64.whl -
Subject digest:
53279087d8681dde65818810fef60cf5b881b5ca98483c7b3a2a22e353bfc65f - Sigstore transparency entry: 743474548
- Sigstore integration time:
-
Permalink:
rollingstorms/groggy@94f369ab7676efbe8ed74b7e3fb7757fe2496ef7 -
Branch / Tag:
refs/tags/v0.5.2 - Owner: https://github.com/rollingstorms
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@94f369ab7676efbe8ed74b7e3fb7757fe2496ef7 -
Trigger Event:
release
-
Statement type:
File details
Details for the file groggy-0.5.2-cp314-cp314-macosx_11_0_arm64.whl.
File metadata
- Download URL: groggy-0.5.2-cp314-cp314-macosx_11_0_arm64.whl
- Upload date:
- Size: 4.7 MB
- Tags: CPython 3.14, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e60728a33f6e01e2cc2e2a9e0ceb3fbaa4ae2bcbf2993fe403deb2d603a36b34
|
|
| MD5 |
b2aebe3144a6f7e916b103e75694934f
|
|
| BLAKE2b-256 |
935fa872e7a93cfb1eacf33dc5ce2b623b68f74cfce7ff48d7c3f489325678bf
|
Provenance
The following attestation bundles were made for groggy-0.5.2-cp314-cp314-macosx_11_0_arm64.whl:
Publisher:
publish.yml on rollingstorms/groggy
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
groggy-0.5.2-cp314-cp314-macosx_11_0_arm64.whl -
Subject digest:
e60728a33f6e01e2cc2e2a9e0ceb3fbaa4ae2bcbf2993fe403deb2d603a36b34 - Sigstore transparency entry: 743474555
- Sigstore integration time:
-
Permalink:
rollingstorms/groggy@94f369ab7676efbe8ed74b7e3fb7757fe2496ef7 -
Branch / Tag:
refs/tags/v0.5.2 - Owner: https://github.com/rollingstorms
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@94f369ab7676efbe8ed74b7e3fb7757fe2496ef7 -
Trigger Event:
release
-
Statement type:
File details
Details for the file groggy-0.5.2-cp312-cp312-manylinux_2_34_x86_64.whl.
File metadata
- Download URL: groggy-0.5.2-cp312-cp312-manylinux_2_34_x86_64.whl
- Upload date:
- Size: 5.2 MB
- Tags: CPython 3.12, manylinux: glibc 2.34+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ca9cd0811e4d9bdade952a71dec9e09b514dfb138828aa160e30723df62e54f8
|
|
| MD5 |
e6e4a7bbbbaf4feb1e24c17cb0206cf5
|
|
| BLAKE2b-256 |
d2f3967f57b96eb09ec548c3fef9e3fd1f424fa200d647dc6a2b64ac350bbc44
|
Provenance
The following attestation bundles were made for groggy-0.5.2-cp312-cp312-manylinux_2_34_x86_64.whl:
Publisher:
publish.yml on rollingstorms/groggy
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
groggy-0.5.2-cp312-cp312-manylinux_2_34_x86_64.whl -
Subject digest:
ca9cd0811e4d9bdade952a71dec9e09b514dfb138828aa160e30723df62e54f8 - Sigstore transparency entry: 743474545
- Sigstore integration time:
-
Permalink:
rollingstorms/groggy@94f369ab7676efbe8ed74b7e3fb7757fe2496ef7 -
Branch / Tag:
refs/tags/v0.5.2 - Owner: https://github.com/rollingstorms
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@94f369ab7676efbe8ed74b7e3fb7757fe2496ef7 -
Trigger Event:
release
-
Statement type:
File details
Details for the file groggy-0.5.2-cp39-cp39-win_amd64.whl.
File metadata
- Download URL: groggy-0.5.2-cp39-cp39-win_amd64.whl
- Upload date:
- Size: 4.7 MB
- Tags: CPython 3.9, Windows x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
dae86a92cc7da9b6649941bc1aecc94f2e50f53d55f7be64268f138defa65fdb
|
|
| MD5 |
8188c7ce2ce8ae67d9288493da90b139
|
|
| BLAKE2b-256 |
5352af5ec53d4fa71a0d31a2eda5374174e3d2c6465183043d77d5c42fe5ad76
|
Provenance
The following attestation bundles were made for groggy-0.5.2-cp39-cp39-win_amd64.whl:
Publisher:
publish.yml on rollingstorms/groggy
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
groggy-0.5.2-cp39-cp39-win_amd64.whl -
Subject digest:
dae86a92cc7da9b6649941bc1aecc94f2e50f53d55f7be64268f138defa65fdb - Sigstore transparency entry: 743474552
- Sigstore integration time:
-
Permalink:
rollingstorms/groggy@94f369ab7676efbe8ed74b7e3fb7757fe2496ef7 -
Branch / Tag:
refs/tags/v0.5.2 - Owner: https://github.com/rollingstorms
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@94f369ab7676efbe8ed74b7e3fb7757fe2496ef7 -
Trigger Event:
release
-
Statement type: