@@ -201,7 +201,98 @@ def query(self, query):
201201
202202 raise exception .MaxRetriesReached (retry_count = retry_num , exceptions = retry_exceptions )
203203
204- def parse_json (self , data , encoding = "utf-8" ):
204+ def query_raw (self , query ):
205+ """
206+ Query the Overpass API
207+
208+ :param String|Bytes query: The query string in Overpass QL
209+ :return: The raw result
210+ :rtype: str
211+ """
212+ if not isinstance (query , bytes ):
213+ query = query .encode ("utf-8" )
214+
215+ retry_num = 0
216+ retry_exceptions = []
217+ do_retry = True if self .max_retry_count > 0 else False
218+ while retry_num <= self .max_retry_count :
219+ if retry_num > 0 :
220+ time .sleep (self .retry_timeout )
221+ retry_num += 1
222+ try :
223+ f = urlopen (self .url , query )
224+ except HTTPError as e :
225+ f = e
226+
227+ response = f .read (self .read_chunk_size )
228+ while True :
229+ data = f .read (self .read_chunk_size )
230+ if len (data ) == 0 :
231+ break
232+ response = response + data
233+ f .close ()
234+
235+ if f .code == 200 :
236+ if PY2 :
237+ http_info = f .info ()
238+ content_type = http_info .getheader ("content-type" )
239+ else :
240+ content_type = f .getheader ("Content-Type" )
241+
242+ if content_type == "application/json" :
243+ return self .parse_json (response , return_raw = True )
244+
245+ if content_type == "application/osm3s+xml" :
246+ return self .parse_xml (response , return_raw = True )
247+
248+ e = exception .OverpassUnknownContentType (content_type )
249+ if not do_retry :
250+ raise e
251+ retry_exceptions .append (e )
252+ continue
253+
254+ if f .code == 400 :
255+ msgs = []
256+ for msg in self ._regex_extract_error_msg .finditer (response ):
257+ tmp = self ._regex_remove_tag .sub (b"" , msg .group ("msg" ))
258+ try :
259+ tmp = tmp .decode ("utf-8" )
260+ except UnicodeDecodeError :
261+ tmp = repr (tmp )
262+ msgs .append (tmp )
263+
264+ e = exception .OverpassBadRequest (
265+ query ,
266+ msgs = msgs
267+ )
268+ if not do_retry :
269+ raise e
270+ retry_exceptions .append (e )
271+ continue
272+
273+ if f .code == 429 :
274+ e = exception .OverpassTooManyRequests
275+ if not do_retry :
276+ raise e
277+ retry_exceptions .append (e )
278+ continue
279+
280+ if f .code == 504 :
281+ e = exception .OverpassGatewayTimeout
282+ if not do_retry :
283+ raise e
284+ retry_exceptions .append (e )
285+ continue
286+
287+ e = exception .OverpassUnknownHTTPStatusCode (f .code )
288+ if not do_retry :
289+ raise e
290+ retry_exceptions .append (e )
291+ continue
292+
293+ raise exception .MaxRetriesReached (retry_count = retry_num , exceptions = retry_exceptions )
294+
295+ def parse_json (self , data , encoding = "utf-8" , return_raw = False ):
205296 """
206297 Parse raw response from Overpass service.
207298
@@ -214,12 +305,16 @@ def parse_json(self, data, encoding="utf-8"):
214305 """
215306 if isinstance (data , bytes ):
216307 data = data .decode (encoding )
217- data = json .loads (data , parse_float = Decimal )
218- if "remark" in data :
219- self ._handle_remark_msg (msg = data .get ("remark" ))
220- return Result .from_json (data , api = self )
308+ json_data = json .loads (data , parse_float = Decimal )
309+ if "remark" in json_data :
310+ self ._handle_remark_msg (msg = json_data .get ("remark" ))
311+
312+ if return_raw :
313+ return data
314+ else :
315+ return Result .from_json (data , api = self )
221316
222- def parse_xml (self , data , encoding = "utf-8" , parser = None ):
317+ def parse_xml (self , data , encoding = "utf-8" , parser = None , return_raw = False ):
223318 """
224319
225320 :param data: Raw XML Data
@@ -241,8 +336,11 @@ def parse_xml(self, data, encoding="utf-8", parser=None):
241336 m = re .compile ("<remark>(?P<msg>[^<>]*)</remark>" ).search (data )
242337 if m :
243338 self ._handle_remark_msg (m .group ("msg" ))
244-
245- return Result .from_xml (data , api = self , parser = parser )
339+
340+ if return_raw :
341+ return data
342+ else :
343+ return Result .from_xml (data , api = self , parser = parser )
246344
247345
248346class Result (object ):
0 commit comments