Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove SPARQLWrapper dependency #744

Merged
merged 6 commits into from
Oct 27, 2018
Merged

Remove SPARQLWrapper dependency #744

merged 6 commits into from
Oct 27, 2018

Conversation

gromgull
Copy link
Member

Replace it with "SPARQLWrapper-Lite", which is based on the requests library.

This gains us lots of nice modern HTTP library features, such as keepalive, connection pooling, and by exposing the kwargs to be sent to requests, we can do http basic auth etc. easily.

SPARQLWrapper also has lots of legacy code from supporting various old RDF stores from the days before the SPARQL Protocol was a thing. The new code only supports SPARQL 1.1 Protocol standard, and can therefore be much shorter!

This is not quite done - PR for testing + feedback! (but I run this in production, so it's also not completely pre-beta :) )

@gromgull gromgull added cleanup store Related to a store. labels May 18, 2017
@gromgull
Copy link
Member Author

gromgull commented Nov 3, 2017

I have used this in production since May - it's pretty good. Lets merge? @joernhees ?

@joernhees
Copy link
Member

sure, but shouldn't this just go upstream and replace the SPARQLWrapper default? i somehow fear that we're creating yet another WTF for the future ;) especially with colliding names won't we confuse everyone and in future talk about SPARQLWrapper's SPARQLWrapper and RDFLib's SPARQLWrapper ?

@gromgull
Copy link
Member Author

gromgull commented Nov 3, 2017

No - it's only 120 lines of code, and it removes the SPARQLWrapper dependency all together. But it doesn't try to replace everything SPARQLWrapper does - people also use that for getting stuff out of a SPARQL endpoint, without wrapping it as a RDFLib store. This code does nothing for them.

@scossu
Copy link

scossu commented Jan 3, 2018

@gromgull @joernhees Any decision on merging this PR?
Also, since it is based on requests, does this allow for connection pooling without depending on the keepalive package?

@gromgull
Copy link
Member Author

gromgull commented Jan 3, 2018

I use it in production - so I am happy to have it merged :)

And yes, it should support connection pool without keepalive.

@scossu
Copy link

scossu commented Jan 13, 2018

@gromgull I merged this on a separate repo for testing but I get an error:

>>> from rdflib.plugins.stores.sparqlstore import SPARQLUpdateStore
RDFLib Version: 5.0.0-dev
>>> from rdflib.term import URIRef
>>> store = SPARQLUpdateStore(queryEndpoint='http://localhost:3030/lsup-dev/query', update_endpoint='http://localhost:3030/lsup-dev/update')
>>> fds = Dataset(store)
>>> fgr = fds.graph(URIRef('urn:bogus:1'))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/scossu/code/lakesuperior/virtualenv/lib/python3.5/site-packages/rdflib/graph.py", line 1623, in graph
    self.store.add_graph(g)
  File "/home/scossu/code/lakesuperior/virtualenv/lib/python3.5/site-packages/rdflib/plugins/stores/sparqlstore.py", line 721, in add_graph
    "CREATE GRAPH %s" % self.node_to_sparql(graph.identifier))
  File "/home/scossu/code/lakesuperior/virtualenv/lib/python3.5/site-packages/rdflib/plugins/stores/sparqlstore.py", line 638, in update
    self.setNamespaceBindings(initNs)
AttributeError: 'SPARQLUpdateStore' object has no attribute 'setNamespaceBindings'

Did the API change?

gromgull added 5 commits May 15, 2018 10:52
and a single parser for graph-based results
Replace with a very thin wrapper for modern RDF stores speaking
SPARQL 1.1 protocol. This is based on `requests`.
all passing any kwargs to requests
@gromgull
Copy link
Member Author

@scossu yes - that method is gone. I wonder why the tests didn't catch that the first time around. Will fix!

Copy link
Member

@joernhees joernhees left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

main concern still is the name that will lead to confusion... left some inline comments.

@@ -6,9 +6,9 @@

kwargs = {}
kwargs['install_requires'] = [ 'six', 'isodate', 'pyparsing']
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

requests is a new dependency, no?

@@ -65,18 +58,11 @@ def __init__(self, source):
elif results is not None:
type_ = 'SELECT'
else:
g = Graph()
try:
g.parse(data=xmlstring)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what happens to CONSTRUCT queries now?

raise Exception(
"SPARQLWrapper not found! SPARQL Store will not work." +
"Install with 'pip install SPARQLWrapper'")
from .sparqlwrapper import SPARQLWrapper
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we somehow avoid using SPARQLWrapper as a name (any caps)? Maybe SPARQLConnector? Or not expose it in its own module and internalize it here as _SPARQLWrapper?

I really would like to avoid the confusion

@@ -195,10 +195,11 @@ def _set_bindings(self, b):
_get_bindings, _set_bindings, doc="a list of variable bindings as dicts")

@staticmethod
def parse(source, format='xml', **kwargs):
def parse(source=None, format=None, content_type=None, **kwargs):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm, what happens if source is None?

i'd somehow find the following slightly clearer (if it's what is intended)

def parse(source, format='xml', content_type=None, **kwargs):
    parser = plugin.get(content_type or format, ResultParser()
    return parser.parse(source, content_type=content_type, **kwargs)

@joernhees joernhees added this to the rdflib 5.0.0 milestone May 15, 2018
@joernhees
Copy link
Member

re #391

@wikier
Copy link
Member

wikier commented Oct 20, 2018

In addition, if you consider the underline implementation could be useful standalone, happy to make it part of SPARQLWrapper 2.x ;-)

@jpmccu
Copy link
Contributor

jpmccu commented Oct 30, 2018

This broke our ability to configure POST requests against SPARQL endpoints, and it looks like the setReturnFormat() function went missing. How should I address switching over?

@gromgull
Copy link
Member Author

gromgull commented Nov 1, 2018

@jimmccusker this builds on the requests and you can configure requests as much as requests lets you, any additional kwargs you pass to the store constructor will be passed to requests, i.e. for basic auth:

import rdflib
from rdflib.plugins.stores.sparqlstore import SPARQLStore

store = SPARQLStore('http://localhost:8000', auth=('user', 'pass'))
g = rdflib.Graph(store)
list(g[rdflib.RDFS.Class])

Return format is also set for the constructor - i.e. pass returnFormat

I will update the doc strings in #872 to make this clear!

gromgull added a commit to RDFLib/sparqlwrapper that referenced this pull request Nov 1, 2018
This was removed in 5.0.0 (see
RDFLib/rdflib#744), but it may be useful for
people wanting backwards compatebility, or who relied on particular
SPARQLWrapper features.

In retrospect, this code should always have been in the SPARQLWrapper
project, avoiding the awkward circular rdflib <-> SPARQLWrapper
dependency :)

Now you can install rdflib + sparqlwrapper and do:

```py

>>> import rdflib
>>> g = rdflib.Graph('SPARQLWrapper', identifier='http://dbpedia.org')
>>> g.open('http://dbpedia.org/sparql')
>>> g.value(rdflib.URIRef('http://dbpedia.org/resource/Berlin'), rdflib.RDFS.label)
rdflib.term.Literal(u'Berlin', lang='en')

```
@gromgull
Copy link
Member Author

gromgull commented Nov 1, 2018

@jimmccusker For max backward-compatibility, hopefully this will be merged and you can use your original code: RDFLib/sparqlwrapper#126

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cleanup SPARQL store Related to a store.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants