SPARQLWrapper-1.6.4/0000755000175000017500000000000012377101654014675 5ustar sergiosergio00000000000000SPARQLWrapper-1.6.4/test/0000755000175000017500000000000012377101654015654 5ustar sergiosergio00000000000000SPARQLWrapper-1.6.4/test/wrapper_test.py0000644000175000017500000004613112377047077020762 0ustar sergiosergio00000000000000# -*- coding: utf-8 -*- import inspect import os import sys import logging logging.basicConfig() import unittest from urlparse import urlparse from urllib2 import Request from cgi import parse_qs # prefer local copy to the one which is installed # hack from http://stackoverflow.com/a/6098238/280539 _top_level_path = os.path.realpath(os.path.abspath(os.path.join( os.path.split(inspect.getfile(inspect.currentframe()))[0], ".." ))) if _top_level_path not in sys.path: sys.path.insert(0, _top_level_path) # end of hack from SPARQLWrapper import SPARQLWrapper from SPARQLWrapper import XML, GET, POST, JSON, JSONLD, N3, TURTLE, RDF, SELECT, INSERT from SPARQLWrapper import URLENCODED, POSTDIRECTLY from SPARQLWrapper.Wrapper import QueryResult, QueryBadFormed, EndPointNotFound, EndPointInternalError # we don't want to let Wrapper do real web-requests. so, we are… # constructing a simple Mock! from urllib2 import HTTPError from io import StringIO import warnings import SPARQLWrapper.Wrapper as _victim class FakeResult(object): def __init__(self, request): self.request = request def urlopener(request): return FakeResult(request) def urlopener_error_generator(code): def urlopener_error(request): raise HTTPError(request.get_full_url, code, '', {}, StringIO(u'')) return urlopener_error def urlopener_check_data_encoding(request): if sys.version < '3': # have to write it like this, for 2to3 compatibility if isinstance(request.data, unicode): raise TypeError else: if isinstance(request.data, str): raise TypeError # DONE class SPARQLWrapper_Test(unittest.TestCase): @staticmethod def _get_request(wrapper): request = wrapper.query().response.request # possible due to mock above return request @staticmethod def _get_parameters_from_request(request): if request.get_method() == 'GET': pieces_str = urlparse(request.get_full_url()).query else: if sys.version < '3': pieces_str = request.data else: pieces_str = request.data.decode('ascii') return parse_qs(pieces_str) @staticmethod def _get_request_parameters(wrapper): request = SPARQLWrapper_Test._get_request(wrapper) parameters = SPARQLWrapper_Test._get_parameters_from_request(request) return parameters @staticmethod def _get_request_parameters_as_bytes(wrapper): request = SPARQLWrapper_Test._get_request(wrapper) parameters = SPARQLWrapper_Test._get_parameters_from_request(request) if sys.version < '3': return parameters else: result = {} for k,vs in parameters.iteritems(): result[k] = [v.encode('utf-8') for v in vs] return result def setUp(self): self.wrapper = SPARQLWrapper(endpoint='http://example.org/sparql') _victim.urlopener = urlopener def testConstructor(self): try: SPARQLWrapper() self.fail("SPARQLWrapper constructor should fail without arguments") except TypeError: pass wrapper = SPARQLWrapper(endpoint='http://example.org/sparql/') self.assertEqual(XML, wrapper.returnFormat, 'default return format is XML') self.assertTrue( wrapper.agent.startswith('sparqlwrapper'), 'default user-agent should start with "sparqlwrapper"' ) wrapper = SPARQLWrapper(endpoint='http://example.org/sparql/', returnFormat='wrongformat') self.assertEqual(XML, wrapper.returnFormat, 'default return format is XML') wrapper = SPARQLWrapper(endpoint='http://example.org/sparql/', defaultGraph='http://example.org/default') parameters = self._get_request_parameters(wrapper) self.assertEqual( ['http://example.org/default'], parameters.get('default-graph-uri'), 'default graph is set' ) def testReset(self): self.wrapper.setMethod(POST) self.wrapper.setQuery('CONSTRUCT WHERE {?a ?b ?c}') self.wrapper.setReturnFormat(N3) self.wrapper.addParameter('a', 'b') request = self._get_request(self.wrapper) parameters = self._get_parameters_from_request(request) self.assertEqual('POST', request.get_method()) self.assertTrue(parameters['query'][0].startswith('CONSTRUCT')) self.assertTrue('rdf+n3' in request.get_header('Accept')) self.assertTrue('a' in parameters) self.wrapper.resetQuery() request = self._get_request(self.wrapper) parameters = self._get_parameters_from_request(request) self.assertEqual('GET', request.get_method()) self.assertTrue(parameters['query'][0].startswith('SELECT')) self.assertFalse('rdf+n3' in request.get_header('Accept')) self.assertTrue('sparql-results+xml' in request.get_header('Accept')) self.assertFalse('a' in parameters) def testSetReturnFormat(self): self.assertRaises(ValueError, self.wrapper.setReturnFormat, 'nonexistent format') self.assertEqual(XML, self.wrapper.query().requestedFormat) self.wrapper.setReturnFormat(JSON) self.assertEqual(JSON, self.wrapper.query().requestedFormat) try: import rdflib_jsonld self.wrapper.setReturnFormat(JSONLD) self.assertEqual(JSONLD, self.wrapper.query().requestedFormat) except ImportError: self.assertRaises(ValueError, self.wrapper.setReturnFormat, JSONLD) def testsSupportsReturnFormat(self): self.assertTrue(self.wrapper.supportsReturnFormat(XML)) self.assertTrue(self.wrapper.supportsReturnFormat(JSON)) self.assertTrue(self.wrapper.supportsReturnFormat(TURTLE)) self.assertTrue(self.wrapper.supportsReturnFormat(N3)) self.assertTrue(self.wrapper.supportsReturnFormat(RDF)) self.assertFalse(self.wrapper.supportsReturnFormat('nonexistent format')) try: import rdflib_jsonld self.assertTrue(self.wrapper.supportsReturnFormat(JSONLD)) except ImportError: self.assertFalse(self.wrapper.supportsReturnFormat(JSONLD)) def testAddParameter(self): self.assertFalse(self.wrapper.addParameter('query', 'dummy')) self.assertTrue(self.wrapper.addParameter('param1', 'value1')) self.assertTrue(self.wrapper.addParameter('param1', 'value2')) self.assertTrue(self.wrapper.addParameter('param2', 'value2')) pieces = self._get_request_parameters(self.wrapper) self.assertTrue('param1' in pieces) self.assertEqual(['value1', 'value2'], pieces['param1']) self.assertTrue('param2' in pieces) self.assertEqual(['value2'], pieces['param2']) self.assertNotEqual(['dummy'], 'query') def testSetCredentials(self): request = self._get_request(self.wrapper) self.assertFalse(request.has_header('Authorization')) self.wrapper.setCredentials('login', 'password') request = self._get_request(self.wrapper) self.assertTrue(request.has_header('Authorization')) # TODO: test for header-value using some external decoder implementation def testSetQuery(self): self.wrapper.setQuery('PREFIX example: SELECT * WHERE {?s ?p ?v}') self.assertEqual(SELECT, self.wrapper.queryType) self.wrapper.setQuery('PREFIX e: INSERT {e:a e:b e:c}') self.assertEqual(INSERT, self.wrapper.queryType) self.wrapper.setQuery("""#CONSTRUCT {?s ?p ?o} SELECT ?s ?p ?o WHERE {?s ?p ?o}""") self.assertEqual(SELECT, self.wrapper.queryType) with warnings.catch_warnings(record=True) as w: self.wrapper.setQuery('UNKNOWN {e:a e:b e:c}') self.assertEqual(SELECT, self.wrapper.queryType, 'unknown queries result in SELECT') def testSetQueryEncodingIssues(self): #further details from issue #35 query = u'INSERT DATA { "これはテストです" }' query_bytes = query.encode('utf-8') self.wrapper.setMethod(POST) self.wrapper.setRequestMethod(POSTDIRECTLY) self.wrapper.setQuery(query) request = self._get_request(self.wrapper) self.assertEquals(query_bytes, request.data) self.wrapper.setQuery(query_bytes) request = self._get_request(self.wrapper) self.assertEquals(query_bytes, request.data) self.wrapper.setRequestMethod(URLENCODED) self.wrapper.setQuery(query) parameters = self._get_request_parameters_as_bytes(self.wrapper) self.assertEquals(query_bytes, parameters['update'][0]) self.wrapper.setQuery(query_bytes) parameters = self._get_request_parameters_as_bytes(self.wrapper) self.assertEquals(query_bytes, parameters['update'][0]) try: self.wrapper.setQuery(query.encode('sjis')) self.fail() except UnicodeDecodeError: self.assertTrue(True) try: self.wrapper.setQuery({'foo': 'bar'}) self.fail() except TypeError: self.assertTrue(True) def testSetTimeout(self): self.wrapper.setTimeout(10) self.assertEqual(10, self.wrapper.timeout) self.wrapper.resetQuery() self.assertEqual(None, self.wrapper.timeout) def testClearParameter(self): self.wrapper.addParameter('param1', 'value1') self.wrapper.addParameter('param1', 'value2') self.wrapper.addParameter('param2', 'value2') self.assertFalse(self.wrapper.clearParameter('query')) self.assertTrue(self.wrapper.clearParameter('param1')) pieces = self._get_request_parameters(self.wrapper) self.assertFalse('param1' in pieces) self.assertTrue('param2' in pieces) self.assertEqual(['value2'], pieces['param2']) self.assertFalse(self.wrapper.clearParameter('param1'), 'already cleaned') def testSetMethod(self): self.wrapper.setMethod(POST) request = self._get_request(self.wrapper) self.assertEqual("POST", request.get_method()) self.wrapper.setMethod(GET) request = self._get_request(self.wrapper) self.assertEqual("GET", request.get_method()) def testSetRequestMethod(self): self.assertEqual(URLENCODED, self.wrapper.requestMethod) self.wrapper.setRequestMethod(POSTDIRECTLY) self.assertEqual(POSTDIRECTLY, self.wrapper.requestMethod) def testIsSparqlUpdateRequest(self): self.wrapper.setQuery('DELETE WHERE {?s ?p ?o}') self.assertTrue(self.wrapper.isSparqlUpdateRequest()) self.wrapper.setQuery('DELETE DATA { }') self.assertTrue(self.wrapper.isSparqlUpdateRequest()) self.wrapper.setQuery(""" PREFIX example: BASE DELETE WHERE {?s ?p ?o} """) self.assertTrue(self.wrapper.isSparqlUpdateRequest()) self.wrapper.setQuery('WITH DELETE DATA { }') self.assertTrue(self.wrapper.isSparqlUpdateRequest()) self.wrapper.setQuery('INSERT DATA { }') self.assertTrue(self.wrapper.isSparqlUpdateRequest()) self.wrapper.setQuery('WITH INSERT DATA { }') self.assertTrue(self.wrapper.isSparqlUpdateRequest()) self.wrapper.setQuery('CREATE GRAPH ') self.assertTrue(self.wrapper.isSparqlUpdateRequest()) self.wrapper.setQuery('CLEAR GRAPH ') self.assertTrue(self.wrapper.isSparqlUpdateRequest()) self.wrapper.setQuery('DROP GRAPH ') self.assertTrue(self.wrapper.isSparqlUpdateRequest()) self.wrapper.setQuery('MOVE GRAPH TO GRAPH ') self.assertTrue(self.wrapper.isSparqlUpdateRequest()) self.wrapper.setQuery('LOAD INTO GRAPH ') self.assertTrue(self.wrapper.isSparqlUpdateRequest()) self.wrapper.setQuery('COPY TO GRAPH ') self.assertTrue(self.wrapper.isSparqlUpdateRequest()) self.wrapper.setQuery('ADD TO GRAPH ') self.assertTrue(self.wrapper.isSparqlUpdateRequest()) def testIsSparqlQueryRequest(self): self.wrapper.setQuery('SELECT * WHERE {?s ?p ?o}') self.assertTrue(self.wrapper.isSparqlQueryRequest()) self.wrapper.setQuery(""" PREFIX example: BASE ASK WHERE {?s ?p ?o} """) self.assertTrue(self.wrapper.isSparqlQueryRequest()) self.assertFalse(self.wrapper.isSparqlUpdateRequest()) def testQuery(self): qr = self.wrapper.query() self.assertTrue(isinstance(qr, QueryResult)) request = qr.response.request # possible due to mock above self.assertTrue(isinstance(request, Request)) parameters = self._get_parameters_from_request(request) self.assertTrue('query' in parameters) self.assertTrue('update' not in parameters) self.wrapper.setMethod(POST) self.wrapper.setQuery('PREFIX e: INSERT {e:a e:b e:c}') parameters = self._get_request_parameters(self.wrapper) self.assertTrue('update' in parameters) self.assertTrue('query' not in parameters) _victim.urlopener = urlopener_error_generator(400) try: self.wrapper.query() self.fail('should have raised exception') except QueryBadFormed as e: # TODO: check exception-format pass except: self.fail('got wrong exception') _victim.urlopener = urlopener_error_generator(404) try: self.wrapper.query() self.fail('should have raised exception') except EndPointNotFound as e: # TODO: check exception-format pass except: self.fail('got wrong exception') _victim.urlopener = urlopener_error_generator(500) try: self.wrapper.query() self.fail('should have raised exception') except EndPointInternalError as e: # TODO: check exception-format pass except: self.fail('got wrong exception') _victim.urlopener = urlopener_error_generator(999) try: self.wrapper.query() self.fail('should have raised exception') except HTTPError as e: # TODO: check exception-format pass except: self.fail('got wrong exception') def testQueryEncoding(self): query = 'INSERT DATA { "é" }' wrapper = SPARQLWrapper('http://example.com:3030/example') wrapper.setMethod(POST) wrapper.setRequestMethod(URLENCODED) wrapper.setQuery(query) _victim.urlopener = urlopener_check_data_encoding wrapper.query() def testQueryAndConvert(self): _oldQueryResult = _victim.QueryResult class FakeQueryResult(object): def __init__(self, result): pass def convert(self): return True try: _victim.QueryResult = FakeQueryResult result = self.wrapper.queryAndConvert() self.assertEqual(True, result) finally: _victim.QueryResult = _oldQueryResult class QueryResult_Test(unittest.TestCase): def testConstructor(self): qr = QueryResult('result') self.assertEqual('result', qr.response) try: format = qr.requestedFormat self.fail('format is not supposed to be set') except: pass qr = QueryResult(('result', 'format')) self.assertEqual('result', qr.response) self.assertEqual('format', qr.requestedFormat) def testProxyingToResponse(self): class FakeResponse(object): def __init__(self): self.geturl_called = False self.info_called = False self.iter_called = False self.next_called = False def geturl(self): self.geturl_called = True def info(self): self.info_called = True return {"key": "value"} def __iter__(self): self.iter_called = True def next(self): self.next_called = True result = FakeResponse() qr = QueryResult(result) qr.geturl() qr.__iter__() qr.next() self.assertTrue(result.geturl_called) self.assertTrue(result.iter_called) self.assertTrue(result.next_called) info = qr.info() self.assertTrue(result.info_called) self.assertEqual('value', info.__getitem__('KEY'), 'keys should be case-insensitive') def testConvert(self): class FakeResponse(object): def __init__(self, content_type): self.content_type = content_type def info(self): return {"Content-type": self.content_type} def read(self, len): return '' def _mime_vs_type(mime, requested_type): """ @param mime: @param requested_type: @return: number of warnings produced by combo """ with warnings.catch_warnings(record=True) as w: qr = QueryResult((FakeResponse(mime), requested_type)) try: qr.convert() except: pass return len(w) self.assertEqual(0, _mime_vs_type("application/sparql-results+xml", XML)) self.assertEqual(0, _mime_vs_type("application/sparql-results+json", JSON)) self.assertEqual(0, _mime_vs_type("text/n3", N3)) self.assertEqual(0, _mime_vs_type("text/turtle", TURTLE)) self.assertEqual(0, _mime_vs_type("application/ld+json", JSON)) self.assertEqual(0, _mime_vs_type("application/ld+json", JSONLD)) self.assertEqual(0, _mime_vs_type("application/rdf+xml", XML)) self.assertEqual(0, _mime_vs_type("application/rdf+xml", RDF)) self.assertEqual(1, _mime_vs_type("application/x-foo-bar", XML), "invalid mime") self.assertEqual(1, _mime_vs_type("application/sparql-results+xml", N3)) self.assertEqual(1, _mime_vs_type("application/sparql-results+json", XML)) self.assertEqual(1, _mime_vs_type("text/n3", JSON)) self.assertEqual(1, _mime_vs_type("text/turtle", XML)) self.assertEqual(1, _mime_vs_type("application/ld+json", XML)) self.assertEqual(1, _mime_vs_type("application/ld+json", N3)) self.assertEqual(1, _mime_vs_type("application/rdf+xml", JSON)) self.assertEqual(1, _mime_vs_type("application/rdf+xml", N3)) if __name__ == "__main__": unittest.main() SPARQLWrapper-1.6.4/test/dbpedia.py0000755000175000017500000002276012377047077017640 0ustar sergiosergio00000000000000# -*- coding: utf8 -*- #!/usr/bin/python import inspect import os import sys # prefer local copy to the one which is installed # hack from http://stackoverflow.com/a/6098238/280539 _top_level_path = os.path.realpath(os.path.abspath(os.path.join( os.path.split(inspect.getfile(inspect.currentframe()))[0], ".." ))) if _top_level_path not in sys.path: sys.path.insert(0, _top_level_path) # end of hack import unittest try: from rdflib.graph import ConjunctiveGraph except ImportError: from rdflib import ConjunctiveGraph from SPARQLWrapper import SPARQLWrapper, XML, N3, JSONLD, JSON, POST, GET, SELECT, CONSTRUCT, ASK, DESCRIBE from SPARQLWrapper.Wrapper import _SPARQL_DEFAULT, _SPARQL_XML, _SPARQL_JSON, _SPARQL_POSSIBLE, _RDF_XML, _RDF_N3, _RDF_JSONLD, _RDF_POSSIBLE from SPARQLWrapper.SPARQLExceptions import QueryBadFormed try: from urllib.error import HTTPError # Python 3 except ImportError: from urllib2 import HTTPError # Python 2 try: bytes # Python 2.6 and above except NameError: bytes = str import logging logging.basicConfig() endpoint = "http://dbpedia.org/sparql" prefixes = """ PREFIX rdf: PREFIX rdfs: """ selectQuery = """ SELECT ?label WHERE { rdfs:label ?label . } """ constructQuery = """ CONSTRUCT { _:v rdfs:label ?label . _:v rdfs:comment "this is only a mock node to test library" } WHERE { rdfs:label ?label . } """ queryBadFormed = """ PREFIX prop: PREFIX res: FROM SELECT ?lat ?long WHERE { res:Budapest prop:latitude ?lat; prop:longitude ?long. } """ queryManyPrefixes = """ PREFIX conf: PREFIX meta: PREFIX rdf: PREFIX rdfs: PREFIX xsd: PREFIX owl: PREFIX dc: PREFIX dcterms: PREFIX foaf: PREFIX skos: PREFIX geo: PREFIX dbpedia: PREFIX o: PREFIX p: PREFIX yago: PREFIX units: PREFIX geonames: PREFIX prv: PREFIX prvTypes: PREFIX foo: SELECT ?label WHERE { rdfs:label ?label . } """ class SPARQLWrapperTests(unittest.TestCase): def __generic(self, query, returnFormat, method): sparql = SPARQLWrapper(endpoint) sparql.setQuery(prefixes + query) sparql.setReturnFormat(returnFormat) sparql.setMethod(method) try: result = sparql.query() except HTTPError: # An ugly way to get the exception, but the only one that works # both on Python 2.5 and Python 3. e = sys.exc_info()[1] if e.code == 400: sys.stdout.write("400 Bad Request, probably query is not well formed") elif e.code == 406: sys.stdout.write("406 Not Acceptable, maybe query is not well formed") else: sys.stdout.write(str(e)) sys.stdout.write("\n") return False else: return result def testSelectByGETinXML(self): result = self.__generic(selectQuery, XML, GET) ct = result.info()["content-type"] assert True in [one in ct for one in _SPARQL_XML], ct results = result.convert() results.toxml() def testSelectByPOSTinXML(self): result = self.__generic(selectQuery, XML, POST) ct = result.info()["content-type"] assert True in [one in ct for one in _SPARQL_XML], ct results = result.convert() results.toxml() # Virtuoso returns text/rdf+n3. It MUST return SPARQL Results Document in XML (sparql-results+xml), JSON (sparql-results+json), or CSV/TSV (text/csv or text/tab-separated-values) see http://www.w3.org/TR/sparql11-protocol/#query-success # URI generated http://dbpedia.org/sparql?query=%0A++++PREFIX+rdf%3A+%3Chttp%3A%2F%2Fwww.w3.org%2F1999%2F02%2F22-rdf-syntax-ns%23%3E%0A++++PREFIX+rdfs%3A+%3Chttp%3A%2F%2Fwww.w3.org%2F2000%2F01%2Frdf-schema%23%3E%0A%0A++++SELECT+%3Flabel%0A++++WHERE+%7B%0A++++%3Chttp%3A%2F%2Fdbpedia.org%2Fresource%2FAsturias%3E+rdfs%3Alabel+%3Flabel+.%0A++++%7D%0A def _testSelectByGETinN3(self): result = self.__generic(selectQuery, N3, GET) ct = result.info()["content-type"] assert True in [one in ct for one in _SPARQL_XML], ct assert True in [one in ct for one in _SPARQL_POSSIBLE], ct results = result.convert() self.assertEqual(type(results), bytes) def testSelectByGETinJSON(self): result = self.__generic(selectQuery, JSON, GET) ct = result.info()["content-type"] assert True in [one in ct for one in _SPARQL_JSON], ct results = result.convert() self.assertEqual(type(results), dict) def testSelectByPOSTinJSON(self): result = self.__generic(selectQuery, JSON, POST) ct = result.info()["content-type"] assert True in [one in ct for one in _SPARQL_JSON], ct results = result.convert() self.assertEqual(type(results), dict) def testSelectByGETinUnknow(self): result = self.__generic(selectQuery, "foo", GET) ct = result.info()["content-type"] assert True in [one in ct for one in _SPARQL_POSSIBLE], ct results = result.convert() def testSelectByPOSTinUnknow(self): result = self.__generic(selectQuery, "bar", POST) ct = result.info()["content-type"] assert True in [one in ct for one in _SPARQL_POSSIBLE], ct results = result.convert() def testConstructByGETinXML(self): result = self.__generic(constructQuery, XML, GET) ct = result.info()["content-type"] assert True in [one in ct for one in _RDF_XML], ct results = result.convert() self.assertEqual(type(results), ConjunctiveGraph) def testConstructByPOSTinXML(self): result = self.__generic(constructQuery, XML, POST) ct = result.info()["content-type"] assert True in [one in ct for one in _RDF_XML], ct results = result.convert() self.assertEqual(type(results), ConjunctiveGraph) def testConstructByGETinN3(self): result = self.__generic(constructQuery, N3, GET) ct = result.info()["content-type"] assert True in [one in ct for one in _RDF_N3], ct results = result.convert() self.assertEqual(type(results), bytes) def testConstructByPOSTinN3(self): result = self.__generic(constructQuery, N3, POST) ct = result.info()["content-type"] assert True in [one in ct for one in _RDF_N3], ct results = result.convert() self.assertEqual(type(results), bytes) # Virtuoso returns application/sparql-results+json. It MUST return an RDF graph [RDF-CONCEPTS] serialized, for example, in the RDF/XML syntax [RDF-XML], or an equivalent RDF graph serialization, for SPARQL Query forms DESCRIBE and CONSTRUCT). See http://www.w3.org/TR/sparql11-protocol/#query-success def _testConstructByGETinJSON(self): result = self.__generic(constructQuery, JSON, GET) ct = result.info()["content-type"] assert True in [one in ct for one in _RDF_POSSIBLE], ct results = result.convert() self.assertEqual(type(results), ConjunctiveGraph) def _testConstructByPOSTinJSON(self): result = self.__generic(constructQuery, _RDF_JSONLD, POST) ct = result.info()["content-type"] assert True in [one in ct for one in _RDF_POSSIBLE], ct results = result.convert() self.assertEqual(type(results), bytes) def testConstructByGETinUnknow(self): result = self.__generic(constructQuery, "foo", GET) ct = result.info()["content-type"] assert True in [one in ct for one in _RDF_POSSIBLE], ct results = result.convert() self.assertEqual(type(results), ConjunctiveGraph) def testConstructByPOSTinUnknow(self): result = self.__generic(constructQuery, "bar", POST) ct = result.info()["content-type"] assert True in [one in ct for one in _RDF_POSSIBLE], ct results = result.convert() self.assertEqual(type(results), ConjunctiveGraph) def testQueryBadFormed(self): self.assertRaises(QueryBadFormed, self.__generic, queryBadFormed, XML, GET) # def testQueryManyPrefixes(self): # result = self.__generic(queryManyPrefixes, XML, GET) if __name__ == "__main__": unittest.main() SPARQLWrapper-1.6.4/AUTHORS.md0000644000175000017500000000247612377071420016352 0ustar sergiosergio00000000000000# Authors * Ivan Herman ([@iherman](http://github.com/iherman)) * Sergio Fernández ([@wikier](http://github.com/wikier)) * Carlos Tejo ([@dayures](http://github.com/dayures)) * Alexey Zakhlestin ([@indeyets](http://github.com/indeyets)) # Contributors * Obey Arthur Liu ([@ArthurLiu](http://github.com/ArthurLiu)): different patches * Christopher Lenz ([@cmlenz](http://github.com/cmlenz)): feature to allow developers to choose the json module * Pēteris Caune ([@cuu508](http://github.com/cuu508)): great feedback and patches * Bogdan Benea ([bugdone@users.sourceforge.net](mailto:bugdone@users.sourceforge.net)), patch for the query regular expresion * William Waites ([@wwaites](http://github.com/wwaites)): patches for RDFLib3 * Christoph Burgmer ([@cburgmer](http://github.com/cburgmer)): patches for RDFLib3 * Thomas Kluyver ([@takluyver](http://github.com/takluyver)): patches for Python 3.x * Diego Berrueta ([@berrueta](http://github.com/berrueta)): new function for printing results as table * Olivier Berger ([@olberger](http://github.com/olberger)): patch regarding raw response for unknown formats * Benjamin Cogrel ([@bcogrel](http://github.com/bcogrel)): standard query types * Urs Holzer ([@uholzer](http://github.com/uholzer)): features, patches and testing * Alf Lervåg ([@alf](http://github.com/alf)): setup patch SPARQLWrapper-1.6.4/README.md0000644000175000017500000000075112377047077016167 0ustar sergiosergio00000000000000# SPARQL Endpoint interface to Python [![Build Status](https://secure.travis-ci.org/RDFLib/sparqlwrapper.svg?branch=master)](https://travis-ci.org/RDFLib/sparqlwrapper) The distribution contains: * `SPARQLWrapper`: the Python library. You should copy the directory somewhere into your PYTHONPATH. Alternatively, you can also run the disutils scrips: python setup.py install * `test`: some unit tests * `script`: some scripts to run the library against some SPARQL end-points. SPARQLWrapper-1.6.4/SPARQLWrapper/0000755000175000017500000000000012377101654017240 5ustar sergiosergio00000000000000SPARQLWrapper-1.6.4/SPARQLWrapper/SPARQLExceptions.py0000644000175000017500000000271012377047077022666 0ustar sergiosergio00000000000000# -*- coding: utf-8 -*- """ SPARQL Wrapper exceptions @authors: U{Ivan Herman}, U{Sergio Fernández}, U{Carlos Tejo Alonso} @organization: U{World Wide Web Consortium} and U{Foundation CTIC}. @license: U{W3C® SOFTWARE NOTICE AND LICENSE} """ class SPARQLWrapperException(Exception): """ Base class for SPARQL Wrapper exceptions """ msg = "an exception has occured" def __init__(self, response=None): if response: formatted_msg = "%s: %s. \n\nResponse:\n%s" % (self.__class__.__name__, self.msg, response) else: formatted_msg = "%s: %s." % (self.__class__.__name__, self.msg) super(SPARQLWrapperException, self).__init__(formatted_msg) class EndPointInternalError(SPARQLWrapperException): """ Exception type for 500 Internal Server Error responses. """ msg = "endpoint returned code 500 and response" class QueryBadFormed(SPARQLWrapperException): """ Query Bad Formed exception """ msg = "a bad request has been sent to the endpoint, probably the sparql query is bad formed" class EndPointNotFound(SPARQLWrapperException): """ End Point Not Found exception """ msg = "it was impossible to connect with the endpoint in that address, check if it is correct" SPARQLWrapper-1.6.4/SPARQLWrapper/Wrapper.py0000644000175000017500000007601312377047077021251 0ustar sergiosergio00000000000000# -*- coding: utf-8 -*- # epydoc # """ @var JSON: to be used to set the return format to JSON @var XML: to be used to set the return format to XML (SPARQL XML format or RDF/XML, depending on the query type). This is the default. @var TURTLE: to be used to set the return format to Turtle @var N3: to be used to set the return format to N3 (for most of the SPARQL services this is equivalent to Turtle) @var RDF: to be used to set the return RDF Graph @var POST: to be used to set HTTP POST @var GET: to be used to set HTTP GET. This is the default. @var SELECT: to be used to set the query type to SELECT. This is, usually, determined automatically. @var CONSTRUCT: to be used to set the query type to CONSTRUCT. This is, usually, determined automatically. @var ASK: to be used to set the query type to ASK. This is, usually, determined automatically. @var DESCRIBE: to be used to set the query type to DESCRIBE. This is, usually, determined automatically. @see: U{SPARQL Specification} @authors: U{Ivan Herman}, U{Sergio Fernández}, U{Carlos Tejo Alonso} @organization: U{World Wide Web Consortium}, U{Salzburg Research} and U{Foundation CTIC}. @license: U{W3C® SOFTWARE NOTICE AND LICENSE} @requires: U{RDFLib} package. """ import urllib import urllib2 from urllib2 import urlopen as urlopener # don't change the name: tests override it import socket import base64 import re import sys import warnings import jsonlayer from KeyCaseInsensitiveDict import KeyCaseInsensitiveDict from SPARQLExceptions import QueryBadFormed, EndPointNotFound, EndPointInternalError from SPARQLUtils import deprecated from SPARQLWrapper import __agent__ # Possible output format keys... JSON = "json" JSONLD = "json-ld" XML = "xml" TURTLE = "n3" N3 = "n3" RDF = "rdf" _allowedFormats = [JSON, XML, TURTLE, N3, RDF] # Possible HTTP methods POST = "POST" GET = "GET" _allowedRequests = [POST, GET] # Possible SPARQL/SPARUL query type SELECT = "SELECT" CONSTRUCT = "CONSTRUCT" ASK = "ASK" DESCRIBE = "DESCRIBE" INSERT = "INSERT" DELETE = "DELETE" CREATE = "CREATE" CLEAR = "CLEAR" DROP = "DROP" LOAD = "LOAD" COPY = "COPY" MOVE = "MOVE" ADD = "ADD" _allowedQueryTypes = [SELECT, CONSTRUCT, ASK, DESCRIBE, INSERT, DELETE, CREATE, CLEAR, DROP, LOAD, COPY, MOVE, ADD] # Possible methods to perform requests URLENCODED = "urlencoded" POSTDIRECTLY = "postdirectly" _REQUEST_METHODS = [URLENCODED, POSTDIRECTLY] # Possible output format (mime types) that can be converted by the local script. Unfortunately, # it does not work by simply setting the return format, because there is still a certain level of confusion # among implementations. # For example, Joseki returns application/javascript and not the sparql-results+json thing that is required... # Ie, alternatives should be given... # Andy Seaborne told me (June 2007) that the right return format is now added to his CVS, ie, future releases of # joseki will be o.k., too. The situation with turtle and n3 is even more confusing because the text/n3 and text/turtle # mime types have just been proposed and not yet widely used... _SPARQL_DEFAULT = ["application/sparql-results+xml", "application/rdf+xml", "*/*"] _SPARQL_XML = ["application/sparql-results+xml"] _SPARQL_JSON = ["application/sparql-results+json", "text/javascript", "application/json"] _RDF_XML = ["application/rdf+xml"] _RDF_N3 = ["text/rdf+n3", "application/n-triples", "application/turtle", "application/n3", "text/n3", "text/turtle"] _RDF_JSONLD = ["application/x-json+ld", "application/ld+json"] _ALL = ["*/*"] _RDF_POSSIBLE = _RDF_XML + _RDF_N3 _SPARQL_POSSIBLE = _SPARQL_XML + _SPARQL_JSON + _RDF_XML + _RDF_N3 _SPARQL_PARAMS = ["query"] try: import rdflib_jsonld _allowedFormats.append(JSONLD) _RDF_POSSIBLE = _RDF_POSSIBLE + _RDF_JSONLD except ImportError: #warnings.warn("JSON-LD disabled because no suitable support has been found", RuntimeWarning) pass # This is very ugly. The fact is that the key for the choice of the output format is not defined. # Virtuoso uses 'format', joseki uses 'output', rasqual seems to use "results", etc. Lee Feigenbaum # told me that virtuoso also understand 'output' these days, so I removed 'format'. I do not have # info about the others yet, ie, for the time being I keep the general mechanism. Hopefully, in a # future release, I can get rid of that. However, these processors are (hopefully) oblivious to the # parameters they do not understand. So: just repeat all possibilities in the final URI. UGLY!!!!!!! _returnFormatSetting = ["format", "output", "results"] ####################################################################################################### class SPARQLWrapper(object): """ Wrapper around an online access to a SPARQL Web entry point. The same class instance can be reused for subsequent queries. The values of the base Graph URI, return formats, etc, are retained from one query to the next (in other words, only the query string changes). The instance can also be reset to its initial values using the L{resetQuery} method. @cvar pattern: regular expression used to determine whether a query is of type L{CONSTRUCT}, L{SELECT}, L{ASK}, or L{DESCRIBE}. @type pattern: compiled regular expression (see the C{re} module of Python) @ivar baseURI: the URI of the SPARQL service """ pattern = re.compile(r""" ((?P(\s*BASE\s*<.*?>)\s*)|(?P(\s*PREFIX\s+.+:\s*<.*?>)\s*))* (?P(CONSTRUCT|SELECT|ASK|DESCRIBE|INSERT|DELETE|CREATE|CLEAR|DROP|LOAD|COPY|MOVE|ADD)) """, re.VERBOSE | re.IGNORECASE) def __init__(self, endpoint, updateEndpoint=None, returnFormat=XML, defaultGraph=None, agent=__agent__): """ Class encapsulating a full SPARQL call. @param endpoint: string of the SPARQL endpoint's URI @type endpoint: string @param updateEndpoint: string of the SPARQL endpoint's URI for update operations (if it's a different one) @type updateEndpoint: string @keyword returnFormat: Default: L{XML}. Can be set to JSON or Turtle/N3 No local check is done, the parameter is simply sent to the endpoint. Eg, if the value is set to JSON and a construct query is issued, it is up to the endpoint to react or not, this wrapper does not check. Possible values: L{JSON}, L{XML}, L{TURTLE}, L{N3} (constants in this module). The value can also be set via explicit call, see below. @type returnFormat: string @keyword defaultGraph: URI for the default graph. Default is None, the value can be set either via an L{explicit call} or as part of the query string. @type defaultGraph: string """ self.endpoint = endpoint self.updateEndpoint = updateEndpoint if updateEndpoint else endpoint self.agent = agent self.user = None self.passwd = None self._defaultGraph = defaultGraph if returnFormat in _allowedFormats: self._defaultReturnFormat = returnFormat else: self._defaultReturnFormat = XML self.resetQuery() def resetQuery(self): """Reset the query, ie, return format, query, default or named graph settings, etc, are reset to their default values.""" self.parameters = {} if self._defaultGraph: self.addParameter("default-graph-uri", self._defaultGraph) self.returnFormat = self._defaultReturnFormat self.method = GET self.setQuery("""SELECT * WHERE{ ?s ?p ?o }""") self.timeout = None self.requestMethod = URLENCODED def setReturnFormat(self, format): """Set the return format. If not an allowed value, the setting is ignored. @param format: Possible values: are L{JSON}, L{XML}, L{TURTLE}, L{N3}, L{RDF} (constants in this module). All other cases are ignored. @type format: str """ if format in _allowedFormats : self.returnFormat = format elif format == JSONLD: raise ValueError("Current instance does not support JSON-LD; you might want to install the rdflib-json package.") else: raise ValueError("Invalid format '%s'; current instance supports: %s.", (format, ", ".join(_allowedFormats))) def supportsReturnFormat(self, format): """Check if a return format is supported. @param format: Possible values: are L{JSON}, L{XML}, L{TURTLE}, L{N3}, L{RDF} (constants in this module). All other cases are ignored. @type format: bool """ return (format in _allowedFormats) def setTimeout(self, timeout): """Set the timeout (in seconds) to use for querying the endpoint. @param timeout: Timeout in seconds. @type timeout: int """ self.timeout = int(timeout) def setRequestMethod(self, method): """Set the internal method to use to perform the request for query or update operations, either URL-encoded (C{SPARQLWrapper.URLENCODED}) or POST directly (C{SPARQLWrapper.POSTDIRECTLY}). Further details at U{http://www.w3.org/TR/sparql11-protocol/#query-operation} and U{http://www.w3.org/TR/sparql11-protocol/#update-operation}. @param method: method @type method: str """ if method in _REQUEST_METHODS: self.requestMethod = method else: warnings.warn("invalid update method '%s'" % method, RuntimeWarning) @deprecated def addDefaultGraph(self, uri): """ Add a default graph URI. @param uri: URI of the graph @type uri: string @deprecated: use addParameter("default-graph-uri", uri) instead of this method """ self.addParameter("default-graph-uri", uri) @deprecated def addNamedGraph(self, uri): """ Add a named graph URI. @param uri: URI of the graph @type uri: string @deprecated: use addParameter("named-graph-uri", uri) instead of this method """ self.addParameter("named-graph-uri", uri) @deprecated def addExtraURITag(self, key, value): """ Some SPARQL endpoints require extra key value pairs. E.g., in virtuoso, one would add C{should-sponge=soft} to the query forcing virtuoso to retrieve graphs that are not stored in its local database. @param key: key of the query part @type key: string @param value: value of the query part @type value: string @deprecated: use addParameter(key, value) instead of this method """ self.addParameter(key, value) @deprecated def addCustomParameter(self, name, value): """ Method is kept for backwards compatibility. Historically, it "replaces" parameters instead of adding @param name: name @type name: string @param value: value @type value: string @rtype: bool @deprecated: use addParameter(name, value) instead of this method """ self.clearParameter(name) return self.addParameter(name, value) def addParameter(self, name, value): """ Some SPARQL endpoints allow extra key value pairs. E.g., in virtuoso, one would add C{should-sponge=soft} to the query forcing virtuoso to retrieve graphs that are not stored in its local database. @param name: name @type name: string @param value: value @type value: string @rtype: bool """ if name in _SPARQL_PARAMS: return False else: if name not in self.parameters: self.parameters[name] = [] self.parameters[name].append(value) return True def clearParameter(self, name): """ Clear the values ofd a concrete parameter. @param name: name @type name: string @rtype: bool """ if name in _SPARQL_PARAMS: return False else: try: del self.parameters[name] return True except KeyError: return False def setCredentials(self, user, passwd): """ Set the credentials for querying the current endpoint @param user: username @type user: string @param passwd: password @type passwd: string """ self.user = user self.passwd = passwd def setQuery(self, query): """ Set the SPARQL query text. Note: no check is done on the validity of the query (syntax or otherwise) by this module, except for testing the query type (SELECT, ASK, etc). Syntax and validity checking is done by the SPARQL service itself. @param query: query text @type query: string @bug: #2320024 """ if sys.version < '3': # have to write it like this, for 2to3 compatibility if isinstance(query, unicode): pass elif isinstance(query, str): query = query.decode('utf-8') else: raise TypeError('setQuery takes either unicode-strings or utf-8 encoded byte-strings') else: if isinstance(query, str): pass elif isinstance(query, bytes): query = query.decode('utf-8') else: raise TypeError('setQuery takes either unicode-strings or utf-8 encoded byte-strings') self.queryString = query self.queryType = self._parseQueryType(query) def _parseQueryType(self,query): """ Parse the SPARQL query and return its type (ie, L{SELECT}, L{ASK}, etc). Note that the method returns L{SELECT} if nothing is specified. This is just to get all other methods running; in fact, this means that the query is erronous, because the query must be, according to the SPARQL specification, one of Select, Ask, Describe, or Construct. The SPARQL endpoint should raise an exception (via urllib) for such syntax error. @param query: query text @type query: string @rtype: string """ try: query = query if type(query)==str else query.encode('ascii', 'ignore') query = re.sub(re.compile("#.*?\n" ), "" , query) # remove all occurance singleline comments (issue #32) r_queryType = self.pattern.search(query).group("queryType").upper() except AttributeError: warnings.warn("not detected query type for query '%s'" % query.replace("\n", " "), RuntimeWarning) r_queryType = None if r_queryType in _allowedQueryTypes : return r_queryType else : #raise Exception("Illegal SPARQL Query; must be one of SELECT, ASK, DESCRIBE, or CONSTRUCT") warnings.warn("unknown query type '%s'" % r_queryType, RuntimeWarning) return SELECT def setMethod(self,method): """Set the invocation method. By default, this is L{GET}, but can be set to L{POST}. @param method: should be either L{GET} or L{POST}. Other cases are ignored. """ if method in _allowedRequests : self.method = method def setUseKeepAlive(self): """Make urllib2 use keep-alive. @raise ImportError: when could not be imported urlgrabber.keepalive.HTTPHandler """ try: from urlgrabber.keepalive import HTTPHandler keepalive_handler = HTTPHandler() opener = urllib2.build_opener(keepalive_handler) urllib2.install_opener(opener) except ImportError: warnings.warn("urlgrabber not installed in the system. The execution of this method has no effect.") def isSparqlUpdateRequest(self): """ Returns TRUE if SPARQLWrapper is configured for executing SPARQL Update request @return: bool """ return self.queryType in [INSERT, DELETE, CREATE, CLEAR, DROP, LOAD, COPY, MOVE, ADD] def isSparqlQueryRequest(self): """ Returns TRUE if SPARQLWrapper is configured for executing SPARQL Query request @return: bool """ return not self.isSparqlUpdateRequest() def _getRequestEncodedParameters(self, query=None): query_parameters = self.parameters.copy() if query and type(query) == tuple and len(query) == 2: #tuple ("query"/"update", queryString) query_parameters[query[0]] = [query[1]] # This is very ugly. The fact is that the key for the choice of the output format is not defined. # Virtuoso uses 'format',sparqler uses 'output' # However, these processors are (hopefully) oblivious to the parameters they do not understand. # So: just repeat all possibilities in the final URI. UGLY!!!!!!! for f in _returnFormatSetting: query_parameters[f] = [self.returnFormat] pairs = ( "%s=%s" % ( urllib.quote_plus(param.encode('UTF-8'), safe='/'), urllib.quote_plus(value.encode('UTF-8'), safe='/') ) for param, values in query_parameters.items() for value in values ) return '&'.join(pairs) def _getAcceptHeader(self): if self.queryType in [SELECT, ASK]: if self.returnFormat == XML: acceptHeader = ",".join(_SPARQL_XML) elif self.returnFormat == JSON: acceptHeader = ",".join(_SPARQL_JSON) else: acceptHeader = ",".join(_ALL) elif self.queryType in [INSERT, DELETE]: acceptHeader = "*/*" else: if self.returnFormat == N3 or self.returnFormat == TURTLE: acceptHeader = ",".join(_RDF_N3) elif self.returnFormat == XML: acceptHeader = ",".join(_RDF_XML) elif self.returnFormat == JSONLD and JSONLD in _allowedFormats: acceptHeader = ",".join(_RDF_JSONLD) else: acceptHeader = ",".join(_ALL) return acceptHeader def _createRequest(self): """Internal method to create request according a HTTP method. Returns a C{urllib2.Request} object of the urllib2 Python library @return: request """ request = None if self.isSparqlUpdateRequest(): #protocol details at http://www.w3.org/TR/sparql11-protocol/#update-operation uri = self.updateEndpoint if self.method != POST: warnings.warn("update operations MUST be done by POST") if self.requestMethod == POSTDIRECTLY: request = urllib2.Request(uri + "?" + self._getRequestEncodedParameters()) request.add_header("Content-Type", "application/sparql-update") request.data = self.queryString.encode('UTF-8') else: # URL-encoded request = urllib2.Request(uri) request.add_header("Content-Type", "application/x-www-form-urlencoded") request.data = self._getRequestEncodedParameters(("update", self.queryString)).encode('ascii') else: #protocol details at http://www.w3.org/TR/sparql11-protocol/#query-operation uri = self.endpoint if self.method == POST: if self.requestMethod == POSTDIRECTLY: request = urllib2.Request(uri + "?" + self._getRequestEncodedParameters()) request.add_header("Content-Type", "application/sparql-query") request.data = self.queryString.encode('UTF-8') else: # URL-encoded request = urllib2.Request(uri) request.add_header("Content-Type", "application/x-www-form-urlencoded") request.data = self._getRequestEncodedParameters(("query", self.queryString)).encode('ascii') else: # GET request = urllib2.Request(uri + "?" + self._getRequestEncodedParameters(("query", self.queryString))) request.add_header("User-Agent", self.agent) request.add_header("Accept", self._getAcceptHeader()) if self.user and self.passwd: credentials = "%s:%s" % (self.user, self.passwd) request.add_header("Authorization", "Basic %s" % base64.encodestring(credentials.encode('utf-8'))) return request def _query(self): """Internal method to execute the query. Returns the output of the C{urllib2.urlopen} method of the standard Python library @return: tuples with the raw request plus the expected format """ if self.timeout: socket.setdefaulttimeout(self.timeout) request = self._createRequest() try: response = urlopener(request) return response, self.returnFormat except urllib2.HTTPError, e: if e.code == 400: raise QueryBadFormed(e.read()) elif e.code == 404: raise EndPointNotFound(e.read()) elif e.code == 500: raise EndPointInternalError(e.read()) else: raise e def query(self): """ Execute the query. Exceptions can be raised if either the URI is wrong or the HTTP sends back an error (this is also the case when the query is syntactically incorrect, leading to an HTTP error sent back by the SPARQL endpoint). The usual urllib2 exceptions are raised, which therefore cover possible SPARQL errors, too. Note that some combinations of return formats and query types may not make sense. For example, a SELECT query with Turtle response is meaningless (the output of a SELECT is not a Graph), or a CONSTRUCT query with JSON output may be a problem because, at the moment, there is no accepted JSON serialization of RDF (let alone one implemented by SPARQL endpoints). In such cases the returned media type of the result is unpredictable and may differ from one SPARQL endpoint implementation to the other. (Endpoints usually fall back to one of the "meaningful" formats, but it is up to the specific implementation to choose which one that is.) @return: query result @rtype: L{QueryResult} instance """ return QueryResult(self._query()) def queryAndConvert(self): """Macro like method: issue a query and return the converted results. @return: the converted query result. See the conversion methods for more details. """ res = self.query() return res.convert() ####################################################################################################### class QueryResult(object): """ Wrapper around an a query result. Users should not create instances of this class, it is generated by a L{SPARQLWrapper.query} call. The results can be converted to various formats, or used directly. If used directly: the class gives access to the direct http request results L{self.response}: it is a file-like object with two additional methods: C{geturl()} to return the URL of the resource retrieved and C{info()} that returns the meta-information of the HTTP result as a dictionary-like object (see the urllib2 standard library module of Python). For convenience, these methods are also available on the instance. The C{__iter__} and C{next} methods are also implemented (by mapping them to L{self.response}). This means that the common idiom:: for l in obj : do_something_with_line(l) would work, too. @ivar response: the direct HTTP response; a file-like object, as return by the C{urllib2.urlopen} library call. """ def __init__(self,result): """ @param result: HTTP response stemming from a L{SPARQLWrapper.query} call, or a tuple with the expected format: (response,format) """ if (type(result) == tuple): self.response = result[0] self.requestedFormat = result[1] else: self.response = result """Direct response, see class comments for details""" def geturl(self): """Return the URI of the original call. @return: URI @rtype: string """ return self.response.geturl() def info(self): """Return the meta-information of the HTTP result. @return: meta information @rtype: dictionary """ return KeyCaseInsensitiveDict(self.response.info()) def __iter__(self): """Return an iterator object. This method is expected for the inclusion of the object in a standard C{for} loop. """ return self.response.__iter__() def next(self): """Method for the standard iterator.""" return self.response.next() @staticmethod def setJSONModule(module): """Set the Python module for encoding JSON data. If not an allowed value, the setting is ignored. JSON modules supported: - ``simplejson``: http://code.google.com/p/simplejson/ - ``cjson``: http://pypi.python.org/pypi/python-cjson - ``json``: This is the version of ``simplejson`` that is bundled with the Python standard library since version 2.6 (see http://docs.python.org/library/json.html) @param module: Possible values: are L{simplejson}, L{cjson}, L{json}. All other cases raise a ValueError exception. @type module: string """ jsonlayer.use(module) def _convertJSON(self): """ Convert a JSON result into a Python dict. This method can be overwritten in a subclass for a different conversion method. @return: converted result @rtype: Python dictionary """ return jsonlayer.decode(self.response.read().decode("utf-8")) def _convertXML(self): """ Convert an XML result into a Python dom tree. This method can be overwritten in a subclass for a different conversion method. @return: converted result @rtype: PyXlib DOM node """ from xml.dom.minidom import parse return parse(self.response) def _convertRDF(self): """ Convert a RDF/XML result into an RDFLib triple store. This method can be overwritten in a subclass for a different conversion method. @return: converted result @rtype: RDFLib Graph """ try: from rdflib.graph import ConjunctiveGraph except ImportError: from rdflib import ConjunctiveGraph retval = ConjunctiveGraph() # this is a strange hack. If the publicID is not set, rdflib (or the underlying xml parser) makes a funny #(and, as far as I could see, meaningless) error message... retval.load(self.response, publicID=' ') return retval def _convertN3(self): """ Convert a RDF Turtle/N3 result into a string. This method can be overwritten in a subclass for a different conversion method. @return: converted result @rtype: string """ return self.response.read() def _convertJSONLD(self): """ Convert a RDF JSON-LDresult into an RDFLib triple store. This method can be overwritten in a subclass for a different conversion method. @return: converted result @rtype: RDFLib Graph """ from rdflib import ConjunctiveGraph retval = ConjunctiveGraph() retval.load(self.response, format='json-ld', publicID=' ') return retval def convert(self): """ Encode the return value depending on the return format: - in the case of XML, a DOM top element is returned; - in the case of JSON, a simplejson conversion will return a dictionary; - in the case of RDF/XML, the value is converted via RDFLib into a Graph instance. In all other cases the input simply returned. @return: the converted query result. See the conversion methods for more details. """ def _content_type_in_list(real, expected): return True in [real.find(mime) != -1 for mime in expected] def _validate_format(format_name, allowed, mime, requested): if requested not in allowed: message = "Format requested was %s, but %s (%s) has been returned by the endpoint" warnings.warn(message % (requested.upper(), format_name, mime), RuntimeWarning) if "content-type" in self.info(): ct = self.info()["content-type"] if _content_type_in_list(ct, _SPARQL_XML): _validate_format("XML", [XML], ct, self.requestedFormat) return self._convertXML() elif _content_type_in_list(ct, _SPARQL_JSON): _validate_format("JSON", [JSON], ct, self.requestedFormat) return self._convertJSON() elif _content_type_in_list(ct, _RDF_XML): _validate_format("RDF/XML", [RDF, XML], ct, self.requestedFormat) return self._convertRDF() elif _content_type_in_list(ct, _RDF_N3): _validate_format("N3", [N3, TURTLE], ct, self.requestedFormat) return self._convertN3() elif _content_type_in_list(ct, _RDF_JSONLD): _validate_format("JSON(-LD)", [JSONLD, JSON], ct, self.requestedFormat) return self._convertJSONLD() warnings.warn("unknown response content type, returning raw response...", RuntimeWarning) return self.response.read() def print_results(self, minWidth=None): results = self._convertJSON() if minWidth : width = self.__get_results_width(results, minWidth) else : width = self.__get_results_width(results) index = 0 for var in results["head"]["vars"] : print ("?" + var).ljust(width[index]),"|", index += 1 print print "=" * (sum(width) + 3 * len(width)) for result in results["results"]["bindings"] : index = 0 for var in results["head"]["vars"] : print result[var]["value"].ljust(width[index]),"|", index += 1 print def __get_results_width(self, results, minWidth=2): width = [] for var in results["head"]["vars"] : width.append(max(minWidth, len(var)+1)) for result in results["results"]["bindings"] : index = 0 for var in results["head"]["vars"] : width[index] = max(width[index], len(result[var]["value"])) index =+ 1 return width SPARQLWrapper-1.6.4/SPARQLWrapper/__init__.py0000644000175000017500000002171312377101546021355 0ustar sergiosergio00000000000000# -*- coding: utf8 -*- u""" This is a wrapper around a SPARQL service. It helps in creating the query URI and, possibly, convert the result into a more managable format. The following packages are used: - for JSON, the U{simplejson} package: C{http://cheeseshop.python.org/pypi/simplejson} - for RDF/XML, the U{RDFLib}: C{http://rdflib.net} These packages are imported in a lazy fashion, ie, only when needed. Ie, if the user never intends to use the JSON format, the C{simplejson} package is not imported and the user does not have to install it. The package can be downloaded in C{zip} and C{.tar.gz} formats from U{http://www.ivan-herman.net/Misc/PythonStuff/SPARQL/}. It is also available from U{Sourceforge} under the project named "C{sparql-wrapper}". Documentation is included in the distribution. Basic QUERY Usage ================= Simple query ------------ The simplest usage of this module looks as follows (using the default, ie, U{XML return format}, and special URI for the SPARQL Service):: from SPARQLWrapper import SPARQLWrapper queryString = "SELECT * WHERE { ?s ?p ?o. }" sparql = SPARQLWrapper("http://localhost:2020/sparql") # add a default graph, though that can also be part of the query string sparql.addDefaultGraph("http://www.example.com/data.rdf") sparql.setQuery(queryString) try : ret = sparql.query() # ret is a stream with the results in XML, see except : deal_with_the_exception() If C{SPARQLWrapper("http://localhost:2020/sparql",returnFormat=SPARQLWrapper.JSON)} was used, the result would be in U{JSON format} instead of XML (provided the sparql processor can return JSON). Automatic conversion of the results ----------------------------------- To make processing somewhat easier, the package can do some conversions automatically from the return result. These are: - for XML, the U{xml.dom.minidom} (C{http://docs.python.org/library/xml.dom.minidom.html}) is used to convert the result stream into a Python representation of a DOM tree - for JSON, the U{simplejson} package (C{http://cheeseshop.python.org/pypi/simplejson}) to generate a Python dictionary There are two ways to generate this conversion: - use C{ret.convert()} in the return result from C{sparql.query()} in the code above - use C{sparql.queryAndConvert()} to get the converted result right away if the intermediate stream is not used For example, in the code below:: try : sparql.setReturnFormat(SPARQLWrapper.JSON) ret = sparql.query() dict = ret.convert() except: deal_with_the_exception() the value of C{dict} is a Python dictionary of the query result, based on the U{JSON format}. The L{SPARQLWrapper} class can be subclassed by overriding the conversion routines if the user wants to use something else. Partial interpretation of the results ------------------------------------- A further help is to offer an extra, partial interpretation of the results, again to cover most of the practical use cases. Based on the U{JSON format}, the L{SmartWrapper.Bindings} class can perform some simple steps in decoding the JSON return results. If L{SPARQLWrapper2} is used instead of L{SPARQLWrapper}, this result format is generated. Note that this relies on a JSON format only, ie, it has to be checked whether the SPARQL service can return JSON or not. Here is a simple code that makes use of this feature:: from SPARQLWrapper import SPARQLWrapper2 queryString = "SELECT ?subj ?prop WHERE { ?subj ?prop ?o. }" sparql = SPARQLWrapper2("http://localhost:2020/sparql") # add a default graph, though that can also be in the query string sparql.addDefaultGraph("http://www.example.com/data.rdf") sparql.setQuery(queryString) try : ret = sparql.query() print ret.variables # this is an array consisting of "subj" and "prop" for binding in ret.bindings : # each binding is a dictionary. Let us just print the results print "%s: %s (of type %s)" % ("s",binding[u"subj"].value,binding[u"subj"].type) print "%s: %s (of type %s)" % ("p",binding[u"prop"].value,binding[u"prop"].type) except: deal_with_the_exception() To make this type of code even easier to realize, the C{[]} and C{in} operators are also implemented on the result of L{SmartWrapper.Bindings}. This can be used to check and find a particular binding (ie, particular row in the return value). This features becomes particularly useful when the C{OPTIONAL} feature of SPARQL is used. For example:: from SPARQLWrapper import SPARQLWrapper2 queryString = "SELECT ?subj ?o ?opt WHERE { ?subj ?o. OPTIONAL { ?subj ?opt }}" sparql = SPARQLWrapper2("http://localhost:2020/sparql") # add a default graph, though that can also be in the query string sparql.addDefaultGraph("http://www.example.com/data.rdf") sparql.setQuery(queryString) try : ret = sparql.query() print ret.variables # this is an array consisting of "subj", "o", "opt" if (u"subj",u"prop",u"opt") in ret : # there is at least one binding covering the optional "opt", too bindings = ret[u"subj",u"o",u"opt"] # bindings is an array of dictionaries with the full bindings for b in bindings : subj = b[u"subj"].value o = b[u"o"].value opt = b[u"opt"].value # do something nice with subj, o, and opt # another way of accessing to values for a single variable: # take all the bindings of the "subj" subjbind = ret.getValues(u"subj") # an array of Value instances ... except: deal_with_the_exception() CONSTRUCT, ASK, DESCRIBE ======================== All the examples so far were based on the SELECT queries. If the query includes, eg, the C{CONSTRUCT} keyword then the accepted return formats should be different: eg, C{SPARQLWrapper.XML} means C{RDF/XML} and most of the SPARQL engines can also return the results in C{Turtle}. The package, though it does not contain a full SPARQL parser, makes an attempt to determine the query type when the query is set. This should work in most of the cases (but there is a possibility to set this manually, in case something goes wrong). For RDF/XML, the U{RDFLib} (C{http://rdflib.net}) package is used to convert the result into a C{Graph} instance. GET or POST =========== By default, all SPARQL services are invoked using HTTP GET. However, POST might be useful if the size of the query extends a reasonable size; this can be set in the query instance. Note that some combination may not work yet with all SPARQL processors (eg, there are implementations where POST+JSON return does not work). Hopefully, this problem will eventually disappear. Note that SPARQLWrapper only supports nowadays query using POST via URL-encoded. Acknowledgement =============== The package was greatly inspired by U{Lee Feigenbaum's similar package for Javascript}. @summary: Python interface to SPARQL services @see: U{SPARQL Specification} @authors: U{Ivan Herman}, U{Sergio Fernández}, U{Carlos Tejo Alonso} @organization: U{World Wide Web Consortium}, U{Salzburg Research} and U{Foundation CTIC}. @license: U{W3C® SOFTWARE NOTICE AND LICENSE} @requires: U{simplejson} package. @requires: U{RDFLib} package. """ __version__ = "1.6.4" """The version of SPARQLWrapper""" __authors__ = "Ivan Herman, Sergio Fernández, Carlos Tejo Alonso, Alexey Zakhlestin" """The primary authors of SPARQLWrapper""" __license__ = "W3C® SOFTWARE NOTICE AND LICENSE, http://www.w3.org/Consortium/Legal/copyright-software" """The license governing the use and distribution of SPARQLWrapper""" __url__ = "http://rdflib.github.io/sparqlwrapper" """The URL for SPARQLWrapper's homepage""" __contact__ = "rdflib-dev@googlegroups.com" """Mail list to contact to other people RDFLib and SPARQLWrappers folks and developers""" __date__ = "2014-08-26" """Last update""" __agent__ = "sparqlwrapper %s (rdflib.github.io/sparqlwrapper)" % __version__ from Wrapper import SPARQLWrapper from Wrapper import XML, JSON, TURTLE, N3, JSONLD, RDF from Wrapper import GET, POST from Wrapper import SELECT, CONSTRUCT, ASK, DESCRIBE, INSERT, DELETE from Wrapper import URLENCODED, POSTDIRECTLY from SmartWrapper import SPARQLWrapper2 SPARQLWrapper-1.6.4/SPARQLWrapper/KeyCaseInsensitiveDict.py0000644000175000017500000000211112377047077024166 0ustar sergiosergio00000000000000# -*- coding: utf-8 -*- """ A simple implementation of a key case-insensitive dictionary. @authors: U{Ivan Herman}, U{Sergio Fernández}, U{Carlos Tejo Alonso} @organization: U{World Wide Web Consortium} and U{Foundation CTIC}. @license: U{W3C® SOFTWARE NOTICE AND LICENSE} """ class KeyCaseInsensitiveDict(dict): """ A simple implementation of a key case-insensitive dictionary """ def __init__(self, d={}): for k, v in d.items(): self[k] = v def __setitem__(self, key, value): if (hasattr(key, "lower")): key = key.lower() dict.__setitem__(self, key, value) def __getitem__(self, key): if (hasattr(key, "lower")): key = key.lower() return dict.__getitem__(self, key) def __delitem__(self, key): if hasattr(key, "lower"): key = key.lower() dict.__delitem__(self, key) SPARQLWrapper-1.6.4/SPARQLWrapper/SmartWrapper.py0000644000175000017500000003110112377047077022245 0ustar sergiosergio00000000000000# -*- coding: utf-8 -*- """ @see: U{SPARQL Specification} @authors: U{Ivan Herman}, U{Sergio Fernández}, U{Carlos Tejo Alonso} @organization: U{World Wide Web Consortium} and U{Foundation CTIC}. @license: U{W3C® SOFTWARE NOTICE AND LICENSE} @requires: U{RDFLib} package. """ import SPARQLWrapper from SPARQLWrapper.Wrapper import JSON, SELECT import urllib2 from types import * ###################################################################################### class Value(object): """ Class encapsulating a single binding for a variable. @cvar URI: the string denoting a URI variable @cvar Literal: the string denoting a Literal variable @cvar TypedLiteral: the string denoting a typed literal variable @cvar BNODE: the string denoting a blank node variable @ivar variable: The original variable, stored for an easier reference @type variable: string @ivar value: Value of the binding @type value: string @ivar type: Type of the binding @type type: string; one of L{Value.URI}, L{Value.Literal}, L{Value.TypedLiteral}, or L{Value.BNODE} @ivar lang: Language tag of the binding, or C{None} if not set @type lang: string @ivar datatype: Datatype of the binding, or C{None} if not set @type datatype: string (URI) """ URI = "uri" Literal = "literal" TypedLiteral = "typed-literal" BNODE = "bnode" def __init__(self,variable,binding) : """ @param variable: the variable for that binding. Stored for an easier reference @param binding: the binding dictionary part of the return result for a specific binding """ self.variable = variable self.value = binding['value'] self.type = binding['type'] self.lang = None self.datatype = None try : self.lang = binding['xml:lang'] except : # no lang is set pass try : self.datatype = binding['datatype'] except : pass ###################################################################################### class Bindings(object): """ Class encapsulating one query result, based on the JSON return format. It decodes the return values to make it a bit more usable for a standard usage. The class consumes the return value and instantiates a number of attributes that can be consulted directly. See the list of variables. The U{Serializing SPARQL Query Results in JSON} explains the details of the JSON return structures. Very succintly: the return data has "bindings", which means a list of dictionaries. Each dictionary is a possible binding of the SELECT variables to L{Value} instances. This structure is made a bit more usable by this class. @ivar fullResult: The original dictionary of the results, stored for an easier reference @ivar head: Header part of the return, see the JSON return format document for details @ivar variables: List of unbounds (variables) of the original query. It is an array of strings. None in the case of an ASK query @ivar bindings: The final bindings: array of dictionaries, mapping variables to L{Value} instances. (If unbound, then no value is set in the dictionary; that can be easily checked with C{var in res.bindings[..]}, for example.) @ivar askResult: by default, set to False; in case of an ASK query, the result of the query @type askResult: Boolean """ def __init__(self,retval) : """ @param retval: the query result, instance of a L{Wrapper.QueryResult} """ self.fullResult = retval._convertJSON() self.head = self.fullResult['head'] self.variables = None try : self.variables = self.fullResult['head']['vars'] except : pass self.bindings = [] try : for b in self.fullResult['results']['bindings'] : # this is a single binding. It is a dictionary per variable; each value is a dictionary again that has to be # converted into a Value instance newBind = {} for key in self.variables : if key in b : # there is a real binding for this key newBind[key] = Value(key,b[key]) self.bindings.append(newBind) except : pass self.askResult = False try : self.askResult = self.fullResult["boolean"] except : pass def getValues(self,key) : """A shorthand for the retrieval of all bindings for a single key. It is equivalent to "C{[b[key] for b in self[key]]}" @param key: possible variable @return: list of L{Value} instances """ try : return [b[key] for b in self[key]] except : return [] def __contains__(self,key) : """Emulation of the "C{key in obj}" operator. Key can be a string for a variable or an array/tuple of strings. If C{key} is a variable, the return value is C{True} if there is at least one binding where C{key} is bound. If C{key} is an array or tuple, the return value is C{True} if there is at least one binding where I{all} variables in C{key} are bound. @param key: possible variable, or array/tuple of variables @return: whether there is a binding of the variable in the return @rtype: Boolean """ if len(self.bindings) == 0 : return False if type(key) is list or type(key) is tuple: # check first whether they are all really variables if False in [ k in self.variables for k in key ]: return False for b in self.bindings : # try to find a binding where all key elements are present if False in [ k in b for k in key ] : # this is not a binding for the key combination, move on... continue else : # yep, this one is good! return True return False else : if key not in self.variables : return False for b in self.bindings : if key in b : return True return False def __getitem__(self,key) : """Emulation of the C{obj[key]} operator. Slice notation is also available. The goal is to choose the right bindings among the available ones. The return values are always arrays of bindings, ie, arrays of dictionaries mapping variable keys to L{Value} instances. The different value settings mean the followings: - C{obj[key]} returns the bindings where C{key} has a valid value - C{obj[key1,key2,...]} returns the bindings where I{all} C{key1,key2,...} have valid values - C{obj[(key1,key2,...):(nkey1,nkey2,...)]} returns the bindings where all C{key1,key2,...} have valid values and I{none} of the C{nkey1,nkey2,...} have valid values - C{obj[:(nkey1,nkey2,...)]} returns the bindings where I{none} of the C{nkey1,nkey2,...} have valid values In all cases complete bindings are returned, ie, the values for other variables, not present among the keys in the call, may or may not be present depending on the query results. @param key: possible variable or array/tuple of keys with possible slice notation @return: list of bindings @rtype: array of variable -> L{Value} dictionaries """ def _checkKeys(keys) : if len(keys) == 0 : return False for k in keys : if not isinstance(k, basestring) or not k in self.variables: return False return True def _nonSliceCase(key) : if isinstance(key, basestring) and key != "" and key in self.variables : # unicode or string: return [key] elif type(key) is list or type(key) is tuple: if _checkKeys(key) : return key return False # The arguments should be reduced to arrays of variables, ie, unicode strings yes_keys = [] no_keys = [] if type(key) is slice : # Note: None for start or stop is all right if key.start : yes_keys = _nonSliceCase(key.start) if not yes_keys: raise TypeError if key.stop : no_keys = _nonSliceCase(key.stop) if not no_keys: raise TypeError else : yes_keys = _nonSliceCase(key) # got it right, now get the right binding line with the constraints retval = [] for b in self.bindings : # first check whether the 'yes' part is all there: if False in [k in b for k in yes_keys] : continue if True in [k in b for k in no_keys] : continue # if we got that far, we shouild be all right! retval.append(b) # if retval is of zero length, no hit; an exception should be raised to stay within the python style if len(retval) == 0 : raise IndexError return retval def convert(self) : """This is just a convenience method, returns C{self}. Although C{Binding} is not a subclass of L{QueryResult}, it is returned as a result by L{SPARQLWrapper2.query}, just like L{QueryResult} is returned by L{SPARQLWrapper.SPARQLWrapper.query}. Consequently, having an empty C{convert} method to imitate L{QueryResult's convert method} may avoid unnecessary problems. """ return self ############################################################################################################## class SPARQLWrapper2(SPARQLWrapper.SPARQLWrapper): """Subclass of L{Wrapper} that works with a JSON SELECT return result only. The query result is automatically set to a L{Bindings} instance. Makes the average query processing a bit simpler...""" def __init__(self, baseURI, defaultGraph=None): """ Class encapsulating a full SPARQL call. In contrast to the L{SPARQLWrapper} superclass, the return format cannot be set (it is defaulted to L{JSON}). @param baseURI: string of the SPARQL endpoint's URI @type baseURI: string @keyword defaultGraph: URI for the default graph. Default is None, can be set via an explicit call, too @type defaultGraph: string """ super(SPARQLWrapper2, self).__init__(baseURI, returnFormat=JSON, defaultGraph=defaultGraph) def setReturnFormat(self, format): """Set the return format (overriding the L{inherited method}). This method does nothing; this class instance should work with JSON only. The method is defined just to avoid possible errors by erronously setting the return format. When using this class, the user can safely ignore this call. @param format: return format """ pass def query(self): """ Execute the query and do an automatic conversion. Exceptions can be raised if either the URI is wrong or the HTTP sends back an error. The usual urllib2 exceptions are raised, which cover possible SPARQL errors, too. If the query type is I{not} SELECT, the method falls back to the L{corresponding method in the superclass}. @return: query result @rtype: L{Bindings} instance """ res = super(SPARQLWrapper2, self).query() if self.queryType == SELECT: return Bindings(res) else: return res def queryAndConvert(self): """This is here to override the inherited method; it is equivalent to L{query}. If the query type is I{not} SELECT, the method falls back to the L{corresponding method in the superclass}. @return: the converted query result. """ if self.queryType == SELECT: return self.query() else: return super(SPARQLWrapper2, self).queryAndConvert() SPARQLWrapper-1.6.4/SPARQLWrapper/SPARQLUtils.py0000644000175000017500000000200312377047077021640 0ustar sergiosergio00000000000000# -*- coding: utf8 -*- """ SPARQL Wrapper Utils @authors: U{Ivan Herman}, U{Sergio Fernández}, U{Carlos Tejo Alonso} @organization: U{World Wide Web Consortium} and U{Foundation CTIC}. @license: U{W3C SOFTWARE NOTICE AND LICENSE} """ import warnings def deprecated(func): """ This is a decorator which can be used to mark functions as deprecated. It will result in a warning being emmitted when the function is used. @see: http://code.activestate.com/recipes/391367/ """ def newFunc(*args, **kwargs): warnings.warn("Call to deprecated function %s." % func.__name__, category=DeprecationWarning, stacklevel=2) return func(*args, **kwargs) newFunc.__name__ = func.__name__ newFunc.__doc__ = func.__doc__ newFunc.__dict__.update(func.__dict__) return newFunc SPARQLWrapper-1.6.4/SPARQLWrapper/jsonlayer.py0000644000175000017500000001303312377047077021630 0ustar sergiosergio00000000000000# -*- coding: utf-8 -*- # # Copyright (C) 2009 Christopher Lenz # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # 1. Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # 3. The name of the author may not be used to endorse or promote # products derived from this software without specific prior # written permission. # THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS # OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE # GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER # IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN # IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. """Thin abstraction layer over the different available modules for decoding and encoding JSON data. This module currently supports the following JSON modules: - ``simplejson``: http://code.google.com/p/simplejson/ - ``cjson``: http://pypi.python.org/pypi/python-cjson - ``json``: This is the version of ``simplejson`` that is bundled with the Python standard library since version 2.6 (see http://docs.python.org/library/json.html) The default behavior is to use ``simplejson`` if installed, and otherwise fallback to the standard library module. To explicitly tell SPARQLWrapper which module to use, invoke the `use()` function with the module name:: import jsonlayer jsonlayer.use('cjson') In addition to choosing one of the above modules, you can also configure SPARQLWrapper to use custom decoding and encoding functions:: import jsonlayer jsonlayer.use(decode=my_decode, encode=my_encode) """ __all__ = ['decode', 'encode', 'use'] _initialized = False _using = None _decode = None _encode = None def decode(string): """Decode the given JSON string. :param string: the JSON string to decode :type string: basestring :return: the corresponding Python data structure :rtype: object """ if not _initialized: _initialize() return _decode(string) def encode(obj): """Encode the given object as a JSON string. :param obj: the Python data structure to encode :type obj: object :return: the corresponding JSON string :rtype: basestring """ if not _initialized: _initialize() return _encode(obj) def use(module=None, decode=None, encode=None): """Set the JSON library that should be used, either by specifying a known module name, or by providing a decode and encode function. The modules "simplejson", "cjson", and "json" are currently supported for the ``module`` parameter. If provided, the ``decode`` parameter must be a callable that accepts a JSON string and returns a corresponding Python data structure. The ``encode`` callable must accept a Python data structure and return the corresponding JSON string. Exceptions raised by decoding and encoding should be propagated up unaltered. :param module: the name of the JSON library module to use, or the module object itself :type module: str or module :param decode: a function for decoding JSON strings :type decode: callable :param encode: a function for encoding objects as JSON strings :type encode: callable """ global _decode, _encode, _initialized, _using if module is not None: if not isinstance(module, basestring): module = module.__name__ if module not in ('cjson', 'json', 'simplejson'): raise ValueError('Unsupported JSON module %s' % module) _using = module _initialized = False else: assert decode is not None and encode is not None _using = 'custom' _decode = decode _encode = encode _initialized = True def _initialize(): global _initialized def _init_simplejson(): global _decode, _encode import simplejson _decode = lambda string, loads=simplejson.loads: loads(string) _encode = lambda obj, dumps=simplejson.dumps: \ dumps(obj, allow_nan=False, ensure_ascii=False) def _init_cjson(): global _decode, _encode import cjson _decode = lambda string, decode=cjson.decode: decode(string) _encode = lambda obj, encode=cjson.encode: encode(obj) def _init_stdlib(): global _decode, _encode json = __import__('json', {}, {}) _decode = lambda string, loads=json.loads: loads(string) _encode = lambda obj, dumps=json.dumps: \ dumps(obj, allow_nan=False, ensure_ascii=False) if _using == 'simplejson': _init_simplejson() elif _using == 'cjson': _init_cjson() elif _using == 'json': _init_stdlib() elif _using != 'custom': try: _init_simplejson() except ImportError: _init_stdlib() _initialized = True SPARQLWrapper-1.6.4/setup.py0000755000175000017500000000513112377071336016415 0ustar sergiosergio00000000000000# -*- coding: utf-8 -*- import sys try: from ez_setup import use_setuptools use_setuptools() except: pass from setuptools import setup, find_packages try: import six py3 = six.PY3 except: py3 = sys.version_info[0] >= 3 # grouping requires _requires = [] _install_requires = [] # rdflib _requires.append('rdflib') _install_requires.append('rdflib >= 2.4.2') # simplejson if sys.version_info[0:2] < (2, 6): _requires.append('simplejson') _install_requires.append('simplejson == 2.0.9') # metainformation if py3: import re _version_re = re.compile(r'__version__\s*=\s*"(.*)"') _authors_re = re.compile(r'__authors__\s*=\s*"(.*)"') _url_re = re.compile(r'__url__\s*=\s*"(.*)"') for line in open('SPARQLWrapper/__init__.py', encoding='utf-8'): version_match = _version_re.match(line) if version_match: version = version_match.group(1) authors_match = _authors_re.match(line) if authors_match: authors = authors_match.group(1) url_match = _url_re.match(line) if url_match: url = url_match.group(1) else: import SPARQLWrapper version = SPARQLWrapper.__version__ authors = SPARQLWrapper.__authors__ url = SPARQLWrapper.__url__ # actual setup configuration setup( name = 'SPARQLWrapper', version = version, description = 'SPARQL Endpoint interface to Python', long_description = 'This is a wrapper around a SPARQL service. It helps in creating the query URI and, possibly, convert the result into a more manageable format.', license = 'W3C SOFTWARE NOTICE AND LICENSE', # should be removed by PEP 314 author = authors, author_email = "ivan at ivan-herman net, sergio at wikier org, carlos.tejo at gmail com, indeyets at gmail com", url = url, download_url = 'https://github.com/RDFLib/sparqlwrapper/releases', platforms = ['any'], # should be removed by PEP 314 packages = ['SPARQLWrapper'], requires = _requires, # used by distutils to create metadata PKG-INFO install_requires = _install_requires, # used by setuptools to install the dependencies classifiers = [ 'Development Status :: 5 - Production/Stable', 'Intended Audience :: Developers', 'License :: OSI Approved :: W3C License', 'Operating System :: OS Independent', 'Programming Language :: Python :: 2', 'Programming Language :: Python :: 3', ], keywords = 'python SPARQL', use_2to3 = True, #requires_python = '>=2.5', # Future in PEP 345 #scripts = ['ez_setup.py'] ) SPARQLWrapper-1.6.4/PKG-INFO0000644000175000017500000000166312377101654016000 0ustar sergiosergio00000000000000Metadata-Version: 1.1 Name: SPARQLWrapper Version: 1.6.4 Summary: SPARQL Endpoint interface to Python Home-page: http://rdflib.github.io/sparqlwrapper Author: Ivan Herman, Sergio Fernández, Carlos Tejo Alonso, Alexey Zakhlestin Author-email: ivan at ivan-herman net, sergio at wikier org, carlos.tejo at gmail com, indeyets at gmail com License: W3C SOFTWARE NOTICE AND LICENSE Download-URL: https://github.com/RDFLib/sparqlwrapper/releases Description: This is a wrapper around a SPARQL service. It helps in creating the query URI and, possibly, convert the result into a more manageable format. Keywords: python SPARQL Platform: any Classifier: Development Status :: 5 - Production/Stable Classifier: Intended Audience :: Developers Classifier: License :: OSI Approved :: W3C License Classifier: Operating System :: OS Independent Classifier: Programming Language :: Python :: 2 Classifier: Programming Language :: Python :: 3 Requires: rdflib SPARQLWrapper-1.6.4/MANIFEST.in0000644000175000017500000000010512377047077016437 0ustar sergiosergio00000000000000include *.md exclude Makefile include test/*.py include scripts/*.py SPARQLWrapper-1.6.4/setup.cfg0000644000175000017500000000007312377101654016516 0ustar sergiosergio00000000000000[egg_info] tag_build = tag_date = 0 tag_svn_revision = 0 SPARQLWrapper-1.6.4/MANAGEMENT.md0000644000175000017500000000245212377047077016646 0ustar sergiosergio00000000000000# Management documentation The project keeps a very low-profile on managing, so we try to keep it simple. ## Contributions Every contributor (patchs, pull requests, new features, etc) gets part of ownership by be mentioned as contributor to the project (`AUTHORS.md`). ## Release ### Software The release process is quite simple, just few things have to be done: First, do not forget to update the changelog (`ChangeLog.txt` file). That information could be added later to the release at github. Then you have to [create a release](https://github.com/blog/1547-release-your-software) by tagging the master branch: git tag x.y.z git push --tags And then upload the release to pypi: python setup.py register sdist --formats=gztar,zip bdist_egg upload Please, don't forget to increment to the next module (`SPARQLWrapper/__init__.py` file). ### Documentation In order to provide online documentation, some steps need to be accomplished: 1. First, generate the documentation using [epydoc](http://epydoc.sourceforge.net/) using the makefile make doc 2. And then upload the documentation generated (`doc` folder) to GitHub Pages (`gh-pages` branch). 3. After that, the online version of the documentation would be available on [GitHub Pages](http://rdflib.github.io/sparqlwrapper/resources/doc). SPARQLWrapper-1.6.4/scripts/0000755000175000017500000000000012377101654016364 5ustar sergiosergio00000000000000SPARQLWrapper-1.6.4/scripts/example-optional.py0000644000175000017500000000140012377047077022217 0ustar sergiosergio00000000000000#!/usr/bin/python # -*- coding: utf-8 -*- from SPARQLWrapper import SPARQLWrapper, JSON, XML, N3, RDF sparql = SPARQLWrapper("http://dbpedia.org/sparql") sparql.setQuery(""" PREFIX rdfs: SELECT ?person ?party WHERE { ?person OPTIONAL { ?person ?party } } """) # JSON example print '\n\n*** JSON Example' sparql.setReturnFormat(JSON) results = sparql.query().convert() for result in results["results"]["bindings"]: if result.has_key("party"): print "* " + result["person"]["value"] + " ** " + result["party"]["value"] else: print result["person"]["value"] SPARQLWrapper-1.6.4/scripts/example.py0000644000175000017500000000157712377047077020413 0ustar sergiosergio00000000000000#!/usr/bin/python # -*- coding: utf-8 -*- from SPARQLWrapper import SPARQLWrapper, JSON, XML, N3, RDF sparql = SPARQLWrapper("http://dbpedia.org/sparql") sparql.setQuery(""" PREFIX rdfs: SELECT ?label WHERE { rdfs:label ?label } """) # JSON example print '\n\n*** JSON Example' sparql.setReturnFormat(JSON) results = sparql.query().convert() for result in results["results"]["bindings"]: print result["label"]["value"] # XML example print '\n\n*** XML Example' sparql.setReturnFormat(XML) results = sparql.query().convert() print results.toxml() # N3 example print '\n\n*** N3 Example' sparql.setReturnFormat(N3) results = sparql.query().convert() print results # RDF example print '\n\n*** RDF Example' sparql.setReturnFormat(RDF) results = sparql.query().convert() print results.serialize() SPARQLWrapper-1.6.4/scripts/example-dbpedia.py0000644000175000017500000000136012377047077021767 0ustar sergiosergio00000000000000#!/usr/bin/python # -*- coding: utf-8 -*- from SPARQLWrapper import SPARQLWrapper, JSON sparql = SPARQLWrapper("http://dbpedia.org/sparql") sparql.setQuery(""" PREFIX rdfs: SELECT ?label WHERE { rdfs:label ?label } """) sparql.setReturnFormat(JSON) results = sparql.query() results.print_results() print sparql.setQuery(""" PREFIX rdfs: PREFIX dbpo: SELECT ?subdivision ?label WHERE { dbpo:subdivisionName ?subdivision . ?subdivision rdfs:label ?label . } """) sparql.setReturnFormat(JSON) results = sparql.query() results.print_results() SPARQLWrapper-1.6.4/scripts/sparql.py0000755000175000017500000000437712377047077020266 0ustar sergiosergio00000000000000#!/usr/bin/python # -*- coding: utf-8 -*- from SPARQLWrapper import SPARQLWrapper2, SPARQLWrapper, TURTLE import sys, getopt localSparqler = "http://localhost:2020/sparql" localVirtuoso = "http://localhost:8890/sparql" def main(server,query,sponge=False) : sparql = SPARQLWrapper2(server) if sponge : sparql.addExtraURITag("should-sponge","grab-everything") sparql.setQuery(query) res = sparql.query() variables = res.variables print "Variables:" print variables print print "Bindings:" for b in res.bindings : for v in res.variables : try : val = b[v] if val.lang : str = "%s: %s@%s" % (v,val.value,val.lang) elif val.datatype : str = "%s: %s^^%s" % (v,val.value,val.datatype) else : str = "%s: %s" % (v,val.value) except KeyError : # no binding to that one... str = "%s: <>" % v print str.encode('utf-8') print # ------------------------------------------------------------------------------------------------------------- server = localSparqler query = "" sponge = False usagetxt="""%s [-s] [-u url] [file] -s: use local sparqler (default) -v: use local virtuoso -u url: server url -p: issue an extra sponge for virtuoso file: sparql query file """ def usage() : print usagetxt % sys.argv[0] sys.exit(1) if __name__ == '__main__' : if len(sys.argv) == 1: usage() try : opts,args = getopt.getopt(sys.argv[1:],"shu:pv") for o,a in opts : if o == "-s" : server = localSparqler elif o == "-v" : server = localVirtuoso sponge = True elif o == "-h" : print usage sys.exit(0) elif o == "-u" : server = a elif o == "-p" : sponge = True if query == "" and len(args) > 0 : inp = file(args[0]) query = "" for l in inp : query += l except : usage() if query == "" : usage() main(server,query,sponge) SPARQLWrapper-1.6.4/SPARQLWrapper.egg-info/0000755000175000017500000000000012377101654020732 5ustar sergiosergio00000000000000SPARQLWrapper-1.6.4/SPARQLWrapper.egg-info/PKG-INFO0000644000175000017500000000166312377101641022031 0ustar sergiosergio00000000000000Metadata-Version: 1.1 Name: SPARQLWrapper Version: 1.6.4 Summary: SPARQL Endpoint interface to Python Home-page: http://rdflib.github.io/sparqlwrapper Author: Ivan Herman, Sergio Fernández, Carlos Tejo Alonso, Alexey Zakhlestin Author-email: ivan at ivan-herman net, sergio at wikier org, carlos.tejo at gmail com, indeyets at gmail com License: W3C SOFTWARE NOTICE AND LICENSE Download-URL: https://github.com/RDFLib/sparqlwrapper/releases Description: This is a wrapper around a SPARQL service. It helps in creating the query URI and, possibly, convert the result into a more manageable format. Keywords: python SPARQL Platform: any Classifier: Development Status :: 5 - Production/Stable Classifier: Intended Audience :: Developers Classifier: License :: OSI Approved :: W3C License Classifier: Operating System :: OS Independent Classifier: Programming Language :: Python :: 2 Classifier: Programming Language :: Python :: 3 Requires: rdflib SPARQLWrapper-1.6.4/SPARQLWrapper.egg-info/dependency_links.txt0000644000175000017500000000000112377101641024774 0ustar sergiosergio00000000000000 SPARQLWrapper-1.6.4/SPARQLWrapper.egg-info/top_level.txt0000644000175000017500000000001612377101641023455 0ustar sergiosergio00000000000000SPARQLWrapper SPARQLWrapper-1.6.4/SPARQLWrapper.egg-info/SOURCES.txt0000644000175000017500000000111512377101641022610 0ustar sergiosergio00000000000000AUTHORS.md MANAGEMENT.md MANIFEST.in README.md setup.cfg setup.py SPARQLWrapper/KeyCaseInsensitiveDict.py SPARQLWrapper/SPARQLExceptions.py SPARQLWrapper/SPARQLUtils.py SPARQLWrapper/SmartWrapper.py SPARQLWrapper/Wrapper.py SPARQLWrapper/__init__.py SPARQLWrapper/jsonlayer.py SPARQLWrapper.egg-info/PKG-INFO SPARQLWrapper.egg-info/SOURCES.txt SPARQLWrapper.egg-info/dependency_links.txt SPARQLWrapper.egg-info/requires.txt SPARQLWrapper.egg-info/top_level.txt scripts/example-dbpedia.py scripts/example-optional.py scripts/example.py scripts/sparql.py test/dbpedia.py test/wrapper_test.pySPARQLWrapper-1.6.4/SPARQLWrapper.egg-info/requires.txt0000644000175000017500000000001712377101641023324 0ustar sergiosergio00000000000000rdflib >= 2.4.2