[restapi] Support content negotiation for SPARQL results

authorLaurent Wouters <lwouters@cenotelie.fr>
changeset55a1fdbd8fba
branchdefault
phasedraft
hiddenno
parent revision#35b4499566ca [restapi] Use graph attached to Repository
child revision<not specified>
files modified by this revision
cubicweb/pyramid/rest_api.py
cubicweb/rdf.py
# HG changeset patch
# User Laurent Wouters <lwouters@cenotelie.fr>
# Date 1592577418 -7200
# Fri Jun 19 16:36:58 2020 +0200
# Node ID 55a1fdbd8fba52049f592b28a8c14c24aa49a688
# Parent 35b4499566cafaee7ba362e3a1208b5c74ef08a6
[restapi] Support content negotiation for SPARQL results

diff --git a/cubicweb/pyramid/rest_api.py b/cubicweb/pyramid/rest_api.py
@@ -24,14 +24,15 @@
1 
2  from pyramid.view import view_config
3  from pyramid.response import Response
4 
5  from cubicweb import rdf
6 -from cubicweb.pyramid.resources import rdf_context_from_eid, RDFResource
7 +from cubicweb.pyramid.resources import rdf_context_from_eid, RDFResource, negociate_mime_type
8  from rdflib import URIRef, Literal, ConjunctiveGraph, plugin
9  from rdflib.store import Store
10 
11 +from cubicweb.rdf import SPARQL_MIMETYPE_TO_FORMAT
12 
13 
14  @view_config(
15      route_name='one_entity',
16      context=RDFResource,
@@ -52,12 +53,28 @@
17  @view_config(
18      route_name='sparql'
19  )
20  def sparql_query_view(request):
21      query = request.params['query']
22 +    format = request.params.get('format', None)
23 +    _default_graph_uri = request.params.get('default-graph-uri', None)
24 +    _named_graph_uri = request.params.get('named-graph-uri', None)
25 +
26 +    if format is not None:
27 +        if format in SPARQL_MIMETYPE_TO_FORMAT:
28 +            mime_type = format
29 +        else:
30 +            mime_type = "application/sparql-results+json"
31 +    else:
32 +        mime_type = negociate_mime_type(
33 +            request, SPARQL_MIMETYPE_TO_FORMAT.keys()
34 +        ) or "application/sparql-results+json"
35      result = request.cw_cnx.repo.graph.query(query)
36 -    return Response(result.serialize(format='json'), content_type='application/json')
37 +    return Response(
38 +        result.serialize(
39 +            format=SPARQL_MIMETYPE_TO_FORMAT[mime_type]
40 +        ), content_type=mime_type)
41 
42 
43  def includeme(config):
44      config.include('.predicates')
45      config.add_route(
diff --git a/cubicweb/rdf.py b/cubicweb/rdf.py
@@ -28,10 +28,16 @@
46      'application/n-triples': 'nt',
47      'application/trig': 'trig',
48      'application/ld+json': 'json-ld',
49  }
50 
51 +SPARQL_MIMETYPE_TO_FORMAT = {
52 +    'application/sparql-results+json': 'json',
53 +    'application/sparql-results+xml': 'xml',
54 +    'text/csv': 'csv'
55 +}
56 +
57  NAMESPACES = {
58      "rdf": namespace.RDF,
59      "rdfs": namespace.RDFS,
60      "owl": namespace.OWL,
61      "xsd": namespace.XSD,