RDFLib / sparqlwrapper

A wrapper for a remote SPARQL endpoint
https://sparqlwrapper.readthedocs.io/
Other
520 stars 122 forks source link

Change return format adds extra request parameters #164

Closed renyuneyun closed 3 years ago

renyuneyun commented 3 years ago

I'm using SPARQLWrapper to o my queries and some of them are CONSTRUCT queries. For some reasons, I need to change the return format to anything other than XML (RDF/XML).

When doing the query, my SPARQL endpoint yields errors to me, saying Error 400: Can't determine output content type: turtle. A minimal query code is:

import SPARQLWrapper

sparql = SPARQLWrapper.SPARQLWrapper('http://localhost:3030/prov')
#query = '' # The CONSTRUCT query here
sparql.setQuery(query)
sparql.setReturnFormat(SPARQLWrapper.TURTLE)
return sparql.query().convert()

The error message is raised for any return format other than SPARQLWrapper.XML, including SPARQLWrapper.RDFXML, with only the exact type changed.

When debugging, I found three extra request parameters are sent to fuseki (my SPARQL endpoint):

&format=turtle&output=turtle&results=turtle

If I send the request without these three parameters (e.g. through cURL), it returns valid responses. Therefore, I'm looking for a way to tell SPARQLWrapper not to send them.

However, I don't find any method to do this. The document points to addParameter and clearParemeter, but they don't work for these three.

Should SPARQLWrapper not add these three in the first place? Or is there a workaround I can use?

dayures commented 3 years ago

Maybe you can use setOnlyConneg

Also, depending on the SPARQL endpoint, the way to query it differs. More information is available on the README file

dayures commented 3 years ago

Maybe this issue is related https://github.com/RDFLib/sparqlwrapper/issues/132

renyuneyun commented 3 years ago

Ah, thanks. Using setOnlyConneg solves this issue. There is a necessity to manually convert it to a rdflib.Graph, which is surprising for me in the first place, even though it is mentioned (not highlighted, in my perspective) in the document. And I belive it is indeed related to #132 .

Also thanks for mentioning again the README. This time at the very late sections I found it mentions that different SPARQL endpoints accept different ways of the (HTTP) query. Does SPARQLWrapper automatically tries to determine the SPARQL endpoint (which I believe not)? How about moving (or mentioning) that information to a more obvious place, e.g. before the example queries?

By the way, maybe I misinterpret, but the information for fuseki may be outdated?

renyuneyun commented 3 years ago

Oh, and when I first saw the problem I wasn't sure of it cause, so I asked it first on stackoverflow. A guy (AndyS) gave some comments, and he/she seems come from the fuseki part. He mentioned [1] [2] fuseki prefers to use the HTTP Header, instead of the query parameters. Maybe this is worth considering (e.g. changing the default behaviour)? (Though, I'm not sure about the behaviours of other SPARQL endpoint servers.)

dayures commented 3 years ago

Right now, SPARQLWrapper cannot determine the "system" of SPARQL endpoint that it is going to query. Actually, this could be a side project (giving a URL of a potential SPARQL endpoint, return the system behind).

Maybe this information is easier to read in the documentation, where there is a section about it.

About using Content Negotiation (conneg) as the default behaviour, there are some considerations:

renyuneyun commented 3 years ago

Thanks for the information! Some of them are indeed worth reading for me.

Another thought: instead of changing the default behaviour, how about adding two parameters to the query (and queryAndConvert) function like this:

def query(use_query_parameter=True, use_http_header=True)

At lease this is the first place I was looking for in the document. Or, maybe mentioning the setOnlyConneg() method in the docstring of query(), addParameter() or clearParameter() would be useful?

Anyway, thanks for the help again. I'm closing this issue since it's solved -- workaround available by using setOnlyConneg().