def details_request(self, reference): ''' Returns a detail dict for a Google Places reference token. See http://code.google.com/apis/maps/documentation/places/#PlaceDetailsResults for contents of this dict. If the place no longer exists, the resulting dict will be empty. Can raise a GoogleAPIError. ''' opts = {'key': self.key, 'reference': reference, 'sensor': 'false'} request_url = 'https://maps.googleapis.com/maps/api/place/details/json' + '?' + urllib.urlencode(opts) response = '' try: response = delayed_retry_on_ioerror( lambda: json.load(urllib.urlopen(request_url)), delay_seconds=5, retry_limit=2) if response['status'] != 'OK' and response['status'] != 'ZERO_RESULTS': print response raise GoogleAPIError(request_url, response) else: return response['result'] except ValueError, KeyError: raise GoogleAPIError(request_url, response)
def search_request(self, coords, radius, keyword=None, name=None): ''' Returns a list of result dicts. See http://code.google.com/apis/maps/documentation/places/#PlaceSearchResults for contents of these dicts. Can raise a GoogleAPIError. ''' opts = {'key': self.key, 'location': '%f,%f' % coords, 'radius': radius, 'sensor': 'false'} if keyword is not None: opts['keyword'] = keyword if name is not None: opts['name'] = name request_url = 'https://maps.googleapis.com/maps/api/place/search/json' + '?' + urllib.urlencode(opts) response = '' try: response = delayed_retry_on_ioerror( lambda: json.load(urllib.urlopen(request_url)), delay_seconds=5, retry_limit=2) if response['status'] != 'OK' and response['status'] != 'ZERO_RESULTS': print response raise GoogleAPIError(request_url, response) else: return response['results'] except ValueError, KeyError: raise GoogleAPIError(request_url, response)
def resolve(self, name=None, address=None, town=None, state=None, postcode=None, latitude=None, longitude=None): ''' Runs a Factual Resolve API call with the given search options and returns a ResolveResponse object. Will raise a FactualAPIError if response returns a non-OK status. ''' query_opts = dict( name=name, address=address, locality=town, region=state, postcode=postcode, latitude=latitude, longitude=longitude, ) # make a JSON version with all None valued-parameters stripped out json_query = json.dumps(dict([(key, val) for key, val in query_opts.items() if val is not None])) full_url = FactualClient.RESOLVE_URL + '?' + urllib.urlencode({'values': json_query}) request = build_oauth_request(full_url, self.key, self.secret) response = delayed_retry_on_ioerror(lambda: ResolveResponse(urllib2.urlopen(request)), 4, self.retry, outsourcing_log) if response.status != 'ok': raise FactualAPIError(request, response.error_type, response.message) return response
def run_geocode_request(self, query, bounds=None, region='US', sensor=False): ''' Calls the Google Geocoding API with given text query and returns a GoogleGeocodingResponse. query should be a raw string (not urlencoded). bounds should be a pair of (lat, long) pairs for the upper left and lower right corner of the bounding rect Will pass on errors of urllib.urlopen if the API's URL has trouble connecting. ''' cleaned_address = self._preprocess_address(query).encode('utf8') options = {'address': cleaned_address, 'sensor': 'true' if sensor else 'false'} if bounds is not None: options['bounds'] = '%f,%f|%f,%f' % (bounds[0][0], bounds[0][1], bounds[1][0], bounds[1][1]) if region is not None: options['region'] = region request_url = self.GOOGLE_BASE_URL + '?' + urllib.urlencode(options) # Google will be polite and give us a nice notice if it's throttling us -- handle that in this loop throttle_retry_count = 0 if self.retry == 0: throttle_retry_limit = 1 else: throttle_retry_limit = 2 while throttle_retry_limit > 0: fp = delayed_retry_on_ioerror(lambda: urllib.urlopen(request_url), delay_seconds=5, retry_limit=1, logger=outsourcing_log) raw_response = fp.read() try: return self._package_response(raw_response, request_url) except GoogleGeocodingThrottleError: throttle_retry_count += 1 throttle_retry_limit -= 1 outsourcing_log.info('Google throttling: Will attempt retry %d (of %d max) in %d secs...' %\ (throttle_retry_count, throttle_retry_limit, 5)) time.sleep(5)