Skip to main content
groggy Logo

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

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

Release files for groggy 0.5.2

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

Source distribution (sdist)

Source distribution for groggy 0.5.2
File Size Uploaded
groggy-0.5.2.tar.gz 2.9 MB Details

Built distributions (wheels)

Table of built distributions (wheels) for groggy 0.5.2
File
groggy-0.5.2-pp39-pypy39_pp73-macosx_10_12_x86_64.whl PyPy 3.9 PyPy 3.9 7.3 macOS 10.12+ x86-64 Details
groggy-0.5.2-cp314-cp314-macosx_11_0_arm64.whl CPython 3.14 CPython 3.14 macOS 11.0+ ARM64 Details
groggy-0.5.2-cp312-cp312-manylinux_2_34_x86_64.whl CPython 3.12 CPython 3.12 Linux glibc 2.34+ x86-64 Details
groggy-0.5.2-cp39-cp39-win_amd64.whl CPython 3.9 CPython 3.9 Windows x86-64 Details

Total release size: 22.4 MB

Release files / groggy-0.5.2.tar.gz

Download URL groggy-0.5.2.tar.gz
Size 2.9 MB
Tags Source
SHA-256 checksum
How to use checksums
afa9102299df1c4084db75dd13b7dc8ece11831576fdbb62931c81492d39f638
BLAKE2b-256 checksum
How to use checksums
91e8d54f3d259516a34434b0fe0263678a294c23bae5ae033c047208b64bd2c8
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Dec 5, 2025.

Transparency log

Release files / groggy-0.5.2-pp39-pypy39_pp73-macosx_10_12_x86_64.whl

Download URL groggy-0.5.2-pp39-pypy39_pp73-macosx_10_12_x86_64.whl
Size 4.9 MB
Tags PyPy 3.9 PyPy 3.9 7.3 macOS 10.12+ x86-64
SHA-256 checksum
How to use checksums
53279087d8681dde65818810fef60cf5b881b5ca98483c7b3a2a22e353bfc65f
BLAKE2b-256 checksum
How to use checksums
4191fe910e3f307b7f088caa8e032ad496ac0fc837be1409ed7ec61dcefc9fb0
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Dec 5, 2025.

Transparency log

Release files / groggy-0.5.2-cp314-cp314-macosx_11_0_arm64.whl

Download URL groggy-0.5.2-cp314-cp314-macosx_11_0_arm64.whl
Size 4.7 MB
Tags CPython 3.14 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
e60728a33f6e01e2cc2e2a9e0ceb3fbaa4ae2bcbf2993fe403deb2d603a36b34
BLAKE2b-256 checksum
How to use checksums
935fa872e7a93cfb1eacf33dc5ce2b623b68f74cfce7ff48d7c3f489325678bf
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Dec 5, 2025.

Transparency log

Release files / groggy-0.5.2-cp312-cp312-manylinux_2_34_x86_64.whl

Download URL groggy-0.5.2-cp312-cp312-manylinux_2_34_x86_64.whl
Size 5.2 MB
Tags CPython 3.12 Linux glibc 2.34+ x86-64
SHA-256 checksum
How to use checksums
ca9cd0811e4d9bdade952a71dec9e09b514dfb138828aa160e30723df62e54f8
BLAKE2b-256 checksum
How to use checksums
d2f3967f57b96eb09ec548c3fef9e3fd1f424fa200d647dc6a2b64ac350bbc44
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Dec 5, 2025.

Transparency log

Release files / groggy-0.5.2-cp39-cp39-win_amd64.whl

Download URL groggy-0.5.2-cp39-cp39-win_amd64.whl
Size 4.7 MB
Tags CPython 3.9 Windows x86-64
SHA-256 checksum
How to use checksums
dae86a92cc7da9b6649941bc1aecc94f2e50f53d55f7be64268f138defa65fdb
BLAKE2b-256 checksum
How to use checksums
5352af5ec53d4fa71a0d31a2eda5374174e3d2c6465183043d77d5c42fe5ad76
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Dec 5, 2025.

Transparency log

Release history Release notifications | RSS feed

This release

0.5.2 This release

5 release files

0.5.1

5 release files

0.3.1

2 release files

0.3.0

2 release files

0.2.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