Skip to content

Commit

Permalink
Merge pull request #35 from ri0t/master
Browse files Browse the repository at this point in the history
Added more tests, cleaned up source, minor fixes
  • Loading branch information
nilsnolde committed Mar 23, 2019
2 parents 3a889f3 + f1afb7f commit 3060a29
Show file tree
Hide file tree
Showing 25 changed files with 1,183 additions and 1,006 deletions.
17 changes: 6 additions & 11 deletions docs/source/conf.py
Expand Up @@ -18,7 +18,8 @@
#
import os
import sys
#sys.path.insert(0, 'C:\\Users\\gisadmin\\Documents\\Dev\\Git\\Uni\\ORS\\infrastructure\\SDK\\openrouteservice-python-api\\openrouteservice')

# sys.path.insert(0, 'C:\\Users\\gisadmin\\Documents\\Dev\\Git\\Uni\\ORS\\infrastructure\\SDK\\openrouteservice-python-api\\openrouteservice')
sys.path.insert(0, os.path.abspath('../..'))

# -- General configuration ------------------------------------------------
Expand All @@ -30,9 +31,11 @@
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = ['sphinx.ext.autodoc',
extensions = [
'sphinx.ext.autodoc',
'sphinx.ext.todo',
'sphinx.ext.coverage']
'sphinx.ext.coverage'
]

# Add any paths that contain templates here, relative to this directory.
templates_path = ['.templates']
Expand Down Expand Up @@ -78,7 +81,6 @@
# If true, `todo` and `todoList` produce output, else they produce nothing.
todo_include_todos = True


# -- Options for HTML output ----------------------------------------------

# The theme to use for HTML and HTML Help pages. See the documentation for
Expand Down Expand Up @@ -112,13 +114,11 @@
]
}


# -- Options for HTMLHelp output ------------------------------------------

# Output file base name for HTML help builder.
htmlhelp_basename = 'openrouteservice-pydoc'


# -- Options for LaTeX output ---------------------------------------------

latex_elements = {
Expand Down Expand Up @@ -147,7 +147,6 @@
u'Nils Nolde', 'manual'),
]


# -- Options for manual page output ---------------------------------------

# One entry per manual page. List of tuples
Expand All @@ -157,7 +156,6 @@
[author], 1)
]


# -- Options for Texinfo output -------------------------------------------

# Grouping the document tree into Texinfo files. List of tuples
Expand All @@ -168,6 +166,3 @@
author, 'openrouteservice-py', 'One line description of project.',
'Miscellaneous'),
]



17 changes: 16 additions & 1 deletion openrouteservice/__init__.py
Expand Up @@ -19,8 +19,23 @@

__version__ = "2.0.0"


# Make sure QGIS plugin can import openrouteservice-py


def get_ordinal(number):
"""Produces an ordinal (1st, 2nd, 3rd, 4th) from a number"""

if number == 1:
return 'st'
elif number == 2:
return 'nd'
elif number == 3:
return 'rd'
else:
return 'th'


from openrouteservice.client import Client
## Allow sphinx to pick up these symbols for the documentation.
#__all__ = ["Client"]
# __all__ = ["Client"]
56 changes: 33 additions & 23 deletions openrouteservice/client.py
Expand Up @@ -30,27 +30,27 @@
import time
import warnings

from openrouteservice import exceptions, __version__
from openrouteservice import exceptions, __version__, get_ordinal

try: # Python 3
try: # Python 3
from urllib.parse import urlencode
except ImportError: # Python 2
except ImportError: # Python 2
from urllib import urlencode


_USER_AGENT = "ORSClientPython.v{}".format(__version__)
_DEFAULT_BASE_URL = "https://api.openrouteservice.org"

_RETRIABLE_STATUSES = set([503])


class Client(object):
"""Performs requests to the ORS API services."""

