Graph theoretic classes and algorithm helper functions.
Project description
Graphworks
A Python module for efficient graph theoretic programming
Quick Start
pip install graphworks
import json
from graphworks.graph import Graph
json_graph = {"label": "my graph", "edges": {"A": ["B"], "B": []}}
graph = Graph("my graph", input_graph=json.dumps(json_graph))
print(graph)
Optional extras:
pip install graphworks[matrix] # numpy adjacency matrix support
pip install graphworks[viz] # graphviz export
pip install graphworks[docs] # generate documentation
Development
Requirements
- Python 3.13+
- uv (>= 0.10.12)
Setup
uv sync --extra all
Running Tests
# Run all tests (includes coverage; fails under 90%)
uv run pytest
# Run a single test file
uv run pytest tests/test_graph.py
# Run a single test by name
uv run pytest tests/test_graph.py -k "test_method_name"
Linting and Formatting
# Lint
uv run ruff check --fix src/ tests/
# Format
uv run black src/ tests/
uv run isort src/ tests/
# Type checking
uv run ty check
# Code complexity
uv run xenon --max-average=A --max-modules=B --max-absolute=B src/
# Run all pre-commit hooks
pre-commit run --all-files
Publishing
Version is managed automatically via git tags using hatchling-vcs.
- Tag a commit:
git tag -a vX.Y.Z -m 'release message' - Push the tag:
git push --tags - The GitHub Actions workflow will build and publish to PyPI automatically.
TODO
Tier 1: Data model (do first, everything depends on it) The biggest gap right now is that vertices
are bare strings and edges are lightweight dataclasses that the Graph class barely uses internally.
The adjacency list stores defaultdict[str, list[str]] — just names pointing to names. This means
vertex attributes, edge weights, and edge labels all live outside the canonical representation. Your
g4.json weighted format already hints at the tension: it uses dicts-as-neighbors instead of
strings, but the Graph class doesn't actually parse them. A Vertex class (with a name, optional
label, and an attribute dict) and a richer Edge (already a dataclass, but needs to be the actual
unit of storage rather than reconstructed on every .edges() call) would give you a foundation where
all the metadata survives every operation.
Tier 2: Graph refactor Once Vertex and Edge exist as first-class objects, the internal
defaultdict[str, list[str]] can become something like dict[str, Vertex] for vertex lookup and an
edge storage structure that preserves weights and attributes. The critical constraint from your
philosophy: conversions to adjacency matrix and back must be lossless — this is exactly the
get_complement bug you just hit. A vertex-name-to-index mapping maintained alongside the matrix
would solve it.
Tier 3: Lossless conversions With named vertices and attributed edges, you can build clean
to_adjacency_matrix() / from_adjacency_matrix() round-trips that carry a name mapping,
to_edge_list() / from_edge_list(), and fix get_complement to work through the matrix without
losing names.
Tier 4: Algorithms With weighted edges actually in the data model, Dijkstra and Prim become natural. Strongly connected components, better shortest-path implementations, and the directed graph algorithms from your TODO list can all build on the refactored core.
Tier 5: Export/CLI The Rich rendering and CLI app build on top of everything above. The export layer (JSON, DOT, Rich) becomes a clean translation from your canonical format rather than ad-hoc string building.
Tier 6: Cross-cutting quality Thread safety (immutable graph views, or threading.Lock around mutations), input validation, and benchmarks can happen in parallel with other tiers. Where would you like to start? The Vertex class and Edge redesign are the natural first move — they're self-contained, testable, and unblock everything downstream.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file graphworks-0.6.1.tar.gz.
File metadata
- Download URL: graphworks-0.6.1.tar.gz
- Upload date:
- Size: 20.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c3f666093e8be7d41d30bc4a6a3c0d5b89323f83e24fbae44c3bab69c2952aaf
|
|
| MD5 |
b4acf22dbbede89f8a5db4dcdc9904ee
|
|
| BLAKE2b-256 |
aa0a990ea9ed3d8809f62f35d2a86cd306eaec55d05388b3ed611205eefc5b60
|
Provenance
The following attestation bundles were made for graphworks-0.6.1.tar.gz:
Publisher:
publish-to-pypi.yml on nathan-gilbert/graphworks
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
graphworks-0.6.1.tar.gz -
Subject digest:
c3f666093e8be7d41d30bc4a6a3c0d5b89323f83e24fbae44c3bab69c2952aaf - Sigstore transparency entry: 1184119770
- Sigstore integration time:
-
Permalink:
nathan-gilbert/graphworks@c9260f49cffab831b55a7aadc091afdbf4feb0e0 -
Branch / Tag:
refs/tags/0.6.1 - Owner: https://github.com/nathan-gilbert
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-to-pypi.yml@c9260f49cffab831b55a7aadc091afdbf4feb0e0 -
Trigger Event:
push
-
Statement type:
File details
Details for the file graphworks-0.6.1-py3-none-any.whl.
File metadata
- Download URL: graphworks-0.6.1-py3-none-any.whl
- Upload date:
- Size: 26.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
904fa7d696121d9e67f9a5343e0507de96cdddd40eb06e13440afd3b4828d324
|
|
| MD5 |
0c11a3e63f19cf18105700469ae6d1bb
|
|
| BLAKE2b-256 |
3c278bd418c0875b4b39c8f55d6b108bae7321ce366fd812b14b6d470f4658c3
|
Provenance
The following attestation bundles were made for graphworks-0.6.1-py3-none-any.whl:
Publisher:
publish-to-pypi.yml on nathan-gilbert/graphworks
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
graphworks-0.6.1-py3-none-any.whl -
Subject digest:
904fa7d696121d9e67f9a5343e0507de96cdddd40eb06e13440afd3b4828d324 - Sigstore transparency entry: 1184119802
- Sigstore integration time:
-
Permalink:
nathan-gilbert/graphworks@c9260f49cffab831b55a7aadc091afdbf4feb0e0 -
Branch / Tag:
refs/tags/0.6.1 - Owner: https://github.com/nathan-gilbert
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-to-pypi.yml@c9260f49cffab831b55a7aadc091afdbf4feb0e0 -
Trigger Event:
push
-
Statement type: