# 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"
}