def __init__(self,
key=None,
base_url=_DEFAULT_BASE_URL,
timeout=60,
retry_timeout=60,
retry_timeout=60,
requests_kwargs=None,
retry_over_query_limit=True):
"""
Expand Down Expand Up @@ -91,16 +91,19 @@ def __init__(self,
self._base_url = base_url

if self._base_url == _DEFAULT_BASE_URL and key is None:
raise ValueError("No API key was specified. Please visit https://openrouteservice.org/sign-up to create one.")
raise ValueError(
"No API key was specified. Please visit https://openrouteservice.org/sign-up to create one.")

self._timeout = timeout
self._retry_over_query_limit = retry_over_query_limit
self._retry_timeout = timedelta(seconds=retry_timeout)
self._requests_kwargs = requests_kwargs or {}
self._requests_kwargs.update({
"headers": {"User-Agent": _USER_AGENT,
'Content-type': 'application/json',
"Authorization": self._key},
"headers": {
"User-Agent": _USER_AGENT,
'Content-type': 'application/json',
"Authorization": self._key
},
"timeout": self._timeout,
})

Expand Down Expand Up @@ -171,20 +174,20 @@ def request(self,
# requests_kwargs arg overriding.
requests_kwargs = requests_kwargs or {}
final_requests_kwargs = dict(self._requests_kwargs, **requests_kwargs)

# Determine GET/POST.
requests_method = self._session.get

if post_json is not None:
requests_method = self._session.post
final_requests_kwargs["json"] = post_json

# Only print URL and parameters for dry_run
if dry_run:
print("url:\n{}\nHeaders:\n{}".format(self._base_url + authed_url,
json.dumps(final_requests_kwargs, indent=2)))
return

try:
response = requests_method(self._base_url + authed_url,
**final_requests_kwargs)
Expand All @@ -195,10 +198,11 @@ def request(self,

if response.status_code in _RETRIABLE_STATUSES:
# Retry request.
warnings.warn('Server down.\nRetrying for the {}th time.'.format(retry_counter + 1),
warnings.warn('Server down.\nRetrying for the {0}{1} time.'.format(retry_counter + 1,
get_ordinal(retry_counter + 1)),
UserWarning,
stacklevel=1)

return self.request(url, get_params, first_request_time,
retry_counter + 1, requests_kwargs, post_json)

Expand All @@ -209,8 +213,9 @@ def request(self,
except exceptions._RetriableRequest as e:
if isinstance(e, exceptions._OverQueryLimit) and not self._retry_over_query_limit:
raise

warnings.warn('Rate limit exceeded.\nRetrying for the {}th time.'.format(retry_counter + 1),

warnings.warn('Rate limit exceeded. Retrying for the {0}{1} time.'.format(retry_counter + 1,
get_ordinal(retry_counter + 1)),
UserWarning,
stacklevel=1)
# Retry request.
Expand All @@ -223,11 +228,13 @@ def req(self):
"""Returns request object. Can be used in case of request failure."""
return self._req

def _get_body(self, response):
@staticmethod
def _get_body(response):
"""Returns the body of a response object, raises status code exceptions if necessary."""
body = response.json()
# error = body.get('error')
# error = body.get('error')
status_code = response.status_code

if status_code == 429:
raise exceptions._OverQueryLimit(
status_code,
Expand All @@ -241,7 +248,8 @@ def _get_body(self, response):

return body

def _generate_auth_url(self, path, params):
@staticmethod
def _generate_auth_url(path, params):
"""Returns the path and query string portion of the request URL, first
adding any necessary parameters.
Expand All @@ -254,10 +262,10 @@ def _generate_auth_url(self, path, params):
:rtype: string
"""

if type(params) is dict:
params = sorted(dict(**params).items())

return path + "?" + _urlencode_params(params)


Expand All @@ -283,6 +291,7 @@ def _make_api_method(func):
Please note that this is an unsupported feature for advanced use only.
It's also currently incompatibile with multiple threads, see GH #160.
"""

@functools.wraps(func)
def wrapper(*args, **kwargs):
args[0]._extra_params = kwargs.pop("extra_params", None)
Expand All @@ -292,6 +301,7 @@ def wrapper(*args, **kwargs):
except AttributeError:
pass
return result

return wrapper


Expand Down
25 changes: 13 additions & 12 deletions openrouteservice/convert.py
Expand Up @@ -20,13 +20,14 @@
"""Converts Python types to string representations suitable for ORS API server.
"""


def _pipe_list(arg):
"""Convert list of values to pipe-delimited string"""
if not _is_list(arg):
raise TypeError(
"Expected a list or tuple, "
"but got {}".format(type(arg).__name__))
return "|".join(map(str,arg))
return "|".join(map(str, arg))


def _comma_list(arg):
Expand All @@ -35,12 +36,12 @@ def _comma_list(arg):
raise TypeError(
"Expected a list or tuple, "
"but got {}".format(type(arg).__name__))
return ",".join(map(str,arg))
return ",".join(map(str, arg))


def _convert_bool(boolean):
"""Convert to stringified boolean"""

return str(boolean).lower()


Expand Down Expand Up @@ -105,10 +106,10 @@ def _concat_coords(arg):


def _is_list(arg):
"""Checks if arg is list-like."""
"""Checks if arg is list-like."""
if isinstance(arg, dict):
return False
if isinstance(arg, str): # Python 3-only, as str has __iter__
if isinstance(arg, str): # Python 3-only, as str has __iter__
return False
return (not _has_method(arg, "strip")
and _has_method(arg, "__getitem__")
Expand Down Expand Up @@ -141,7 +142,7 @@ def decode_polyline(polyline, is3d=False):
:rtype: dict
"""
points = []
index = lat = lng = z= 0
index = lat = lng = z = 0

while index < len(polyline):
result = 1
Expand All @@ -165,7 +166,7 @@ def decode_polyline(polyline, is3d=False):
if b < 0x1f:
break
lng += ~(result >> 1) if (result & 1) != 0 else (result >> 1)

if is3d:
result = 1
shift = 0
Expand All @@ -179,13 +180,13 @@ def decode_polyline(polyline, is3d=False):
if (result & 1) != 0:
z += ~(result >> 1)
else:
z += (result >> 1)
points.append([round(lng * 1e-5, 6), round(lat * 1e-5, 6), round(z*1e-2,1)])
z += (result >> 1)

points.append([round(lng * 1e-5, 6), round(lat * 1e-5, 6), round(z * 1e-2, 1)])

else:
points.append([round(lng * 1e-5, 6), round(lat * 1e-5, 6)])

geojson = {u'type': u'LineString', u'coordinates': points}

return geojson
3 changes: 3 additions & 0 deletions openrouteservice/deprecation.py
Expand Up @@ -17,7 +17,10 @@

import warnings


def warning(old_name, new_name):
"""Deprecation warning"""

warnings.warn('{} will be deprecated in v2.0. Please use {} instead'.format(old_name, new_name),
DeprecationWarning,
stacklevel=2)
1 change: 1 addition & 0 deletions openrouteservice/directions.py
Expand Up @@ -21,6 +21,7 @@

from openrouteservice import validator, deprecation


def directions(client,
coordinates,
profile='driving-car',
Expand Down

0 comments on commit 3060a29

Please sign in to comment.