groggy


Namegroggy JSON
Version 0.3.1 PyPI version JSON
download
home_pageNone
SummaryGroggy - A Graph Language Engine for dynamic graphs and versioned state
upload_time2025-09-01 15:16:14
maintainerNone
docs_urlNone
authorGroggy Contributors
requires_python>=3.8
licenseMIT
keywords graph network data-structure algorithms
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # Groggy

**A graph analytics library for Python with a Rust core**

<div align="center">
  <img src="img/groggy.svg" alt="Groggy Logo" width="300"/>
</div>

---

## ๐Ÿš€ **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.

> ๐Ÿš€ **NEW in v0.4.0**: Complete architecture overhaul with GraphEntity foundation! All previously broken subgraph operations (BFS, DFS, shortest_path) now work correctly. See [Release Notes](documentation/releases/RELEASE_NOTES_v0.4.0.md) for details.

### **Key Features:**
- ๐Ÿ”ฅ **High-performance Rust core** with Python bindings
- ๐Ÿ“Š **Unified data structures**: GraphArray, GraphTable, GraphMatrix
- ๐ŸŽฏ **Graph-aware analytics** with table operations
- ๐Ÿ†• **Fixed subgraph operations**: BFS, DFS, shortest_path now work correctly
- ๐Ÿ†• **GraphEntity system**: Universal trait-based architecture
- ๐Ÿ†• **Enhanced connectivity**: Efficient `has_path()` method
---

## ๐Ÿ“ฅ **Installation**

### From Source
```bash
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
```python
import groggy as gr
print("Groggy installed successfully! ๐ŸŽ‰")
```

---

## ๐Ÿš€ **Quick Start**

### **Basic Graph Operations**
```python
import groggy as gr

# Create a graph
g = gr.Graph()

# Add nodes with attributes (returns numeric IDs)
alice = g.add_node(name="Alice", age=30, dept="Engineering")
bob = g.add_node(name="Bob", age=25, dept="Design")  
charlie = g.add_node(name="Charlie", age=35, dept="Management")

# Add edges with attributes
g.add_edge(alice, bob, weight=0.8, type="collaborates")
g.add_edge(charlie, alice, weight=0.9, type="manages")

print(f"Graph: {g.node_count()} nodes, {g.edge_count()} edges")
```

### **Table-Style Data Access**
```python
# Get node data as a table
nodes_table = g.nodes.table()
print(nodes_table)
# โŠ–โŠ– gr.table
# โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ
# โ”‚    # โ”‚ name  โ”‚ age  โ”‚ dept         โ”‚
# โ”‚      โ”‚ str   โ”‚ i64  โ”‚ str          โ”‚
# โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
# โ”‚    0 โ”‚ Alice โ”‚ 30   โ”‚ Engineering  โ”‚
# โ”‚    1 โ”‚ Bob   โ”‚ 25   โ”‚ Design       โ”‚
# โ”‚    2 โ”‚ Charlieโ”‚ 35   โ”‚ Management   โ”‚
# โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ

# Statistical analysis on columns
age_column = nodes_table['age']
print(f"Average age: {age_column.mean()}")
print(f"Age range: {age_column.min()} - {age_column.max()}")

# Table-style operations
print(nodes_table.describe())  # Statistical summary
young_nodes = nodes_table[nodes_table['age'] < 30]  # Boolean filtering
```

### **Graph Analytics**
```python
# Add edge to connect nodes first
g.add_edge(alice, bob, weight=0.8)

# Connected components
components = g.connected_components()
print(f"Components: {len(components)}")

# Shortest paths  
path = g.shortest_path(alice, bob)
print(f"Shortest path: {path}")

# Graph properties
print(f"Graph density: {g.density()}")
print(f"Is connected: {g.is_connected()}")

# Neighborhood analysis
neighbors = g.neighbors(alice)
print(f"Alice's neighbors: {neighbors}")

# NEW in v0.4.0 - Fixed subgraph operations!
# Get a component (subgraph) and perform traversals
component = components[0]  # Get first connected component
bfs_result = component.bfs(alice)  # BFS traversal (now works!)
dfs_result = component.dfs(alice)  # DFS traversal (now works!)

# NEW - Efficient connectivity checking
has_path = component.has_path(alice, bob)
print(f"Path from Alice to Bob: {has_path}")
```

### **Advanced Features**
```python
# Filtering with graph-aware operations
engineering = g.filter_nodes(gr.NodeFilter.attribute_filter("dept", "==", "Engineering"))
print(f"Engineering team: {engineering.node_count()} people")

