Skip to main content

AlgoGraph

Immutable graph data structures and algorithms library with functional transformers, declarative selectors, and lazy views.

PyPI version Python 3.8+ License: MIT

Installation

pip install AlgoGraph

Overview

AlgoGraph provides immutable graph data structures with a clean, functional API. Version 2.0.0 brings AlgoTree-level API elegance with pipe-based transformers, declarative selectors, and lazy views—achieving ~90% code reduction for common operations.

Key Features

  • Immutable by default: All operations return new graph objects
  • 56+ algorithms: Traversal, shortest path, centrality, flow, matching, coloring
  • Pipe-based transformers: Composable operations with | operator (v2.0.0)
  • Declarative selectors: Pattern matching with logical operators (v2.0.0)
  • Lazy views: Memory-efficient filtering without copying (v2.0.0)
  • Fluent builder API: Construct graphs with 82% less code
  • Type-safe: Full type hints for IDE support
  • Optional AlgoTree integration: Convert between trees and graphs

Quick Start

from AlgoGraph import Graph, Vertex, Edge

# Create a graph
g = (Graph.builder()
     .add_vertex('A', age=30)
     .add_vertex('B', age=25)
     .add_edge('A', 'B', weight=5.0)
     .build())

# Query the graph
g.has_edge('A', 'B')  # True
g.neighbors('A')       # {'B'}

# Run algorithms
from AlgoGraph.algorithms import dijkstra, pagerank
distances = dijkstra(g, source='A')

Advanced Features (v2.0.0)

Transformer Pipelines

Compose graph operations using the | pipe operator:

from AlgoGraph.transformers import filter_vertices, largest_component, stats

# Filter → extract component → compute stats
result = (graph
    | filter_vertices(lambda v: v.get('active'))
    | largest_component()
    | stats())

# result: {'vertex_count': 42, 'edge_count': 156, 'density': 0.18, ...}

Available Transformers:

  • filter_vertices(pred), filter_edges(pred) - Filter by predicate
  • map_vertices(fn), map_edges(fn) - Transform attributes
  • reverse(), to_undirected() - Structure transformations
  • largest_component(), minimum_spanning_tree() - Algorithm-based
  • to_dict(), to_adjacency_list(), stats() - Export operations

Declarative Selectors

Query vertices and edges with logical operators:

from AlgoGraph.graph_selectors import vertex as v, edge as e

# Find active users with high degree
power_users = graph.select_vertices(
    v.attrs(active=True) & v.degree(min_degree=10)
)

# Find heavy edges from admin nodes
admin_edges = graph.select_edges(
    e.source(v.attrs(role='admin')) & e.weight(min_weight=100)
)

# Complex queries with OR, NOT, XOR
special = graph.select_vertices(
    (v.attrs(vip=True) | v.degree(min_degree=50)) & ~v.attrs(banned=True)
)

Selector Types:

  • vertex.id(pattern) - Match by ID (glob/regex)
  • vertex.attrs(**attrs) - Match attributes (supports callables)
  • vertex.degree(min/max/exact) - Match by degree
  • edge.weight(min/max/exact) - Match by weight
  • edge.source(selector), edge.target(selector) - Match endpoints

Lazy Views

Efficient filtering without copying data:

from AlgoGraph.views import filtered_view, neighborhood_view

# Create view without copying
view = filtered_view(
    large_graph,
    vertex_filter=lambda v: v.get('active'),
    edge_filter=lambda e: e.weight > 5.0
)

# Iterate lazily
for vertex in view.vertices():
    process(vertex)

# Materialize only when needed
small_graph = view.materialize()

# Explore k-hop neighborhood
local = neighborhood_view(graph, center='Alice', k=2)

View Types:

  • filtered_view() - Filter vertices/edges
  • subgraph_view() - View specific vertices
  • reversed_view() - Reverse edge directions
  • undirected_view() - View as undirected
  • neighborhood_view() - k-hop neighborhood

