Convert to/from a NetworkX graph

prov.graph converts a document to and from a NetworkX MultiDiGraph, useful for running graph algorithms (centrality, shortest paths, community detection, …) that prov itself does not implement. networkx is a core dependency — no extra install needed.

Document to graph

prov_to_graph() returns one node per element (entity/activity/agent) and one edge per relation. It unifies the document first, so records describing the same identifier are merged into a single node:

import prov.model as pm
from prov.graph import prov_to_graph

document = pm.ProvDocument()
document.set_default_namespace("http://example.org/")
e = document.entity("e1")
a = document.activity("a1")
document.wasGeneratedBy(e, a)

g = prov_to_graph(document)

print(list(g.nodes()))
# [<ProvEntity: e1>, <ProvActivity: a1>]
print(list(g.edges(data=True)))
# [(<ProvEntity: e1>, <ProvActivity: a1>, {'relation': <ProvGeneration: (e1, a1)>})]

Each node is the prov element record (a ProvElement); each edge carries the originating ProvRelation under the "relation" key so you don’t lose PROV-specific information (relation type, extra attributes) while using NetworkX.

Run a NetworkX algorithm

Because nodes are hashable prov objects, any NetworkX algorithm works directly:

import networkx as nx

print(nx.is_directed_acyclic_graph(g))

Graph back to document

graph_to_prov() reverses the conversion for a graph previously produced by prov_to_graph (or built to match its shape — nodes are ProvRecord instances with a bundle, edges carry a "relation" record in their data):

from prov.graph import graph_to_prov

reloaded = graph_to_prov(g)
assert reloaded == document

Round trip

g = prov_to_graph(document)
reloaded = graph_to_prov(g)
assert reloaded == document