# Adjacency matrix operations  
adj_matrix = g.adjacency()
print(f"Matrix shape: {adj_matrix.shape}")
print(f"Density: {adj_matrix.sum_axis(1)}")  # Row sums (node degrees)

# Export compatibility
import networkx as nx
import pandas as pd
nx_graph = g.to_networkx()           # NetworkX compatibility
df = nodes_table.to_pandas()         # Pandas DataFrame
numpy_matrix = adj_matrix.to_numpy() # NumPy array
```

---

## ๐Ÿ—๏ธ **Core Architecture**

### **Data Structures**
- **`Graph`**: Main graph container with nodes, edges, and attributes
- **`GraphArray`**: High-performance columnar arrays with statistics (like Pandas Series)
- **`GraphTable`**: Table operations on graph data (like Pandas DataFrame)  
- **`GraphMatrix`**: Matrix operations including adjacency matrices
- **`Subgraph`**: Filtered views of the main graph

### **Key Concepts**
- **Node/Edge IDs**: Groggy uses numeric IDs (not strings) returned from `add_node()`/`add_edge()`
- **Attributes**: Rich attribute system supporting strings, numbers, booleans
- **Lazy Views**: Data structures are views that only materialize when needed
- **Unified API**: Same operations work on graphs, tables, arrays, and matrices

---

## ๐Ÿ”ง **API Reference**

### **Graph Operations**
```python
# Graph creation
g = gr.Graph(directed=False)  # Undirected graph (default)
g = gr.Graph(directed=True)   # Directed graph

# Node operations
node_id = g.add_node(**attributes)      # Returns numeric ID
g.add_nodes(data_list)                  # Bulk node creation
g.set_node_attribute(node_id, "key", value)

# Edge operations  
edge_id = g.add_edge(source, target, **attributes)
g.add_edges(edge_list)                  # Bulk edge creation
g.set_edge_attribute(edge_id, "key", value)

# Graph properties
g.node_count()                          # Number of nodes
g.edge_count()                          # Number of edges  
g.density()                             # Graph density
g.is_connected()                        # Connectivity check
g.degree(node_id)                       # Node degree
```

### **Data Access**
```python
# Accessor objects
g.nodes                                 # NodesAccessor
g.edges                                 # EdgesAccessor

# Table access
nodes_table = g.nodes.table()           # All nodes as GraphTable
edges_table = g.edges.table()           # All edges as GraphTable
subgraph_table = subgraph.table()       # Subgraph data as GraphTable

# Array access (single columns)
ages = nodes_table['age']               # GraphArray of ages
weights = edges_table['weight']         # GraphArray of edge weights

# Node/edge data access
node_data = g.nodes[node_id]            # Dictionary of node attributes
edge_data = g.edges[edge_id]            # Dictionary of edge attributes
```

### **Filtering & Subgraphs**
```python
# Node filtering
young = g.filter_nodes(gr.NodeFilter.attribute_filter("age", "<", 30))
engineers = g.filter_nodes(gr.NodeFilter.attribute_filter("dept", "==", "Engineering"))

# Edge filtering  
strong = g.filter_edges(gr.EdgeFilter.attribute_filter("weight", ">", 0.5))

# Subgraph operations (all return Subgraph objects)
components = g.analytics.connected_components()
subgraph = g.nodes[:10]                 # First 10 nodes
filtered = g.filter_nodes(filter_obj)   # Filtered nodes
```

### **Analytics**
```python
# Graph algorithms (g.analytics.*)
g.analytics.connected_components()      # List of connected components
g.analytics.shortest_path(start, end)  # Shortest path between nodes
g.analytics.bfs(start_node)            # Breadth-first search
g.analytics.dfs(start_node)            # Depth-first search

# Matrix operations
adj = g.adjacency()                     # Adjacency matrix as GraphMatrix
adj[i, j]                              # Matrix element access
adj.sum_axis(0)                        # Column sums (in-degrees)
adj.sum_axis(1)                        # Row sums (out-degrees)
adj.to_numpy()                         # Convert to NumPy array
```

---

## ๐Ÿ“š **Documentation**

- **[User Guide](docs/user-guide/)**: Comprehensive tutorials and examples
- **[API Reference](docs/api/)**: Complete method documentation  
- **[Quickstart](docs/quickstart.rst)**: Get up and running quickly
- **[Architecture](docs/architecture/)**: Internal design and Rust core details

---

## ๐Ÿงช **Testing**

Groggy includes tests and validation scripts:

### **Rust Core Tests**
```bash
# Run Rust unit tests
cargo test

