If you ever had a burning desire to use SPARUL updates (aka SPARQL/1.1) on an Ubuntu machine via SPARQLWrapper you probably seen the following error message
Traceback (most recent call last): File "./wquery", line 93, in test ret = m_sparql.query() File "/usr/local/lib/python2.7/dist-packages/SPARQLWrapper/Wrapper.py", line 390, in query return QueryResult(self._query()) File "/usr/local/lib/python2.7/dist-packages/SPARQLWrapper/Wrapper.py", line 369, in _query raise e urllib2.HTTPError: HTTP Error 406: Unacceptable
it turns out that it is resolved on 1.5.3, however at the time of the writing PIP only carries SPARQLWrapper 1.5.2. to get the fresh version one must pull from SVN:
svn checkout svn://svn.code.sf.net/p/sparql-wrapper/code/trunk sparql-wrapper-code
And here is the test code to write a RDF record to the quad-store:
iquery = 'INSERT IN GRAPH <nepomuk:/sourceforge.net/users/mcradle/resources/ontologies/magic-bucket> {<http://www.example.org/subject> <http://example.org/predicate> <http://example.org/ob>}' m_sparql = SPARQLWrapper(endpoint = "http://localhost:8893/sparql/", updateEndpoint = "http://localhost:8893/sparql-auth/") m_sparql.addDefaultGraph ("nepomuk:/sourceforge.net/users/mcradle/resources/ontologies/magic-bucket") m_sparql.setCredentials(user = "user", passwd = "password") m_sparql.setQuery(iquery) m_sparql.setReturnFormat(JSON) ret = m_sparql.query()
This now ends with HTTP/1.1 Error 401:
mcradle@carver:~/workdir/remember/nepomuk/nepomuk$ ./wquery "http://www.example2.org/subject" "http://www.example2.org/predicate13" "http://www.example2.org/object" INSERT IN GRAPH <nepomuk:/sourceforge.net/users/mcradle/resources/ontologies/magic-bucket> {<http://www.example2.org/subject> <http://www.example2.org/predicate13> <http://www.example2.org/object> } send: 'GET /sparql-auth?output=xml&format=xml&results=xml&update=INSERT+IN+GRAPH+%3Cnepomuk%3A%2Fsourceforge.net%2Fusers%2Fmcradle%2Fresources%2Fontologies%2Fmagic-bucket%3E+%7B%3Chttp%3A%2F%2Fwww.example2.org%2Fsubject%3E+%3Chttp%3A%2F%2Fwww.example2.org%2Fpredicate13%3E+%3Chttp%3A%2F%2Fwww.example2.org%2Fobject%3E+%7D HTTP/1.1\r\nAccept-Encoding: identity\r\nAccept: */*\r\nHost: localhost:8891\r\nConnection: close\r\nAuthorization: Digest cmVtZW1iZXI6cmVtZW1iZXI=\n\r\nUser-Agent: sparqlwrapper 1.5.3 (http://sparql-wrapper.sourceforge.net/)\r\n\r\n' reply: 'HTTP/1.1 401 Unauthorized\r\n' header: Server: Virtuoso/06.01.3127 (Linux) i686-pc-linux-gnu header: Connection: close header: Content-Type: text/html; charset=UTF-8 header: Date: Sat, 01 Jun 2013 16:40:16 GMT header: Accept-Ranges: bytes header: Content-Length: 0 Traceback (most recent call last): File "./wquery", line 118, in <module> registerStatement2 (t_subject, t_predicate, t_object) File "./wquery", line 107, in registerStatement2 ret = m_sparql.query() File "/home/mcradle/workdir/remember/sparqlwrapper/sparql-wrapper-code/src/SPARQLWrapper/Wrapper.py", line 391, in query return QueryResult(self._query()) File "/home/mcradle/workdir/remember/sparqlwrapper/sparql-wrapper-code/src/SPARQLWrapper/Wrapper.py", line 370, in _query raise e urllib2.HTTPError: HTTP Error 401: Unauthorized
But this is because SPARQLWrapper does not support digest auth , so I monkey patched my 1.5.3 SPARQLWrapper to see if it helps:
mcradle@carver:~/workdir/remember/sparqlwrapper/sparql-wrapper-code$ diff -u /mcradle/temp/sparqlwrapper/sparql-wrapper-code/src/SPARQLWrapper/Wrapper.py ./src/SPARQLWrapper/Wrapper.py --- /tmp/sparqlwrapper/sparql-wrapper-code/src/SPARQLWrapper/Wrapper.py 2013-05-19 00:34:20.597501904 +0300 +++ ./src/SPARQLWrapper/Wrapper.py 2013-06-01 19:53:38.808090704 +0300 @@ -343,8 +344,15 @@ request.add_header("User-Agent", self.agent) request.add_header("Accept", acceptHeader) if (self.user and self.passwd): request.add_header("Authorization", "Basic " + base64.encodestring("%s:%s" % (self.user,self.passwd))) + passman = urllib2.HTTPPasswordMgrWithDefaultRealm() + passman.add_password(None, self.updateEndpoint, self.user, self.passwd) + auth_handler = urllib2.HTTPDigestAuthHandler(passman) + opener = urllib2.build_opener(auth_handler) + urllib2.install_opener(opener) + return request def _query(self):
it further turns out that virtuoso-opensource 6.1.4+dfsg1-0ubuntu1 is not compliant with the new update= notation that replaces the query= syntax in case of a SPARQL 1.1 update operation, according to the SPARQL 1.1 spec anyway.
so one needs to override the SPARQLWrapper Query keyword when a SPARQL 1.1 update is used in a SPARQLWrapper Query:
sparql.queryType= SELECT
I can finally update my virtuoso database by using SPARQLWrapper!