Files
dataservices-api/server/lib/python/cartodb_services/cartodb_services/google/geocoder.py
Mario de Frutos 61efb66aba Add an extra check for google credentials
If the user has a wrong base64 padded secret key the googlemaps
python library is returning "TypeError: Incorrect padding" which
is very hard to understand. So now we check if the secret key is
a valid base64 string
2017-05-26 11:51:32 +02:00

65 lines
2.2 KiB
Python

#!/usr/local/bin/python
# -*- coding: utf-8 -*-
import base64
import googlemaps
from exceptions import MalformedResult, InvalidGoogleCredentials
class GoogleMapsGeocoder:
"""A Google Maps Geocoder wrapper for python"""
def __init__(self, client_id, client_secret, logger):
if not self._valid_credentials(client_secret):
raise InvalidGoogleCredentials('Invalid google secret key')
self.client_id = self._clean_client_id(client_id)
self.client_secret = client_secret
self.geocoder = googlemaps.Client(
client_id=self.client_id, client_secret=self.client_secret)
self._logger = logger
def geocode(self, searchtext, city=None, state=None,
country=None):
try:
opt_params = self._build_optional_parameters(city, state, country)
results = self.geocoder.geocode(address=searchtext,
components=opt_params)
if results:
return self._extract_lng_lat_from_result(results[0])
else:
return []
except KeyError:
raise MalformedResult()
def _extract_lng_lat_from_result(self, result):
location = result['geometry']['location']
longitude = location['lng']
latitude = location['lat']
return [longitude, latitude]
def _build_optional_parameters(self, city=None, state=None,
country=None):
optional_params = {}
if city:
optional_params['locality'] = city
if state:
optional_params['administrative_area'] = state
if country:
optional_params['country'] = country
return optional_params
def _clean_client_id(self, client_id):
# Consistency with how the client_id is saved in metadata
return client_id.replace('client=', '')
def _valid_credentials(self, private_key):
try:
# Only fails if the string dont have a correct padding for b64
# but this way we could provide a more clear error than
# TypeError: Incorrect padding
base64.b64decode(private_key)
return True
except TypeError:
return False