Core Classes

Vertex

from AlgoGraph import Vertex

v = Vertex('A', attrs={'value': 10, 'color': 'red'})
v2 = v.with_attrs(value=20)      # Immutable update
v3 = v.without_attrs('color')    # Remove attribute

Edge

from AlgoGraph import Edge

e = Edge('A', 'B', directed=True, weight=5.0)
e2 = e.with_weight(10.0)  # Immutable update
e3 = e.reversed()         # B -> A

Graph

from AlgoGraph import Graph, Vertex, Edge

# Direct construction
g = Graph({Vertex('A'), Vertex('B')}, {Edge('A', 'B')})

# Fluent builder
g = (Graph.builder()
     .add_vertex('A', age=30)
     .add_edge('A', 'B', weight=5.0)
     .add_path('B', 'C', 'D')
     .add_cycle('X', 'Y', 'Z')
     .build())

# From edges (auto-creates vertices)
g = Graph.from_edges(('A', 'B'), ('B', 'C'), ('C', 'A'))

# Immutable operations
g2 = g.add_vertex(Vertex('D'))
g3 = g.remove_vertex('A')
g4 = g.subgraph({'B', 'C', 'D'})

Algorithms

Traversal

from AlgoGraph.algorithms import dfs, bfs, topological_sort, has_cycle, find_path

visited = dfs(graph, start_vertex='A')
levels = bfs(graph, start_vertex='A')
order = topological_sort(graph)  # DAG only
path = find_path(graph, 'A', 'Z')

Shortest Paths

from AlgoGraph.algorithms import dijkstra, bellman_ford, floyd_warshall, a_star

distances = dijkstra(graph, source='A')
distances = bellman_ford(graph, source='A')  # Handles negative weights
all_pairs = floyd_warshall(graph)
path = a_star(graph, 'A', 'Z', heuristic=h)

Connectivity

from AlgoGraph.algorithms import (
    connected_components, strongly_connected_components,
    is_connected, is_bipartite, find_bridges, find_articulation_points
)

components = connected_components(graph)
scc = strongly_connected_components(graph)
bridges = find_bridges(graph)
articulation = find_articulation_points(graph)

Spanning Trees

from AlgoGraph.algorithms import minimum_spanning_tree, kruskal, prim

mst = minimum_spanning_tree(graph)
mst = kruskal(graph)
mst = prim(graph, start='A')

Centrality

from AlgoGraph.algorithms import (
    pagerank, betweenness_centrality, closeness_centrality,
    degree_centrality, eigenvector_centrality
)

pr = pagerank(social_network)
bc = betweenness_centrality(network)
cc = closeness_centrality(network)

Flow Networks

from AlgoGraph.algorithms import max_flow, min_cut, edmonds_karp

flow_value = max_flow(network, 'Source', 'Sink')
cut_value, source_set, sink_set = min_cut(network, 'Source', 'Sink')

Matching

from AlgoGraph.algorithms import hopcroft_karp, maximum_bipartite_matching, is_perfect_matching

matching = hopcroft_karp(bipartite_graph, left_set, right_set)
max_matching = maximum_bipartite_matching(graph, left, right)

Graph Coloring

from AlgoGraph.algorithms import welsh_powell, chromatic_number, dsatur, is_k_colorable

coloring = welsh_powell(graph)
num_colors = chromatic_number(graph)
coloring = dsatur(graph)  # Often better than greedy

Serialization

from AlgoGraph import save_graph, load_graph

# Save/load JSON
save_graph(graph, 'network.json')
graph = load_graph('network.json')

AlgoTree Integration (Optional)

from AlgoTree import Node, Tree
from AlgoGraph import tree_to_graph, graph_to_tree

# Tree to Graph
tree = Tree(Node('root', Node('child1'), Node('child2')))
graph = tree_to_graph(tree)

