Metadata-Version: 2.4
Name: netsmith
Version: 0.3.0
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Topic :: Scientific/Engineering
Classifier: Topic :: Scientific/Engineering :: Information Analysis
Classifier: Intended Audience :: Science/Research
Requires-Dist: numpy>=1.23,<3.0.0
Requires-Dist: click>=8.0 ; extra == 'cli'
Requires-Dist: pandas>=1.5,<3.0.0 ; extra == 'cli'
Requires-Dist: pyarrow>=12.0 ; extra == 'cli'
Requires-Dist: pytest>=7.0 ; extra == 'dev'
Requires-Dist: pytest-cov>=4.0 ; extra == 'dev'
Requires-Dist: black>=23.0 ; extra == 'dev'
Requires-Dist: flake8>=6.0 ; extra == 'dev'
Requires-Dist: mypy>=1.0 ; extra == 'dev'
Requires-Dist: isort>=5.12 ; extra == 'dev'
Requires-Dist: click>=8.0 ; extra == 'dev'
Requires-Dist: pandas>=1.5,<3.0.0 ; extra == 'dev'
Requires-Dist: pyarrow>=12.0 ; extra == 'dev'
Requires-Dist: networkx>=3.0,<4.0.0 ; extra == 'networkx'
Requires-Dist: pandas>=1.5,<3.0.0 ; extra == 'pandas'
Requires-Dist: polars>=0.20,<1.0.0 ; extra == 'polars'
Requires-Dist: scipy>=1.9,<2.0.0 ; extra == 'scipy'
Provides-Extra: cli
Provides-Extra: dev
Provides-Extra: networkx
Provides-Extra: pandas
Provides-Extra: polars
Provides-Extra: rust
Provides-Extra: scipy
License-File: LICENSE
Summary: Fast network analysis with Rust kernels: communities, centrality, paths and null models
Author-email: "Kyle T. Jones" <kyle@kyletjones.com>
Requires-Python: >=3.12
Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM

# NetSmith: Fast Network Analysis Library

NetSmith computes the standard network measures — community detection, centrality,
shortest paths, clustering, k-core and null models — on graphs large enough that the
usual Python tools become the bottleneck. The algorithms are Rust kernels that release
the GIL and parallelize across cores; every one has a pure-Python fallback, so the
library works whether or not the compiled extension is present.

It needs only NumPy. NetworkX is optional, and only for converting a graph to one
(`Graph.as_networkx()`) — no computation reaches for it.

```python
import netsmith
from netsmith.core.graph import Graph
from netsmith.core.community import louvain_hooks
from netsmith.api import betweenness

graph = Graph(edges=[(0, 1), (1, 2), (0, 2), (3, 4), (4, 5), (3, 5), (2, 3)], n_nodes=6)

louvain_hooks(graph, seed=42)["n_communities"]   # 2
betweenness(graph)                               # brokerage per node
```

Measured against NetworkX on this machine: betweenness on 5,000 nodes takes 0.34s
against 29.7s (87x), and five degree-preserving null models of a 25,000-edge graph
take 0.11s against 9.4s (86x).

## Architecture

NetSmith follows a four-layer architecture:

### Layer 1: Core
Pure math, no I/O, no global state. Located in `src/netsmith/core/`:
- `graph.py`: Core graph types (`Graph`, `GraphView`)
- `metrics.py`: Degree, centrality (degree, betweenness), assortativity, clustering, k-core, components
- `paths.py`: Shortest paths, reachability, walk metrics
- `community.py`: Modularity, Louvain and label propagation (all built-in kernels)
- `nulls.py`: Null models and permutation tests
- `stats.py`: Distributions, confidence intervals, bootstrap

### Layer 2: Engine
Performance and execution. Located in `src/netsmith/engine/`:
- `python/`: Reference Python implementations
- `rust/`: Rust-accelerated kernels (to be implemented)
- `dispatch.py`: Backend selection (auto, python, rust)
- `contracts.py`: Data contracts (EdgeList, GraphData)

