Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions overpass/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,6 @@

from .api import API
from .queries import MapQuery, WayQuery
from .errors import (
OverpassError, OverpassSyntaxError, TimeoutError, MultipleRequestsError, ServerLoadError, UnknownOverpassError
)
54 changes: 15 additions & 39 deletions overpass/api.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import sys
import requests
import json
import geojson

from .errors import OverpassSyntaxError, TimeoutError, MultipleRequestsError, ServerLoadError, UnknownOverpassError


class API(object):
"""A simple Python wrapper for the OpenStreetMap Overpass API"""
Expand Down Expand Up @@ -40,20 +41,12 @@ def __init__(self, *args, **kwargs):
def Get(self, query, asGeoJSON=False):
"""Pass in an Overpass query in Overpass QL"""

response = ""
full_query = self._ConstructQLQuery(query, asGeoJSON=asGeoJSON)
raw_response = self._GetFromOverpass(full_query)
response = json.loads(raw_response)

try:
response = json.loads(self._GetFromOverpass(
self._ConstructQLQuery(query, asGeoJSON=asGeoJSON)))
except OverpassException as oe:
print(oe)
sys.exit(1)

if "elements" not in response or len(response["elements"]) == 0:
raise OverpassException(
204,
'No OSM features satisfied your query'
)
if "elements" not in response:
raise UnknownOverpassError("Received an invalid answer from Overpass.")

if not asGeoJSON:
return response
Expand All @@ -63,7 +56,7 @@ def Get(self, query, asGeoJSON=False):

def Search(self, feature_type, regex=False):
"""Search for something."""
pass
raise NotImplementedError()

def _ConstructQLQuery(self, userquery, asGeoJSON=False):
raw_query = str(userquery)
Expand Down Expand Up @@ -96,23 +89,18 @@ def _GetFromOverpass(self, query):
timeout=self.timeout
)
except requests.exceptions.Timeout:
raise OverpassException(
408,
'Query timed out. API instance is set to time out in {timeout}'
' seconds. Try passing in a higher value when instantiating'
' this API: api = Overpass.API(timeout=60)'.format(
timeout=self.timeout
)
)
raise TimeoutError(self._timeout)

self._status = r.status_code

if self._status != 200:
if self._status == 400:
message = 'Query syntax error'
else:
message = 'Error from Overpass API'
raise OverpassException(self._status, message)
raise OverpassSyntaxError(query)
elif self._status == 429:
raise MultipleRequestsError()
elif self._status == 504:
raise ServerLoadError(self._timeout)
raise UnknownOverpassError("The request returned status code {code}".format(code = self._status))
else:
return r.text

Expand All @@ -139,15 +127,3 @@ def _asGeoJSON(self, elements):
features.append(feature)

return geojson.FeatureCollection(features)


class OverpassException(Exception):
def __init__(self, status_code, message):
self.status_code = status_code
self.message = message

def __str__(self):
return json.dumps({
'status': self.status_code,
'message': self.message
})
37 changes: 37 additions & 0 deletions overpass/errors.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
class OverpassError(Exception):
"""An error during your request occurred. Super class for all Overpass api errors."""
pass


class OverpassSyntaxError(OverpassError, ValueError):
"""The request contains a syntax error."""

def __init__(self, request):
self.request = request


class TimeoutError(OverpassError):
"""A request timeout occurred."""

def __init__(self, timeout):
self.timeout = timeout


class MultipleRequestsError(OverpassError):
"""You are trying to run multiple requests at the same time."""
pass


class ServerLoadError(OverpassError):
"""The Overpass server is currently under load and declined the request. Try again later or retry with reduced
timeout value."""

def __init__(self, timeout):
self.timeout = timeout


class UnknownOverpassError(OverpassError):
"""An unknown kind of error happened during the request."""

def __init__(self, message):
self.message = message
3 changes: 1 addition & 2 deletions overpass/queries.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,7 @@ def __str__(self):

class WayQuery(object):

"""Query to retrieve a set of ways and their dependent nodes satisfying
the input parameters"""
"""Query to retrieve a set of ways and their dependent nodes satisfying the input parameters"""

_QUERY_TEMPLATE = "(way{query_parameters});(._;>;);"

Expand Down