Skip to content
Merged
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ python:
- "2.7"
- "3.5"
- "3.6"
- "pypy"
# - "pypy3" # out of date OpenSSL error

matrix:
include:
Expand Down
4 changes: 4 additions & 0 deletions Changes.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
v1.2.1 Wed 6 May 2020
Ensure OpenSSL is available on installation
Add exponential backoff to HTTP requests

v1.2 Sun 9 Jun 2019
Use https as default
Handle 401 and 403 exceptions
Expand Down
2 changes: 1 addition & 1 deletion opencage/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@

__author__ = "OpenCage Data"
__email__ = 'info@opencagedata.com'
__version__ = '1.0.0'
__version__ = '1.2.1'
46 changes: 29 additions & 17 deletions opencage/geocoder.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,13 @@
from decimal import Decimal
import collections

import os
import six
import requests
import backoff

def backoff_max_time():
return int(os.environ.get('BACKOFF_MAX_TIME', '120'))

class OpenCageGeocodeError(Exception):

Expand Down Expand Up @@ -142,7 +147,29 @@ def geocode(self, query, **kwargs):
# Add user parameters
data.update(kwargs)

response = requests.get(self.url, params=data)
response = self._opencage_request(data)

return floatify_latlng(response['results'])

def reverse_geocode(self, lat, lng, **kwargs):
"""
Given a latitude & longitude, return an address for that point from OpenCage's Geocoder.

:param lat: Latitude
:param lng: Longitude
:return: Results from OpenCageData
:rtype: dict
:raises RateLimitExceededError: if you have exceeded the number of queries you can make. Exception says when you can try again
:raises UnknownError: if something goes wrong with the OpenCage API
"""
return self.geocode(_query_for_reverse_geocoding(lat, lng), **kwargs)

@backoff.on_exception(
backoff.expo,
(UnknownError, requests.exceptions.RequestException),
max_tries=5, max_time=backoff_max_time)
def _opencage_request(self, params):
response = requests.get(self.url, params=params)

if (response.status_code == 401):
raise NotAuthorizedError()
Expand All @@ -166,22 +193,7 @@ def geocode(self, query, **kwargs):
if 'results' not in response_json:
raise UnknownError("JSON from API doesn't have a 'results' key")


return floatify_latlng(response_json['results'])

def reverse_geocode(self, lat, lng, **kwargs):
"""
Given a latitude & longitude, return an address for that point from OpenCage's Geocoder.

:param lat: Latitude
:param lng: Longitude
:return: Results from OpenCageData
:rtype: dict
:raises RateLimitExceededError: if you have exceeded the number of queries you can make. Exception says when you can try again
:raises UnknownError: if something goes wrong with the OpenCage API
"""
return self.geocode(_query_for_reverse_geocoding(lat, lng), **kwargs)

return response_json

def _query_for_reverse_geocoding(lat, lng):
"""
Expand Down
4 changes: 3 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@

setup(
name="opencage",
version="1.2",
version="1.2.1",
description="Simple wrapper module for the OpenCage Geocoder API",
long_description=long_description,
long_description_content_type='text/markdown',
Expand Down Expand Up @@ -56,6 +56,8 @@
install_requires=[
'Requests>=2.2.0',
'six>=1.4.0',
'pyopenssl>=0.15.1',
'backoff>=1.10.0'
],
test_suite='tests',
tests_require=[
Expand Down
3 changes: 3 additions & 0 deletions tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,16 @@

import unittest

import os
import six
import httpretty

from opencage.geocoder import OpenCageGeocode
from opencage.geocoder import InvalidInputError, RateLimitExceededError, UnknownError, ForbiddenError, NotAuthorizedError
from opencage.geocoder import floatify_latlng, _query_for_reverse_geocoding

# reduce maximum backoff retry time from 120s to 1s
os.environ['BACKOFF_MAX_TIME'] = '1'

class OpenCageGeocodeTestCase(unittest.TestCase):
def setUp(self):
Expand Down