Skip to content

Commit

Permalink
feat: add renderer for cidoc
Browse files Browse the repository at this point in the history
resolves #326
  • Loading branch information
sennierer committed Nov 20, 2024
1 parent 8e1519d commit 7717061
Show file tree
Hide file tree
Showing 3 changed files with 129 additions and 0 deletions.
53 changes: 53 additions & 0 deletions apis_ontology/renderer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
from rest_framework import renderers
from rdflib import Graph


class BaseRdfRenderer(renderers.BaseRenderer):
def render(self, data, accepted_media_type=None, renderer_context=None):
result = Graph()

if isinstance(data, dict) and "results" in data:
# Handle case where data is a dict with multiple graphs
for graph in data["results"]:
if isinstance(graph, Graph):
# Merge triples
for triple in graph:
result.add(triple)
# Merge namespace bindings
for prefix, namespace in graph.namespaces():
result.bind(prefix, namespace, override=False)
elif isinstance(data, Graph):
# Handle case where data is a single graph
result = data
# Ensure namespaces are properly bound in the single graph case
for prefix, namespace in data.namespaces():
result.bind(prefix, namespace, override=False)
else:
raise ValueError(
"Invalid data format. Expected rdflib Graph or dict with 'results' key containing graphs"
)
return result


class CidocTTLRenderer(BaseRdfRenderer):
format = "Cidoc"
media_type = "text/ttl"

def render(self, data, accepted_media_type=None, renderer_context=None):
return (
super()
.render(data, accepted_media_type, renderer_context)
.serialize(format="ttl")
)


class CidocXMLRenderer(BaseRdfRenderer):
format = "Cidoc"
media_type = "application/rdf+xml"

def render(self, data, accepted_media_type=None, renderer_context=None):
return (
super()
.render(data, accepted_media_type, renderer_context)
.serialize(format="xml")
)
70 changes: 70 additions & 0 deletions apis_ontology/serializers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
from rest_framework.renderers import serializers
from rdflib import Graph, Literal, URIRef, Namespace
from rdflib.namespace import RDF, RDFS, XSD


class PersonCidocSerializer(serializers.BaseSerializer):
def to_representation(self, instance):
g = Graph()

# Define namespaces
crm = Namespace("http://www.cidoc-crm.org/cidoc-crm/")
apis = Namespace("http://apis.acdh.oeaw.ac.at/")

g.namespace_manager.bind("crm", crm, replace=True)
g.namespace_manager.bind("apis", apis, replace=True)

# Create the Person instance
person_uri = URIRef(apis[str(instance.id)])
g.add((person_uri, RDF.type, crm.E21_Person))

# Add properties
appellation_uri = URIRef(apis[f"appellation_{instance.id}"])
g.add((appellation_uri, RDF.type, crm.E41_Appellation))
g.add((person_uri, crm.P1_is_identified_by, appellation_uri))
g.add(
(
appellation_uri,
RDFS.label,
Literal(f"{instance.forename} {instance.surname}"),
)
)

if hasattr(instance, "forename"):
forename_uri = URIRef(apis[f"forename_{instance.id}"])
g.add((forename_uri, RDF.type, crm.E41_Appellation))
g.add((appellation_uri, crm.P106_is_composed_of, forename_uri))
g.add((forename_uri, RDFS.label, Literal(instance.forename)))

if hasattr(instance, "surname"):
surname_uri = URIRef(apis[f"surname_{instance.id}"])
g.add((surname_uri, RDF.type, crm.E41_Appellation))
g.add((appellation_uri, crm.P106_is_composed_of, surname_uri))
g.add((surname_uri, RDFS.label, Literal(instance.surname)))

if hasattr(instance, "birth_date"):
birth_event = URIRef(apis[f"birth_{instance.id}"])
g.add((birth_event, RDF.type, crm.E67_Birth))
g.add((birth_event, crm.P98_brought_into_life, person_uri))
g.add(
(
birth_event,
crm.P4_has_time_span,
Literal(instance.birth_date, datatype=XSD.date),
)
)

if hasattr(instance, "death_date"):
death_event = URIRef(apis[f"death_{instance.id}"])
g.add((death_event, RDF.type, crm.E69_Death))
g.add((death_event, crm.P100_was_death_of, person_uri))
g.add(
(
death_event,
crm.P4_has_time_span,
Literal(instance.death_date, datatype=XSD.date),
)
)

# Serialize the graph to RDF/XML
return g
6 changes: 6 additions & 0 deletions apis_ontology/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,12 @@
"simple_history.middleware.HistoryRequestMiddleware",
]

REST_FRAMEWORK["DEFAULT_RENDERER_CLASSES"] = [ # noqa: F405
"rest_framework.renderers.JSONRenderer",
"rest_framework.renderers.BrowsableAPIRenderer",
"apis_ontology.renderer.CidocTTLRenderer",
"apis_ontology.renderer.CidocXMLRenderer",
]
# this is a workaround to disable pagintation in the relations
# listing on the entities pages
APIS_ENTITIES = {
Expand Down

0 comments on commit 7717061

Please sign in to comment.