Views
SPARQLQueryAPIView
Bases: APIView
Parent class for a SPARQL query request.
Source code in sparql/views.py
class SPARQLQueryAPIView(APIView):
'''
Parent class for a SPARQL query request.
'''
renderer_classes = SPARQLContentNegotiator.rdf_renderers + \
SPARQLContentNegotiator.results_renderers
content_negotiation_class = SPARQLContentNegotiator
def get_exception_handler(self):
''' Errors are returned as turtle, even when the original querytype
does not satisfy could not be rendered in this format. A hard
overwrite of renderer is necessary. Ideally, this should render errors
in a querytype-compatibleway. '''
self.request.accepted_renderer = TurtleRenderer()
self.request.accepted_media_type = TurtleRenderer.media_type
return turtle_exception_handler
def execute_query(self, querystring):
""" Attempt to query a graph with a SPARQL-Query string
Sets query type on succes
"""
graph = self.graph()
try:
if not querystring:
query_results = graph
query_type = "EMPTY"
else:
# See SPARQLUpdateAPIView.execute_update
query_results = graph.query(querystring)
query_type = query_results.type
self.request.data["query_type"] = query_type
# re-perform content negotiation to determine if
# querytype satisfies accept header
neg = self.perform_content_negotiation(self.request)
self.request.accepted_renderer, self.request.accepted_media_type = neg
return query_results
except (ParseException, ValueError) as p_e:
# Raised when SPARQL syntax is not valid, or parsing fails
graph.rollback()
raise ParseSPARQLError(p_e)
except HTTPError as h_e:
graph.rollback()
if 400 <= h_e.response.status_code < 500:
raise ParseSPARQLError(h_e)
else:
raise APIException(h_e)
except urllibHTTPError as u_h_e:
graph.rollback()
if 400 <= u_h_e.code < 500:
raise ParseSPARQLError(u_h_e)
else:
raise APIException(u_h_e)
except NotAcceptable:
graph.rollback()
raise
except Exception as n_e:
graph.rollback()
raise APIException(n_e)
def get(self, request, **kwargs):
""" Accepts GET request, optional SPARQL-Query
in query parameter 'query'.
Without 'query' parameter, returns the entire graph as text/turtle.
Renders application/json or text/turtle based
on query type and header 'Accept.
"""
sparql_string = request.query_params.get("query")
if request.data:
raise ParseSPARQLError(
"GET request should provide query in parameter, not request body.")
query_results = self.execute_query(sparql_string)
return Response(query_results)
def post(self, request, **kwargs):
""" Accepts POST request with SPARQL-Query in body parameter 'query'.
Renders application/json or text/turtle based
on query type and header 'Accept'.
"""
sparql_string = request.data.get("query")
if not sparql_string:
raise NoParamError()
# request.data is immutable for POST requests
request.data._mutable = True
query_results = self.execute_query(sparql_string)
return Response(query_results)
def graph(self):
raise NotImplementedError
execute_query(querystring)
Attempt to query a graph with a SPARQL-Query string Sets query type on succes
Source code in sparql/views.py
def execute_query(self, querystring):
""" Attempt to query a graph with a SPARQL-Query string
Sets query type on succes
"""
graph = self.graph()
try:
if not querystring:
query_results = graph
query_type = "EMPTY"
else:
# See SPARQLUpdateAPIView.execute_update
query_results = graph.query(querystring)
query_type = query_results.type
self.request.data["query_type"] = query_type
# re-perform content negotiation to determine if
# querytype satisfies accept header
neg = self.perform_content_negotiation(self.request)
self.request.accepted_renderer, self.request.accepted_media_type = neg
return query_results
except (ParseException, ValueError) as p_e:
# Raised when SPARQL syntax is not valid, or parsing fails
graph.rollback()
raise ParseSPARQLError(p_e)
except HTTPError as h_e:
graph.rollback()
if 400 <= h_e.response.status_code < 500:
raise ParseSPARQLError(h_e)
else:
raise APIException(h_e)
except urllibHTTPError as u_h_e:
graph.rollback()
if 400 <= u_h_e.code < 500:
raise ParseSPARQLError(u_h_e)
else:
raise APIException(u_h_e)
except NotAcceptable:
graph.rollback()
raise
except Exception as n_e:
graph.rollback()
raise APIException(n_e)
get(request, **kwargs)
Accepts GET request, optional SPARQL-Query in query parameter 'query'. Without 'query' parameter, returns the entire graph as text/turtle. Renders application/json or text/turtle based on query type and header 'Accept.
Source code in sparql/views.py
def get(self, request, **kwargs):
""" Accepts GET request, optional SPARQL-Query
in query parameter 'query'.
Without 'query' parameter, returns the entire graph as text/turtle.
Renders application/json or text/turtle based
on query type and header 'Accept.
"""
sparql_string = request.query_params.get("query")
if request.data:
raise ParseSPARQLError(
"GET request should provide query in parameter, not request body.")
query_results = self.execute_query(sparql_string)
return Response(query_results)
get_exception_handler()
Errors are returned as turtle, even when the original querytype does not satisfy could not be rendered in this format. A hard overwrite of renderer is necessary. Ideally, this should render errors in a querytype-compatibleway.
Source code in sparql/views.py
def get_exception_handler(self):
''' Errors are returned as turtle, even when the original querytype
does not satisfy could not be rendered in this format. A hard
overwrite of renderer is necessary. Ideally, this should render errors
in a querytype-compatibleway. '''
self.request.accepted_renderer = TurtleRenderer()
self.request.accepted_media_type = TurtleRenderer.media_type
return turtle_exception_handler
post(request, **kwargs)
Accepts POST request with SPARQL-Query in body parameter 'query'. Renders application/json or text/turtle based on query type and header 'Accept'.
Source code in sparql/views.py
def post(self, request, **kwargs):
""" Accepts POST request with SPARQL-Query in body parameter 'query'.
Renders application/json or text/turtle based
on query type and header 'Accept'.
"""
sparql_string = request.data.get("query")
if not sparql_string:
raise NoParamError()
# request.data is immutable for POST requests
request.data._mutable = True
query_results = self.execute_query(sparql_string)
return Response(query_results)
SPARQLUpdateAPIView
Bases: APIView
Parent class for an SPARL update request.
Source code in sparql/views.py
class SPARQLUpdateAPIView(APIView):
'''
Parent class for an SPARL update request.
'''
renderer_classes = (TurtleRenderer,)
def get_exception_handler(self):
return turtle_exception_handler
def check_supported(self, updatestring):
# check the entire string for unsupported keywords
if re.match(UPDATE_NOT_SUPPORTED_PATTERN, updatestring):
# do a dry-run parse of the updatestring
parse_request = parseUpdate(updatestring).request
# check if the parse contains any unsupported operations
if any(part.name in UPDATE_NOT_SUPPORTED for part in parse_request):
raise UnsupportedUpdateError(
'Update operation is not supported.'
)
# Do a quick check for blank nodes
if re.search(BLANK_NODE_PATTERN, updatestring):
parse_request = parseUpdate(updatestring).request
for part in parse_request:
if any(
isinstance(term, BNode)
for triple in part.quads.triples
for term in triple
):
raise BlankNodeError()
return
def execute_update(self, updatestring):
graph = self.graph()
try:
self.check_supported(updatestring)
graph.update(updatestring)
except (ParseException, ParseError, ValueError) as p_e:
# Raised when SPARQL syntax is not valid, or parsing fails
graph.rollback()
raise ParseSPARQLError(p_e)
except HTTPError as h_e:
graph.rollback()
if 400 <= h_e.response.status_code < 500:
raise ParseSPARQLError(h_e)
else:
raise APIException(h_e)
except urllibHTTPError as u_h_e:
graph.rollback()
if 400 <= u_h_e.code < 500:
raise ParseSPARQLError(u_h_e)
else:
raise APIException(u_h_e)
except Exception as e:
graph.rollback()
raise APIException(e)
def post(self, request, **kwargs):
""" Accepts POST request with SPARQL-Query in body parameter 'query'
Renders text/turtle
"""
sparql_string = request.data.get("update")
if not sparql_string:
# POST must contain an update
raise NoParamError()
blank = BNode()
status = 200
response = graph_from_triples(
(
(blank, RDF.type, HTTP.Response),
(blank, HTTP.statusCodeValue, Literal(status)),
(blank, HTTP.reasonPhrase, Literal("Updated successfully")),
(blank, HTTP.sc, HTTPSC.OK),
)
)
self.execute_update(sparql_string)
return Response(response)
def graph(self):
raise NotImplementedError
post(request, **kwargs)
Accepts POST request with SPARQL-Query in body parameter 'query' Renders text/turtle
Source code in sparql/views.py
def post(self, request, **kwargs):
""" Accepts POST request with SPARQL-Query in body parameter 'query'
Renders text/turtle
"""
sparql_string = request.data.get("update")
if not sparql_string:
# POST must contain an update
raise NoParamError()
blank = BNode()
status = 200
response = graph_from_triples(
(
(blank, RDF.type, HTTP.Response),
(blank, HTTP.statusCodeValue, Literal(status)),
(blank, HTTP.reasonPhrase, Literal("Updated successfully")),
(blank, HTTP.sc, HTTPSC.OK),
)
)
self.execute_update(sparql_string)
return Response(response)