1
2
3 """
4 @see: U{SPARQL Specification<http://www.w3.org/TR/rdf-sparql-query/>}
5 @authors: U{Ivan Herman<http://www.ivan-herman.net>}, U{Sergio Fernández<http://www.wikier.org>}, U{Carlos Tejo Alonso<http://www.dayures.net>}
6 @organization: U{World Wide Web Consortium<http://www.w3.org>} and U{Foundation CTIC<http://www.fundacionctic.org/>}.
7 @license: U{W3C® SOFTWARE NOTICE AND LICENSE<href="http://www.w3.org/Consortium/Legal/copyright-software">}
8 @requires: U{RDFLib<http://rdflib.net>} package.
9 """
10
11 import urllib2
12 from types import *
13 import SPARQLWrapper
14 from SPARQLWrapper.Wrapper import JSON, SELECT
15
16
17
19 """
20 Class encapsulating a single binding for a variable.
21
22 @cvar URI: the string denoting a URI variable
23 @cvar Literal: the string denoting a Literal variable
24 @cvar TypedLiteral: the string denoting a typed literal variable
25 @cvar BNODE: the string denoting a blank node variable
26
27 @ivar variable: The original variable, stored for an easier reference
28 @type variable: string
29 @ivar value: Value of the binding
30 @type value: string
31 @ivar type: Type of the binding
32 @type type: string; one of L{Value.URI}, L{Value.Literal}, L{Value.TypedLiteral}, or L{Value.BNODE}
33 @ivar lang: Language tag of the binding, or C{None} if not set
34 @type lang: string
35 @ivar datatype: Datatype of the binding, or C{None} if not set
36 @type datatype: string (URI)
37 """
38 URI = "uri"
39 Literal = "literal"
40 TypedLiteral = "typed-literal"
41 BNODE = "bnode"
42
44 """
45 @param variable: the variable for that binding. Stored for an easier reference
46 @param binding: the binding dictionary part of the return result for a specific binding
47 """
48 self.variable = variable
49 self.value = binding['value']
50 self.type = binding['type']
51 self.lang = None
52 self.datatype = None
53 try:
54 self.lang = binding['xml:lang']
55 except:
56
57 pass
58 try:
59 self.datatype = binding['datatype']
60 except:
61 pass
62
64 cls = self.__class__.__name__
65 return "%s(%s:%r)" % (cls, self.type, self.value)
66
67
68
69
71 """
72 Class encapsulating one query result, based on the JSON return format. It decodes the
73 return values to make it a bit more usable for a standard usage. The class consumes the
74 return value and instantiates a number of attributes that can be consulted directly. See
75 the list of variables.
76
77 The U{Serializing SPARQL Query Results in JSON<http://www.w3.org/TR/rdf-sparql-json-res/>} explains the details of the
78 JSON return structures. Very succintly: the return data has "bindings", which means a list of dictionaries. Each
79 dictionary is a possible binding of the SELECT variables to L{Value} instances. This structure is made a bit
80 more usable by this class.
81
82 @ivar fullResult: The original dictionary of the results, stored for an easier reference
83 @ivar head: Header part of the return, see the JSON return format document for details
84 @ivar variables: List of unbounds (variables) of the original query. It is an array of strings. None in the case of an ASK query
85 @ivar bindings: The final bindings: array of dictionaries, mapping variables to L{Value} instances.
86 (If unbound, then no value is set in the dictionary; that can be easily checked with
87 C{var in res.bindings[..]}, for example.)
88 @ivar askResult: by default, set to False; in case of an ASK query, the result of the query
89 @type askResult: Boolean
90 """
92 """
93 @param retval: the query result, instance of a L{Wrapper.QueryResult}
94 """
95 self.fullResult = retval._convertJSON()
96 self.head = self.fullResult['head']
97 self.variables = None
98 try:
99 self.variables = self.fullResult['head']['vars']
100 except:
101 pass
102
103 self.bindings = []
104 try:
105 for b in self.fullResult['results']['bindings']:
106
107
108 newBind = {}
109 for key in self.variables:
110 if key in b:
111
112 newBind[key] = Value(key, b[key])
113 self.bindings.append(newBind)
114 except:
115 pass
116
117 self.askResult = False
118 try:
119 self.askResult = self.fullResult["boolean"]
120 except:
121 pass
122
124 """A shorthand for the retrieval of all bindings for a single key. It is
125 equivalent to "C{[b[key] for b in self[key]]}"
126 @param key: possible variable
127 @return: list of L{Value} instances
128 """
129 try:
130 return [b[key] for b in self[key]]
131 except:
132 return []
133
135 """Emulation of the "C{key in obj}" operator. Key can be a string for a variable or an array/tuple
136 of strings.
137
138 If C{key} is a variable, the return value is C{True} if there is at least one binding where C{key} is
139 bound. If C{key} is an array or tuple, the return value is C{True} if there is at least one binding
140 where I{all} variables in C{key} are bound.
141
142 @param key: possible variable, or array/tuple of variables
143 @return: whether there is a binding of the variable in the return
144 @rtype: Boolean
145 """
146 if len(self.bindings) == 0:
147 return False
148 if type(key) is list or type(key) is tuple:
149
150 if False in [k in self.variables for k in key]:
151 return False
152 for b in self.bindings:
153
154 if False in [k in b for k in key]:
155
156 continue
157 else:
158
159 return True
160 return False
161 else:
162 if key not in self.variables:
163 return False
164 for b in self.bindings:
165 if key in b:
166 return True
167 return False
168
170 """Emulation of the C{obj[key]} operator. Slice notation is also available.
171 The goal is to choose the right bindings among the available ones. The return values are always
172 arrays of bindings, ie, arrays of dictionaries mapping variable keys to L{Value} instances.
173 The different value settings mean the followings:
174
175 - C{obj[key]} returns the bindings where C{key} has a valid value
176 - C{obj[key1,key2,...]} returns the bindings where I{all} C{key1,key2,...} have valid values
177 - C{obj[(key1,key2,...):(nkey1,nkey2,...)]} returns the bindings where all C{key1,key2,...} have
178 valid values and I{none} of the C{nkey1,nkey2,...} have valid values
179 - C{obj[:(nkey1,nkey2,...)]} returns the bindings where I{none} of the C{nkey1,nkey2,...} have valid values
180
181 In all cases complete bindings are returned, ie, the values for other variables, not present among
182 the keys in the call, may or may not be present depending on the query results.
183
184 @param key: possible variable or array/tuple of keys with possible slice notation
185 @return: list of bindings
186 @rtype: array of variable -> L{Value} dictionaries
187 """
188 def _checkKeys(keys):
189 if len(keys) == 0:
190 return False
191 for k in keys:
192 if not isinstance(k, basestring) or not k in self.variables:
193 return False
194 return True
195
196 def _nonSliceCase(key):
197 if isinstance(key, basestring) and key != "" and key in self.variables:
198
199 return [key]
200 elif type(key) is list or type(key) is tuple:
201 if _checkKeys(key):
202 return key
203 return False
204
205
206 yes_keys = []
207 no_keys = []
208 if type(key) is slice:
209
210 if key.start:
211 yes_keys = _nonSliceCase(key.start)
212 if not yes_keys:
213 raise TypeError
214 if key.stop:
215 no_keys = _nonSliceCase(key.stop)
216 if not no_keys:
217 raise TypeError
218 else:
219 yes_keys = _nonSliceCase(key)
220
221
222 retval = []
223 for b in self.bindings:
224
225 if False in [k in b for k in yes_keys]:
226 continue
227 if True in [k in b for k in no_keys]:
228 continue
229
230 retval.append(b)
231
232 if len(retval) == 0:
233 raise IndexError
234 return retval
235
237 """This is just a convenience method, returns C{self}.
238
239 Although C{Binding} is not a subclass of L{QueryResult<SPARQLWrapper.Wrapper.QueryResult>}, it is returned as a result by
240 L{SPARQLWrapper2.query}, just like L{QueryResult<SPARQLWrapper.Wrapper.QueryResult>} is returned by
241 L{SPARQLWrapper.SPARQLWrapper.query}. Consequently,
242 having an empty C{convert} method to imitate L{QueryResult's convert method<SPARQLWrapper.Wrapper.QueryResult.convert>} may avoid unnecessary problems.
243 """
244 return self
245
246
247
248
250 """Subclass of L{Wrapper<SPARQLWrapper.SPARQLWrapper>} that works with a JSON SELECT return result only. The query result
251 is automatically set to a L{Bindings} instance. Makes the average query processing a bit simpler..."""
252 - def __init__(self, baseURI, defaultGraph=None):
253 """
254 Class encapsulating a full SPARQL call. In contrast to the L{SPARQLWrapper<SPARQLWrapper.SPARQLWrapper>} superclass, the return format
255 cannot be set (it is defaulted to L{JSON<Wrapper.JSON>}).
256 @param baseURI: string of the SPARQL endpoint's URI
257 @type baseURI: string
258 @param defaultGraph: URI for the default graph. Default is None, can be set via an explicit call, too
259 @type defaultGraph: string
260 """
261 super(SPARQLWrapper2, self).__init__(baseURI, returnFormat=JSON, defaultGraph=defaultGraph)
262
271
273 """
274 Execute the query and do an automatic conversion.
275
276 Exceptions can be raised if either the URI is wrong or the HTTP sends back an error.
277 The usual urllib2 exceptions are raised, which cover possible SPARQL errors, too.
278
279 If the query type is I{not} SELECT, the method falls back to the
280 L{corresponding method in the superclass<SPARQLWrapper.query>}.
281
282 @return: query result
283 @rtype: L{Bindings} instance
284 """
285 res = super(SPARQLWrapper2, self).query()
286
287 if self.queryType == SELECT:
288 return Bindings(res)
289 else:
290 return res
291
293 """This is here to override the inherited method; it is equivalent to L{query}.
294
295 If the query type is I{not} SELECT, the method falls back to the
296 L{corresponding method in the superclass<SPARQLWrapper.queryAndConvert>}.
297
298 @return: the converted query result.
299 """
300 if self.queryType == SELECT:
301 return self.query()
302 else:
303 return super(SPARQLWrapper2, self).queryAndConvert()
304