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