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 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 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 graph_api_picture_request(self,fbid,size='normal'): ''' Returns the url to the picture connected to the given object. size can be among 'small','normal','large' ''' url = 'http://graph.facebook.com/%s/picture?type=%s' % (fbid,size) response = delayed_retry_on_ioerror(lambda:urllib.urlopen(url), delay_seconds=3, retry_limit=2, logger=outsourcing_log) return response.url
def graph_api_picture_request(self, fbid, size='normal'): ''' Returns the url to the picture connected to the given object. size can be among 'small','normal','large' ''' url = 'http://graph.facebook.com/%s/picture?type=%s' % (fbid, size) response = delayed_retry_on_ioerror(lambda: urllib.urlopen(url), delay_seconds=3, retry_limit=2, logger=outsourcing_log) return response.url
def _make_request(self,request,urllib_module=urllib): ''' Helper function to make Graph API request and handle possible error conditions. Request will be executed by calling <urllib_module>.urlopen on request object. In the default case, this is callign urllib.urlopen on a url string, but the urllib_module argument allows for flexibility (i.e. calling urllib2.urlopen on a urllib2.Request) ''' response = delayed_retry_on_ioerror(lambda:json.load(urllib_module.urlopen(request)), delay_seconds=6, retry_limit=3, logger=outsourcing_log) return self.postprocess_response(request,response)
def run_geocode_request(cls, 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 = cls._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 = cls.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 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 cls._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)
def _make_request(self, request, urllib_module=urllib): ''' Helper function to make Graph API request and handle possible error conditions. Request will be executed by calling <urllib_module>.urlopen on request object. In the default case, this is callign urllib.urlopen on a url string, but the urllib_module argument allows for flexibility (i.e. calling urllib2.urlopen on a urllib2.Request) ''' response = delayed_retry_on_ioerror( lambda: json.load(urllib_module.urlopen(request)), delay_seconds=6, retry_limit=3, logger=outsourcing_log) return self.postprocess_response(request, response)
def run_geocode_request(cls,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 = cls._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 = cls.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 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 cls._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)
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( {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)), 5, 5, outsourcing_log) if response.status != 'ok': raise FactualAPIError(request, response.error_type, response.message) return response