In [1]:
%matplotlib inline
In [2]:
from rdflib import (
Graph,
Namespace,
URIRef,
Literal,
BNode,
)
from rdflib.namespace import RDF
Property Graph Classes #######################################################################
In [3]:
class Node:
def __init__(self, id):
self.id = id
self.labels = set()
self.properties = {}
class Edge:
def __init__(self, source, label, target):
self.source = source
self.label = label
self.target = target
self.properties = {}
class PropertyGraph:
def __init__(self):
self.nodes = {}
self.edges = []
def get_node(self, id):
if id not in self.nodes:
self.nodes[id] = Node(id)
return self.nodes[id]
def add_edge(self, source, label, target):
edge = Edge(source, label, target)
self.edges.append(edge)
return edge
Property Graph -> RDF Translator #######################################################################
In [4]:
class PropertyGraphToRDF:
def __init__(self):
self.graph = Graph()
self.EX = Namespace("http://example.org/")
self.graph.bind("ex", self.EX)
self.graph.bind("rdf", RDF)
####################################################################
# Utility Functions
####################################################################
def uri(self, name):
"""Return a URI for a graph object."""
return self.EX[name]
def literal(self, value):
"""Convert a Python value into an RDF literal."""
return Literal(value)
####################################################################
# Translation
####################################################################
def translate(self, property_graph):
self.graph = Graph()
self.graph.bind("ex", self.EX)
self.graph.bind("rdf", RDF)
#
# Translate nodes
#
for node in property_graph.nodes.values():
self.translate_node(node)
#
# Translate edges
#
for edge in property_graph.edges:
self.translate_edge(edge)
return self.graph
####################################################################
# Translate one node
####################################################################
def translate_node(self, node):
subject = self.uri(node.id)
#
# Labels become rdf:type assertions
#
for label in node.labels:
self.graph.add(
(
subject,
RDF.type,
self.uri(label),
)
)
#
# Properties become RDF triples
#
for key, value in node.properties.items():
self.graph.add(
(
subject,
self.uri(key),
self.literal(value),
)
)
####################################################################
# Translate one edge
####################################################################
def translate_edge(self, edge):
subject = self.uri(edge.source)
predicate = self.uri(edge.label)
object = self.uri(edge.target)
#
# Simple relationship
#
if len(edge.properties) == 0:
self.graph.add(
(
subject,
predicate,
object,
)
)
return
#
# Relationship with properties
# Use RDF reification.
#
statement = BNode()
self.graph.add((statement, RDF.type, RDF.Statement))
self.graph.add((statement, RDF.subject, subject))
self.graph.add((statement, RDF.predicate, predicate))
self.graph.add((statement, RDF.object, object))
for key, value in edge.properties.items():
self.graph.add(
(
statement,
self.uri(key),
self.literal(value),
)
)
####################################################################
# Output
####################################################################
def serialize(self, format="turtle"):
return self.graph.serialize(format=format)
Example #######################################################################
In [5]:
pg = PropertyGraph()
#
# Nodes
#
art = pg.get_node("art")
art.labels.add("Person")
art.properties["name"] = "Art"
bea = pg.get_node("bea")
bea.labels.add("Person")
bea.properties["age"] = 23
#
# Relationship
#
edge = pg.add_edge("art", "knows", "bea")
edge.properties["since"] = 2010
#
# Translate
#
translator = PropertyGraphToRDF()
rdf_graph = translator.translate(pg)
print(translator.serialize())
@prefix ex: <http://example.org/> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
ex:art a ex:Person ;
ex:name "Art" .
ex:bea a ex:Person ;
ex:age 23 .
[] a rdf:Statement ;
ex:since 2010 ;
rdf:object ex:bea ;
rdf:predicate ex:knows ;
rdf:subject ex:art .