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)