# Run specific test module
cargo test core::array
```

### **Python Integration Tests**
```bash
# Run comprehensive documentation validation
python tests/test_documentation_validation.py

# Quick validation test
python tests/simple_validation_test.py

# Full validation suite  
python tests/validation_test_suite.py
```

**Current validation results: 95%+ documented features working correctly** โœ…

**Test Coverage**: Rust unit tests + comprehensive Python validation scripts ensure reliability.

---

## ๐Ÿ› ๏ธ **Development**

### **Project Structure**
```
groggy/
โ”œโ”€โ”€ src/                    # Rust core library  
โ”‚   โ”œโ”€โ”€ core/              # Core data structures and algorithms (with unit tests)
โ”‚   โ”œโ”€โ”€ api/               # High-level graph API
โ”‚   โ””โ”€โ”€ display/           # Rich formatting and display
โ”œโ”€โ”€ python-groggy/         # Python bindings and package
โ”‚   โ”œโ”€โ”€ src/ffi/          # Rust-to-Python FFI layer  
โ”‚   โ””โ”€โ”€ python/groggy/    # Python package code
โ”œโ”€โ”€ docs/                  # Sphinx documentation (RST)
โ”œโ”€โ”€ documentation/         # Development docs (Markdown)
โ”‚   โ”œโ”€โ”€ development/      # Development documentation  
โ”‚   โ”œโ”€โ”€ planning/         # Architecture plans  
โ”‚   โ”œโ”€โ”€ releases/         # Release notes
โ”‚   โ””โ”€โ”€ examples/         # Usage examples
โ”œโ”€โ”€ tests/                 # Python validation and integration tests
โ””โ”€โ”€ notebooks/             # Jupyter notebooks for testing/demos
```

### **Building & Testing**
```bash
# 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**
1. Fork the repository
2. Create a feature branch
3. Make your changes with tests
4. Run validation scripts to ensure docs work
5. Submit a pull request

---

## โš–๏ธ **License**

