Skip to content

Commit 1d7eeea

Browse files
committed
Add query_raw method
Signed-off-by: Diego Ramírez <[email protected]>
1 parent 8aa4baf commit 1d7eeea

File tree

1 file changed

+106
-8
lines changed

1 file changed

+106
-8
lines changed

overpy/__init__.py

Lines changed: 106 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -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

248346
class Result(object):

0 commit comments

Comments
 (0)