### Layer 3: API
Public surface. Located in `src/netsmith/api/`:
- `load.py`: Load edges from pandas, polars, parquet, csv
- `graph.py`: Public Graph API
- `compute.py`: Stable compute functions (degree, pagerank, communities)
- `validate.py`: Input validation

### Layer 4: Apps
Opinionated use cases. Located in `src/netsmith/apps/`:
- `cli/`: Command-line interface
- `reports/`: HTML/markdown report generation
- `datasets/`: Sample graphs and download helpers

## Data Contracts

Canonical edge representation:
```python
EdgeList(
    u: NDArray[np.int64],      # Source nodes (length m)
    v: NDArray[np.int64],      # Destination nodes (length m)
    w: Optional[NDArray[np.float64]],  # Edge weights (optional)
    directed: bool,
    n_nodes: Optional[int]     # Preferred but inferred if not provided
)
```

## Usage Examples

### Basic Usage

```python
import netsmith
import numpy as np

# Create edge list
u = np.array([0, 1, 2], dtype=np.int64)
v = np.array([1, 2, 0], dtype=np.int64)
edges = netsmith.api.load.EdgeList(u=u, v=v, directed=False, n_nodes=3)

# Compute degree
degrees = netsmith.degree(edges, backend="auto")
print(degrees)  # [2, 2, 2]

# Compute PageRank
pr = netsmith.pagerank(edges, alpha=0.85, backend="auto")
print(pr)

# Compute communities
communities = netsmith.communities(edges, method="louvain", backend="auto")
print(communities)
```

### Loading from Files

```python
# Load from parquet
edges = netsmith.load_edges("edges.parquet", u_col="source", v_col="target")

# Load from CSV
edges = netsmith.load_edges("edges.csv", u_col="u", v_col="v", w_col="weight")
```

### CLI Usage

```bash
# Compute degree
netsmith compute degree --input edges.parquet --out degree.parquet

# Compute PageRank
netsmith compute pagerank --input edges.parquet --out pr.parquet --alpha 0.85

# Compute communities
netsmith compute communities --input edges.parquet --out communities.parquet
```

## Installation

**Minimal installation (numpy only - ~10MB):**
```bash
pip install netsmith
```

**With optional dependencies:**
```bash
pip install netsmith[scipy]      # For sparse matrices (adjacency_matrix format='sparse'/'coo')
pip install netsmith[cli]        # For the `netsmith` command-line tool
pip install netsmith[networkx]   # Interop only: Graph.as_networkx()
pip install netsmith[pandas]     # For pandas data loading
pip install netsmith[polars]     # For polars data loading

# Or install all optional dependencies:
pip install netsmith[scipy,networkx,pandas,polars]

# Development
pip install netsmith[dev]
```

**Note:** Every algorithm works with just `numpy` — community detection, k-core, null
models, centrality and paths included. `scipy` is only needed for sparse matrix formats,
and `networkx` only for `Graph.as_networkx()` interop; no computation reaches for it.

## Rust Backend

The Rust backend will be automatically used if available. To build:

```bash
# Install Rust
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

# Build and install
maturin develop --release
```

## Status

✅ **Completed:**
- Core layer structure (graph types, metrics, paths, community, nulls, stats)
- Engine layer structure (Python backend, dispatch system, contracts)
- API layer (load, graph, compute, validate)
- Apps layer (CLI skeleton)
- pyproject.toml configuration

🚧 **In Progress:**
- Rust backend implementation (degree, clustering, paths, components, Louvain done)
- Full metric implementations
- Test suite

📋 **Planned:**
- Rust acceleration for Phase 1 kernels (degree, strength, components, BFS, k-core)
- Comprehensive test coverage
- Documentation
- Performance benchmarks

## Design Philosophy

NetSmith focuses on pure network analysis. For time series to network conversion, use downstream libraries that build on NetSmith.

## License

MIT