MIT License - see [LICENSE](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

---

**Ready to get started? Try the [Quick Start](#-quick-start) above!** ๐Ÿš€

            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "groggy",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.8",
    "maintainer_email": null,
    "keywords": "graph, network, data-structure, algorithms",
    "author": "Groggy Contributors",
    "author_email": null,
    "download_url": "https://files.pythonhosted.org/packages/c7/8a/c3e72a4e92a59a88b066da99d27802686e0f9aa60ce7890fab1989fbebca/groggy-0.3.1.tar.gz",
    "platform": null,
    "description": "# Groggy\n\n**A graph analytics library for Python with a Rust core**\n\n<div align=\"center\">\n  <img src=\"img/groggy.svg\" alt=\"Groggy Logo\" width=\"300\"/>\n</div>\n\n---\n\n## \ud83d\ude80 **What is Groggy?**\n\nGroggy 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.\n\n> \ud83d\ude80 **NEW in v0.4.0**: Complete architecture overhaul with GraphEntity foundation! All previously broken subgraph operations (BFS, DFS, shortest_path) now work correctly. See [Release Notes](documentation/releases/RELEASE_NOTES_v0.4.0.md) for details.\n\n### **Key Features:**\n- \ud83d\udd25 **High-performance Rust core** with Python bindings\n- \ud83d\udcca **Unified data structures**: GraphArray, GraphTable, GraphMatrix\n- \ud83c\udfaf **Graph-aware analytics** with table operations\n- \ud83c\udd95 **Fixed subgraph operations**: BFS, DFS, shortest_path now work correctly\n- \ud83c\udd95 **GraphEntity system**: Universal trait-based architecture\n- \ud83c\udd95 **Enhanced connectivity**: Efficient `has_path()` method\n---\n\n## \ud83d\udce5 **Installation**\n\n### From Source\n```bash\ngit clone https://github.com/rollingstorms/groggy.git\ncd groggy/python-groggy\n\n# Install dependencies\npip install maturin\n\n# Build and install\nmaturin develop --release\n```\n\n### Quick Test\n```python\nimport groggy as gr\nprint(\"Groggy installed successfully! \ud83c\udf89\")\n```\n\n---\n\n## \ud83d\ude80 **Quick Start**\n\n### **Basic Graph Operations**\n```python\nimport groggy as gr\n\n# Create a graph\ng = gr.Graph()\n\n# Add nodes with attributes (returns numeric IDs)\nalice = g.add_node(name=\"Alice\", age=30, dept=\"Engineering\")\nbob = g.add_node(name=\"Bob\", age=25, dept=\"Design\")  \ncharlie = g.add_node(name=\"Charlie\", age=35, dept=\"Management\")\n\n# Add edges with attributes\ng.add_edge(alice, bob, weight=0.8, type=\"collaborates\")\ng.add_edge(charlie, alice, weight=0.9, type=\"manages\")\n\nprint(f\"Graph: {g.node_count()} nodes, {g.edge_count()} edges\")\n```\n\n### **Table-Style Data Access**\n```python\n# Get node data as a table\nnodes_table = g.nodes.table()\nprint(nodes_table)\n# \u2296\u2296 gr.table\n# \u256d\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256e\n# \u2502    # \u2502 name  \u2502 age  \u2502 dept         \u2502\n# \u2502      \u2502 str   \u2502 i64  \u2502 str          \u2502\n# \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n# \u2502    0 \u2502 Alice \u2502 30   \u2502 Engineering  \u2502\n# \u2502    1 \u2502 Bob   \u2502 25   \u2502 Design       \u2502\n# \u2502    2 \u2502 Charlie\u2502 35   \u2502 Management   \u2502\n# \u2570\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256f\n\n# Statistical analysis on columns\nage_column = nodes_table['age']\nprint(f\"Average age: {age_column.mean()}\")\nprint(f\"Age range: {age_column.min()} - {age_column.max()}\")\n\n# Table-style operations\nprint(nodes_table.describe())  # Statistical summary\nyoung_nodes = nodes_table[nodes_table['age'] < 30]  # Boolean filtering\n```\n\n### **Graph Analytics**\n```python\n# Add edge to connect nodes first\ng.add_edge(alice, bob, weight=0.8)\n\n# Connected components\ncomponents = g.connected_components()\nprint(f\"Components: {len(components)}\")\n\n# Shortest paths  \npath = g.shortest_path(alice, bob)\nprint(f\"Shortest path: {path}\")\n\n# Graph properties\nprint(f\"Graph density: {g.density()}\")\nprint(f\"Is connected: {g.is_connected()}\")\n\n# Neighborhood analysis\nneighbors = g.neighbors(alice)\nprint(f\"Alice's neighbors: {neighbors}\")\n\n# NEW in v0.4.0 - Fixed subgraph operations!\n# Get a component (subgraph) and perform traversals\ncomponent = components[0]  # Get first connected component\nbfs_result = component.bfs(alice)  # BFS traversal (now works!)\ndfs_result = component.dfs(alice)  # DFS traversal (now works!)\n\n# NEW - Efficient connectivity checking\nhas_path = component.has_path(alice, bob)\nprint(f\"Path from Alice to Bob: {has_path}\")\n```\n\n### **Advanced Features**\n```python\n# Filtering with graph-aware operations\nengineering = g.filter_nodes(gr.NodeFilter.attribute_filter(\"dept\", \"==\", \"Engineering\"))\nprint(f\"Engineering team: {engineering.node_count()} people\")\n\n# Adjacency matrix operations  \nadj_matrix = g.adjacency()\nprint(f\"Matrix shape: {adj_matrix.shape}\")\nprint(f\"Density: {adj_matrix.sum_axis(1)}\")  # Row sums (node degrees)\n\n# Export compatibility\nimport networkx as nx\nimport pandas as pd\nnx_graph = g.to_networkx()           # NetworkX compatibility\ndf = nodes_table.to_pandas()         # Pandas DataFrame\nnumpy_matrix = adj_matrix.to_numpy() # NumPy array\n```\n\n---\n\n## \ud83c\udfd7\ufe0f **Core Architecture**\n\n### **Data Structures**\n- **`Graph`**: Main graph container with nodes, edges, and attributes\n- **`GraphArray`**: High-performance columnar arrays with statistics (like Pandas Series)\n- **`GraphTable`**: Table operations on graph data (like Pandas DataFrame)  \n- **`GraphMatrix`**: Matrix operations including adjacency matrices\n- **`Subgraph`**: Filtered views of the main graph\n\n### **Key Concepts**\n- **Node/Edge IDs**: Groggy uses numeric IDs (not strings) returned from `add_node()`/`add_edge()`\n- **Attributes**: Rich attribute system supporting strings, numbers, booleans\n- **Lazy Views**: Data structures are views that only materialize when needed\n- **Unified API**: Same operations work on graphs, tables, arrays, and matrices\n\n---\n\n## \ud83d\udd27 **API Reference**\n\n### **Graph Operations**\n```python\n# Graph creation\ng = gr.Graph(directed=False)  # Undirected graph (default)\ng = gr.Graph(directed=True)   # Directed graph\n\n# Node operations\nnode_id = g.add_node(**attributes)      # Returns numeric ID\ng.add_nodes(data_list)                  # Bulk node creation\ng.set_node_attribute(node_id, \"key\", value)\n\n# Edge operations  \nedge_id = g.add_edge(source, target, **attributes)\ng.add_edges(edge_list)                  # Bulk edge creation\ng.set_edge_attribute(edge_id, \"key\", value)\n\n# Graph properties\ng.node_count()                          # Number of nodes\ng.edge_count()                          # Number of edges  \ng.density()                             # Graph density\ng.is_connected()                        # Connectivity check\ng.degree(node_id)                       # Node degree\n```\n\n### **Data Access**\n```python\n# Accessor objects\ng.nodes                                 # NodesAccessor\ng.edges                                 # EdgesAccessor\n\n# Table access\nnodes_table = g.nodes.table()           # All nodes as GraphTable\nedges_table = g.edges.table()           # All edges as GraphTable\nsubgraph_table = subgraph.table()       # Subgraph data as GraphTable\n\n# Array access (single columns)\nages = nodes_table['age']               # GraphArray of ages\nweights = edges_table['weight']         # GraphArray of edge weights\n\n# Node/edge data access\nnode_data = g.nodes[node_id]            # Dictionary of node attributes\nedge_data = g.edges[edge_id]            # Dictionary of edge attributes\n```\n\n### **Filtering & Subgraphs**\n```python\n# Node filtering\nyoung = g.filter_nodes(gr.NodeFilter.attribute_filter(\"age\", \"<\", 30))\nengineers = g.filter_nodes(gr.NodeFilter.attribute_filter(\"dept\", \"==\", \"Engineering\"))\n\n# Edge filtering  \nstrong = g.filter_edges(gr.EdgeFilter.attribute_filter(\"weight\", \">\", 0.5))\n\n# Subgraph operations (all return Subgraph objects)\ncomponents = g.analytics.connected_components()\nsubgraph = g.nodes[:10]                 # First 10 nodes\nfiltered = g.filter_nodes(filter_obj)   # Filtered nodes\n```\n\n### **Analytics**\n```python\n# Graph algorithms (g.analytics.*)\ng.analytics.connected_components()      # List of connected components\ng.analytics.shortest_path(start, end)  # Shortest path between nodes\ng.analytics.bfs(start_node)            # Breadth-first search\ng.analytics.dfs(start_node)            # Depth-first search\n\n# Matrix operations\nadj = g.adjacency()                     # Adjacency matrix as GraphMatrix\nadj[i, j]                              # Matrix element access\nadj.sum_axis(0)                        # Column sums (in-degrees)\nadj.sum_axis(1)                        # Row sums (out-degrees)\nadj.to_numpy()                         # Convert to NumPy array\n```\n\n---\n\n## \ud83d\udcda **Documentation**\n\n- **[User Guide](docs/user-guide/)**: Comprehensive tutorials and examples\n- **[API Reference](docs/api/)**: Complete method documentation  \n- **[Quickstart](docs/quickstart.rst)**: Get up and running quickly\n- **[Architecture](docs/architecture/)**: Internal design and Rust core details\n\n---\n\n## \ud83e\uddea **Testing**\n\nGroggy includes tests and validation scripts:\n\n### **Rust Core Tests**\n```bash\n# Run Rust unit tests\ncargo test\n\n# Run specific test module\ncargo test core::array\n```\n\n### **Python Integration Tests**\n```bash\n# Run comprehensive documentation validation\npython tests/test_documentation_validation.py\n\n# Quick validation test\npython tests/simple_validation_test.py\n\n# Full validation suite  \npython tests/validation_test_suite.py\n```\n\n**Current validation results: 95%+ documented features working correctly** \u2705\n\n**Test Coverage**: Rust unit tests + comprehensive Python validation scripts ensure reliability.\n\n---\n\n## \ud83d\udee0\ufe0f **Development**\n\n### **Project Structure**\n```\ngroggy/\n\u251c\u2500\u2500 src/                    # Rust core library  \n\u2502   \u251c\u2500\u2500 core/              # Core data structures and algorithms (with unit tests)\n\u2502   \u251c\u2500\u2500 api/               # High-level graph API\n\u2502   \u2514\u2500\u2500 display/           # Rich formatting and display\n\u251c\u2500\u2500 python-groggy/         # Python bindings and package\n\u2502   \u251c\u2500\u2500 src/ffi/          # Rust-to-Python FFI layer  \n\u2502   \u2514\u2500\u2500 python/groggy/    # Python package code\n\u251c\u2500\u2500 docs/                  # Sphinx documentation (RST)\n\u251c\u2500\u2500 documentation/         # Development docs (Markdown)\n\u2502   \u251c\u2500\u2500 development/      # Development documentation  \n\u2502   \u251c\u2500\u2500 planning/         # Architecture plans  \n\u2502   \u251c\u2500\u2500 releases/         # Release notes\n\u2502   \u2514\u2500\u2500 examples/         # Usage examples\n\u251c\u2500\u2500 tests/                 # Python validation and integration tests\n\u2514\u2500\u2500 notebooks/             # Jupyter notebooks for testing/demos\n```\n\n### **Building & Testing**\n```bash\n# Build development version\nmaturin develop\n\n# Build release version  \nmaturin develop --release\n\n# Run formatting\ncargo fmt\n\n# Run Rust tests\ncargo test\n\n# Run Python tests\npython tests/test_documentation_validation.py\n```\n\n### **Contributing**\n1. Fork the repository\n2. Create a feature branch\n3. Make your changes with tests\n4. Run validation scripts to ensure docs work\n5. Submit a pull request\n\n---\n\n## \u2696\ufe0f **License**\n\nMIT License - see [LICENSE](LICENSE) for details.\n\n---\n\n## \ud83d\ude4f **Acknowledgments**\n\nGroggy builds on the excellent work of:\n- **Rust ecosystem**: Especially PyO3 for Python bindings\n- **Graph libraries**: NetworkX, igraph, and others for inspiration  \n- **Data science tools**: Pandas, NumPy for API design patterns\n\n---\n\n**Ready to get started? Try the [Quick Start](#-quick-start) above!** \ud83d\ude80\n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "Groggy - A Graph Language Engine for dynamic graphs and versioned state",
    "version": "0.3.1",
    "project_urls": {
        "Documentation": "https://groggy.readthedocs.io",
        "Homepage": "https://github.com/rollingstorms/groggy",
        "Repository": "https://github.com/rollingstorms/groggy"
    },
    "split_keywords": [
        "graph",
        " network",
        " data-structure",
        " algorithms"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "0486dfa8b38e604ef412e88553a6e2065b159054d1ad19a27267448f85243dcb",
                "md5": "0c402d02245ea5f33f5cbf78475305ae",
                "sha256": "c4702d8fd2026721668e8633e7dacb327194af29d814f71eb33c0ffc31015b46"
            },
            "downloads": -1,
            "filename": "groggy-0.3.1-cp310-cp310-manylinux_2_34_x86_64.whl",
            "has_sig": false,
            "md5_digest": "0c402d02245ea5f33f5cbf78475305ae",
            "packagetype": "bdist_wheel",
            "python_version": "cp310",
            "requires_python": ">=3.8",
            "size": 1347506,
            "upload_time": "2025-09-01T15:16:12",
            "upload_time_iso_8601": "2025-09-01T15:16:12.830223Z",
            "url": "https://files.pythonhosted.org/packages/04/86/dfa8b38e604ef412e88553a6e2065b159054d1ad19a27267448f85243dcb/groggy-0.3.1-cp310-cp310-manylinux_2_34_x86_64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "c78ac3e72a4e92a59a88b066da99d27802686e0f9aa60ce7890fab1989fbebca",
                "md5": "e8ea612871af3c5ed37f85c1f8c2c2e3",
                "sha256": "e9684bb0a01cda017f75c6c3dd3111915222724b093ebbf4b69bda644dba1827"
            },
            "downloads": -1,
            "filename": "groggy-0.3.1.tar.gz",
            "has_sig": false,
            "md5_digest": "e8ea612871af3c5ed37f85c1f8c2c2e3",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.8",
            "size": 2111298,
            "upload_time": "2025-09-01T15:16:14",
            "upload_time_iso_8601": "2025-09-01T15:16:14.589956Z",
            "url": "https://files.pythonhosted.org/packages/c7/8a/c3e72a4e92a59a88b066da99d27802686e0f9aa60ce7890fab1989fbebca/groggy-0.3.1.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-09-01 15:16:14",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "rollingstorms",
    "github_project": "groggy",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "lcname": "groggy"
}
        
Elapsed time: 1.45439s