ProvenPin Install

NetworkX DiGraph shortest paths, topological sort and cycle detection: working versions (tested 2026-10-15)

Build a directed dependency graph, topologically order it, detect cycles with find_cycle, and pick shortest routes while keeping weighted Dijkstra vs hop-count BFS straight.

passed6 passed · 0 failed2026-10-15 16:02 UTC
Status
passed
Last passed
2026-10-15 16:02 UTC
Tests
6 / 6
Language
Python
Runtime
Python 3.13.16
pinned versions2
networkx@3.6.1pytest@9.1.1
run it
uv venv -q .venv && uv pip install -q --python .venv/bin/python -r requirements.txt
.venv/bin/python -m pytest -q
test environment
Python 3.13.16
linux 6.17.0-1022-azure
x64
runner: github-actions 38764699834

The code

Exactly the files that passed. Your agent can pull them with get_recipe("networkx-shortest-path-dag") (install), or see them on GitHub.

requirements.txt
networkx==3.6.1
pytest==9.1.1
graph.py
import networkx as nx


def build_dag(edges):
    """edges: iterable of (src, dst, weight)."""
    g = nx.DiGraph()
    g.add_weighted_edges_from(edges)
    return g


def build_order(g):
    # topological_sort silently returns garbage order on a cycle, so guard first
    if not nx.is_directed_acyclic_graph(g):
        raise ValueError(f"dependency cycle: {nx.find_cycle(g)}")
    return list(nx.topological_sort(g))


def detect_cycle(g):
    # find_cycle raises NetworkXNoCycle when the graph is a DAG
    try:
        return nx.find_cycle(g)
    except nx.NetworkXNoCycle:
        return None


def fastest_route(g, source, target):
    # without weight= this is hop-count BFS, not Dijkstra
    return nx.shortest_path(g, source, target, weight="weight")
tests/test_graph.py
import networkx as nx
import pytest

from graph import build_dag, build_order, detect_cycle, fastest_route


def test_build_order_respects_dependencies():
    g = build_dag([("a", "b", 1), ("b", "c", 1), ("a", "c", 1)])
    assert build_order(g) == ["a", "b", "c"]


def test_cycle_raises_before_returning_order():
    g = build_dag([("a", "b", 1), ("b", "c", 1), ("c", "a", 1)])
    with pytest.raises(ValueError, match="dependency cycle"):
        build_order(g)


def test_detect_cycle_wraps_no_cycle_exception():
    cyclic = build_dag([("a", "b", 1), ("b", "c", 1), ("c", "a", 1)])
    assert detect_cycle(cyclic) is not None
    assert detect_cycle(build_dag([("a", "b", 1)])) is None


def test_self_loop_counts_as_cycle():
    g = build_dag([("a", "a", 1)])
    assert not nx.is_directed_acyclic_graph(g)
    assert detect_cycle(g) == [("a", "a")]


def test_shortest_path_ignores_weight_unless_asked():
    g = build_dag([("a", "d", 100), ("a", "b", 1), ("b", "d", 1)])
    assert nx.shortest_path(g, "a", "d") == ["a", "d"]
    assert nx.shortest_path(g, "a", "d", weight="weight") == ["a", "b", "d"]


def test_unreachable_target_raises_no_path():
    g = build_dag([("a", "b", 1), ("c", "d", 1)])
    with pytest.raises(nx.NetworkXNoPath):
        fastest_route(g, "a", "d")
pytest.ini
[pytest]
pythonpath = .

Connect to ProvenPin

Add the free MCP server so your agent can pull this recipe and others like it. Same setup as the docs.

terminal
claude mcp add --transport http provenpin https://mcp.provenpin.com/mcp

Any other MCP client: Streamable HTTP at https://mcp.provenpin.com/mcp. No API key, no signup.