# Graph to Tree (extracts spanning tree)
tree = graph_to_tree(graph, root='root')

Interactive Shell

Explore graphs with a filesystem-like interface:

pip install AlgoGraph
algograph                    # Start with sample graph
algograph network.json       # Load from file
graph(5v):/$ ls
Alice/  [2 neighbors]
Bob/    [3 neighbors]

graph(5v):/$ cd Alice
graph(5v):/Alice$ ls
Attributes:
  age = 30
neighbors/  [2 vertices]

graph(5v):/Alice$ path Bob Eve
Path found: Alice -> Bob -> Diana -> Eve

Examples

Social Network Analysis

from AlgoGraph import Graph
from AlgoGraph.algorithms import pagerank, betweenness_centrality
from AlgoGraph.transformers import filter_vertices, stats
from AlgoGraph.graph_selectors import vertex as v

# Build network
network = (Graph.builder()
    .add_vertex('Alice', followers=1000)
    .add_vertex('Bob', followers=500)
    .add_vertex('Charlie', followers=2000)
    .add_edge('Alice', 'Bob', directed=False)
    .add_edge('Bob', 'Charlie', directed=False)
    .add_edge('Alice', 'Charlie', directed=False)
    .build())

# Find influencers
pr = pagerank(network)
top_influencer = max(pr, key=pr.get)

# Find power users with selector
power_users = network.select_vertices(
    v.attrs(followers=lambda f: f > 800)
)

# Analyze active subgraph
analysis = (network
    | filter_vertices(lambda v: v.get('followers', 0) > 500)
    | stats())

Road Network

from AlgoGraph import Graph
from AlgoGraph.algorithms import dijkstra, minimum_spanning_tree

roads = (Graph.builder()
    .add_edge('NYC', 'Boston', weight=215, directed=False)
    .add_edge('NYC', 'DC', weight=225, directed=False)
    .add_edge('Boston', 'DC', weight=440, directed=False)
    .build())

# Shortest routes from NYC
distances = dijkstra(roads, 'NYC')

# Minimum cost network
mst = minimum_spanning_tree(roads)

Design Philosophy

  1. Immutability: All operations return new objects
  2. Composability: Chain operations with | pipe operator
  3. Declarative: Express what, not how (selectors vs lambdas)
  4. Lazy evaluation: Views defer computation until needed
  5. Type safety: Full type hints throughout

Related Projects

  • AlgoTree: Tree data structures and algorithms
  • NetworkX: Comprehensive Python graph library (mutable)
  • graph-tool: High-performance graph analysis

License

MIT License - see LICENSE file for details.

Release files for AlgoGraph 2.1.0

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

Source distribution (sdist)

Source distribution for AlgoGraph 2.1.0
File Size Uploaded
algograph-2.1.0.tar.gz 90.2 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for AlgoGraph 2.1.0
File Interpreter ABI Platform
algograph-2.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 160.9 kB

Release files / algograph-2.1.0.tar.gz

Download URL algograph-2.1.0.tar.gz
Size 90.2 kB
Tags Source
SHA-256 checksum
How to use checksums
eec29673d2223088f6f63cc4851fc9655054725e4139da6115bab224252512ca
BLAKE2b-256 checksum
How to use checksums
7f2d350816df9e3bc39924b3038b4cd943320949775c9a3ffea0e0f00b533fe9
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.12.3

Release files / algograph-2.1.0-py3-none-any.whl

Download URL algograph-2.1.0-py3-none-any.whl
Size 70.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
43b4cc40148ffdc94ed1cec69c955a031cda8b61db4b5b42a83fc0e73a19e3b8
BLAKE2b-256 checksum
How to use checksums
245db4c2ba8f3a8bec69a4888289f0517c00095bfa1e0aeff5740ece5dd8f535
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.12.3

Release history Release notifications | RSS feed

This release

2.1.0 This release

2 release files

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