Skip to content

Commit

Permalink
Merge pull request #7 from indeyets/post_parameters
Browse files Browse the repository at this point in the history
POST requests are second-class citizens
  • Loading branch information
wikier committed Nov 13, 2013
2 parents 5a9704e + 50b0450 commit b391085
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 68 deletions.
13 changes: 7 additions & 6 deletions ChangeLog.txt
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
SPARQLWrapper's changelog:
-------------------------

YYYY-MM-DD 1.6.0 - Returing raw response in case of unknow content type returned
YYYY-MM-DD 1.6.0 - Returning raw response in case of unknown content type returned
- Fixed some issues with the last version of the SPARQL 1.1 Update Protocol
- setQuery() doesn't imply resetQuery() anymore
- Deprecated addCustomParameter(), addParameter() and clearParameter() come to provide all required functionality
- SPARQLWrapper, QueryResult, Value, Bindings (and classes inherited from them) are new-style classes now
- POST queries are accompanied by full set of parameters now

2012-08-28 1.5.2 - Implemented update operation according the latest SPARQL 1.1 Protocol drafts (i.e., switching to 'update' parameter)

2012-07-10 1.5.1 - Added the posibility to use two different endpoints for reading and writing operations
2012-07-10 1.5.1 - Added the possibility to use two different endpoints for reading and writing operations
- New print_results() function for users testing

2012-02-01 1.5.0 - Update handling 500's coming from SPARQL endpoint (feature request #3198363)
Expand All @@ -22,13 +23,13 @@ YYYY-MM-DD 1.6.0 - Returing raw response in case of unknow content type retur
2010-01-11 1.4.1 - Supporting keep-alive in SPARQLWrapper if urlgrabber is available (ticket #2929881)
- fixed bugs (#2949834)

2009-12-14 1.4.0 - Added some suport for SPARUL
2009-12-14 1.4.0 - Added some support for SPARUL
- Improved HTTP related code
- Many other minor bugs fixed

2009-09-23 1.3.2 - Remove pyxml dependecy. Instead, use xml.dom.minidom
2009-09-23 1.3.2 - Remove pyxml dependency. Instead, use xml.dom.minidom
- Updated setup installation (added rdflib dependency)
- Udpated example.py (added XML, N3 and RDF examples)
- Updated example.py (added XML, N3 and RDF examples)

2009-09-11 1.3.1 - Remove simplejson dependency for python => 2.6 version
- Added feature to choose the json module to use
Expand All @@ -48,7 +49,7 @@ YYYY-MM-DD 1.6.0 - Returing raw response in case of unknow content type retur
2008-03-07 1.0.1 - Fixed some cosmetic things.

2008-02-14 1.0.0 - First stable release.
- Main functionalities stabilized.
- Main functionality stabilized.
- Project moved to SourceForge.

2007-07-06 0.2.0 - First public release of the library.
Expand Down
128 changes: 66 additions & 62 deletions SPARQLWrapper/Wrapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -309,87 +309,91 @@ def setUseKeepAlive(self):
except ImportError:
warnings.warn("urlgrabber not installed in the system. The execution of this method has no effect.")

def _getURI(self) :
"""Return the URI as sent (or to be sent) to the SPARQL endpoint. The URI is constructed
with the base URI given at initialization, plus all the other parameters set.
@return: URI
@rtype: string
def isSparqlUpdateRequest(self):
""" Returns TRUE if SPARQLWrapper is configured for executing SPARQL Update request
@return: bool
"""
finalQueryParameters = self.parameters.copy()
if self.queryType in [INSERT, DELETE, MODIFY]:
uri = self.updateEndpoint
finalQueryParameters["update"] = [self.queryString]
return self.queryType in [INSERT, DELETE, MODIFY]

def isSparqlQueryRequest(self):
""" Returns TRUE if SPARQLWrapper is configured for executing SPARQL Query request
@return: bool
"""
return not self.isSparqlUpdateRequest()

def _getRequestParameters(self):
queryParameters = self.parameters.copy()

if self.isSparqlUpdateRequest():
queryParameters["update"] = [self.queryString]
else:
uri = self.endpoint
finalQueryParameters["query"] = [self.queryString]
queryParameters["query"] = [self.queryString]

# This is very ugly. The fact is that the key for the choice of the output format is not defined.
# 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.
# 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: finalQueryParameters[f] = [self.returnFormat]

return uri + "?" + urllib.urlencode(self._flat_parameters(finalQueryParameters))

def _flat_parameters(self, params):
"""Internal method to flat the request parameters (issue #1 has
transformed the internal estructure for single value paramters
into amulti-valued parameters)
@return: list of tuples with parameters' values
@rtype: list
"""
flat = []
for k, l in params.items():
for v in l:
flat.append((k, v.encode("utf-8")))
return flat

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
"""
for f in _returnFormatSetting:
queryParameters[f] = [self.returnFormat]

utfQueryParameters = {}

for k, vs in queryParameters.items():
encodedValues = []

for v in vs:
if isinstance(v, unicode):
encodedValues.append(v.encode('utf-8'))
else:
encodedValues.append(v)

utfQueryParameters[k] = encodedValues

return utfQueryParameters

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 :
else:
acceptHeader = ",".join(_ALL)
elif self.queryType in [INSERT, DELETE, MODIFY]:
acceptHeader = "*/*"
else:
if self.returnFormat == N3 or self.returnFormat == TURTLE :
if self.returnFormat == N3 or self.returnFormat == TURTLE:
acceptHeader = ",".join(_RDF_N3)
elif self.returnFormat == XML :
elif self.returnFormat == XML:
acceptHeader = ",".join(_RDF_XML)
else :
else:
acceptHeader = ",".join(_ALL)
return acceptHeader

if self.method == POST :
# by POST
if self.queryType in [INSERT, DELETE, MODIFY]:
uri = self.updateEndpoint
values = { "update" : self.queryString }
else:
uri = self.endpoint
values = { "query" : self.queryString }
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
"""
if self.isSparqlUpdateRequest():
uri = self.updateEndpoint
else:
uri = self.endpoint

encodedParameters = urllib.urlencode(self._getRequestParameters(), True)

if self.method == POST:
request = urllib2.Request(uri)
request.add_header("Content-Type", "application/x-www-form-urlencoded")
data = urllib.urlencode(values)
if isinstance(data, unicode):
data = data.encode("utf-8")
request.add_data(data)
else:
# by GET
# Some versions of Joseki do not work well if no Accept header is given.
# Although it is probably o.k. in newer versions, it does not harm to have that set once and for all...
request = urllib2.Request(self._getURI())
request.add_data(encodedParameters)
else: # GET
request = urllib2.Request(uri + "?" + encodedParameters)

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)))
request.add_header("Accept", self._getAcceptHeader())
if self.user and self.passwd:
request.add_header("Authorization", "Basic " + base64.encodestring("%s:%s" % (self.user, self.passwd)))

return request

def _query(self):
Expand All @@ -401,7 +405,7 @@ def _query(self):
request = self._createRequest()
try:
response = urllib2.urlopen(request)
return (response, self.returnFormat)
return response, self.returnFormat
except urllib2.HTTPError, e:
if e.code == 400:
raise QueryBadFormed(e.read())
Expand All @@ -412,7 +416,7 @@ def _query(self):
else:
raise e

def query(self) :
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
Expand All @@ -432,7 +436,7 @@ def query(self) :
"""
return QueryResult(self._query())

def queryAndConvert(self) :
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.
"""
Expand Down

0 comments on commit b391085

Please sign in to comment.