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