8000 GitHub - p-sodmann/Ironweaver
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

p-sodmann/Ironweaver

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

31 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

IronWeaver

Logo

A high-performance, Rust-powered Python library for graph data structures and algorithms. Built with PyO3, IronWeaver provides fast, memory-efficient graph operations with seamless Python integration.

🚀 Features

  • High Performance: Rust-powered backend for blazing-fast graph operations
  • Rich Graph API: Intuitive Python interface for creating and manipulating graphs
  • Advanced Algorithms: BFS, shortest path, graph expansion, and filtering
  • NetworkX Integration: Seamless conversion to NetworkX for visualization
  • Serialization: JSON and binary save/load capabilities
  • Event-Driven: Callback system for node and edge modifications
  • Memory Efficient: Optimized Rust implementation for large graphs

Installation

FIXME: this will not work yet, it needs to be cloned from github, rust compiled and installed

pip install IronWeaver

Quick Start

Basic Graph Creation

from ironweaver import Vertex, Node, Edge
import networkx as nx
import matplotlib.pyplot as plt

# Create a new graph
graph = Vertex()

# Add nodes with attributes
node1 = graph.add_node('node1', {'value': 1, 'type': 'start'})
node2 = graph.add_node('node2', {'value': 2, 'type': 'process'})
node3 = graph.add_node('node3', {'value': 3, 'type': 'end'})

# Add edges with weights
edge1 = graph.add_edge('node1', 'node2', {'weight': 1.0})
edge2 = graph.add_edge('node2', 'node3', {'weight': 2.0})
edge3 = graph.add_edge('node1', 'node3', {'weight': 3.0})

print(f"Graph: {graph}")
print(f"Node count: {graph.node_count()}")

Graph Visualization

# Convert to NetworkX for visualization
nx_graph = graph.to_networkx()

# Visualize with matplotlib
plt.figure(figsize=(10, 8))
pos = nx.spring_layout(nx_graph)
nx.draw(nx_graph, 
        pos=pos,
        with_labels=True, 
        node_color='lightblue', 
        node_size=1000,
        font_size=12,
        font_weight='bold', 
        edge_color='gray',
        arrows=True)
plt.title("Graph Visualization")
plt.show()

🔬 Advanced Features

Shortest Path Finding

# Find shortest path between nodes using BFS
path = graph.shortest_path_bfs('node1', 'node3')
print(f"Shortest path: {path}")

# Visualize the path
path_nx = path.to_networkx()
nx.draw(path_nx, with_labels=True, node_color='orange')
plt.title("Shortest Path from node1 to node3")
plt.show()

Graph Expansion

# Create a subgraph and expand it by exploring neighbors
filtered_graph = graph.filter(['node2'])  # Start with just node2
expanded = filtered_graph.expand(graph, depth=1)  # Expand 1 level

print(f"Original nodes: {graph.keys()}")
print(f"Filtered nodes: {filtered_graph.keys()}")
print(f"Expanded nodes: {expanded.keys()}")

Event-Driven Programming

# Set up callbacks for graph modifications
def on_node_added(vertex, node):
    print(f"Node added: {node.id}")
    # Track visited nodes in metadata
    if "visited_nodes" not in vertex.meta:
        vertex.meta["visited_nodes"] = []
    vertex.meta["visited_nodes"].append(node.id)
    return True  # Continue processing

def on_edge_added(vertex, edge):
    print(f"Edge added: {edge.from_node.id} -> {edge.to_node.id}")
    edge.meta["timestamp"] = "2025-05-25"
    return True

# Register callbacks
graph.on_node_add_callbacks.append(on_node_added)
graph.on_edge_add_callbacks.append(on_edge_added)

# Add nodes and edges - callbacks will be triggered
new_node = graph.add_node('node4', {'value': 4})
new_edge = graph.add_edge('node3', 'node4', {'weight': 1.5})

print(f"Graph metadata: {graph.meta}")

Persistence

# Save graph to JSON
graph.save_to_json("my_graph.json")

# Save to binary format (more efficient for large graphs)
graph.save_to_binary("my_graph.bin")
# Or use half precision floats to reduce file size
graph.save_to_binary_f16("my_graph_f16.bin")

# Load from file
loaded_graph = Vertex.load_from_json("my_graph.json")
print(f"Loaded graph: {loaded_graph}")
print(f"Metadata: {loaded_graph.get_metadata()}")

API Reference

Core Classes

Vertex

The main graph container that holds nodes and provides graph-level operations.

# Create empty graph
graph = Vertex()

# Node operations
node = graph.add_node(id: str, attr: dict = None) -> Node
node = graph.get_node(id: str) -> Node
exists = graph.has_node(id: str) -> bool
count = graph.node_count() -> int

# Edge operations  
edge = graph.add_edge(from_id: str, to_id: str, attr: dict = None) -> Edge

# Algorithms
path = graph.shortest_path_bfs(start: str, end: str, max_depth: int = None) -> Vertex
expanded = graph.expand(source: Vertex, depth: int = 1) -> Vertex
filtered = graph.filter(node_ids: List[str]) -> Vertex

# Conversion and analysis
nx_graph = graph.to_networkx() -> networkx.DiGraph
metadata = graph.get_metadata() -> dict

# Persistence
graph.save_to_json(file_path: str)
graph.save_to_binary(file_path: str)
graph.save_to_binary_f16(file_path: str)
loaded = Vertex.load_from_json(file_path: str) -> Vertex
loaded = Vertex.load_from_binary(file_path: str) -> Vertex

Node

Represents individual vertices in the graph with attributes and edges.

# Access node properties
id = node.id  # Node identifier
attrs = node.attr  # Node attributes dict
edges = node.edges  # List of outgoing edges

# Traversal from node
reachable = node.traverse(depth: int = None) -> Vertex
bfs_result = node.bfs(depth: int = None) -> Vertex
found = node.bfs_search(target_id: str, depth: int = None) -> Node

Edge

Represents connections between nodes with optional attributes.

# Access edge properties
from_node = edge.from_node  # Source node
to_node = edge.to_node      # Target node
attrs = edge.attr           # Edge attributes dict

Performance

IronWeaver is built with performance in mind:

  • Rust Backend: Core algorithms implemented in Rust for maximum speed
  • Memory Efficient: Optimized data structures for large graphs
  • Minimal Overhead: PyO3 bindings provide near-native performance
  • Scalable: Tested with graphs containing thousands of nodes and edges

Benchmarks

The library includes comprehensive performance testing for various graph operations:

  • BFS traversal performance
  • Shortest path algorithms
  • Graph expansion operations
  • Memory usage optimization
  • Cyclic graph handling

See the performance_results/ directory for detailed benchmarks.

Contributing

Contributions are welcome! Please see our contributing guidelines for more information.

Development Setup

# Clone the repository
git clone <repository-url>
cd ironweaver

# Build the Rust extension
maturin develop

# Run tests
pytest

License

TODO: Add license information here.

Acknowledgments

  • Built with PyO3 for Rust-Python bindings
  • Compatible with NetworkX for visualization
  • Inspired by the need for high-performance graph operations in Python

Note: This library is designed for applications requiring high-performance graph operations. For simple use cases, NetworkX might be more appropriate. For complex, large-scale graph analysis, IronWeaver might provide significant performance advantages. Initially it was developed for the Gustabor project.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published
0