diff --git a/docs/_modules/placekey/api.html b/docs/_modules/placekey/api.html index 8f26360..3d8573a 100644 --- a/docs/_modules/placekey/api.html +++ b/docs/_modules/placekey/api.html @@ -49,7 +49,7 @@

Source code for placekey.api

     logging.Formatter('%(asctime)s\t%(levelname)s\t%(message)s')
 )
 log = logging.getLogger()
-log.setLevel(logging.INFO)
+log.setLevel(logging.ERROR)
 log.handlers = [console_log]
 
 
@@ -104,6 +104,8 @@ 

Source code for placekey.api

         'query_id'
     }
 
+    DEFAULT_QUERY_ID_PREFIX = "place_"
+
     def __init__(self, api_key=None, max_retries=DEFAULT_MAX_RETRIES, logger=log):
         self.api_key = api_key
         self.max_retries = max_retries
@@ -173,9 +175,14 @@ 

Source code for placekey.api

         Lookup Placekeys for an iterable of places specified by place dictionaries.
         This method checks that the place dictionaries are valid before querying
         the API, and it will return partial results if it encounters a fatal error.
-        This method follows the rate limits of the Placekey API. This function is a
-        wrapper for `lookup_batch`, and that function may be used if different error
-        handling or logic around batch processing is desired.
+        Places without a `query_id` will have one generated for them based on their
+        index in `places`, e.g., "place_0" for the first item in the list, but a
+        user-provided `query_id` will be passed through as is.
+
+        This function is a wrapper for `lookup_batch`, and that function may be
+        used if different error handling or logic around batch processing is desired.
+
+        This method follows the rate limits of the Placekey API.
 
         :param places: An iterable of of place dictionaries.
         :param strict_address_match: Boolean for whether or not to strict match
@@ -197,9 +204,22 @@ 

Source code for placekey.api

             raise ValueError(
                 "Some queries contain keys other than: {}".format(self.QUERY_PARAMETERS))
 
+        if verbose:
+            self.logger.setLevel(logging.INFO)
+            logging.getLogger('backoff').setLevel(logging.INFO)
+        else:
+            self.logger.setLevel(logging.ERROR)
+            logging.getLogger('backoff').setLevel(logging.ERROR)
+
+        # Add a query_id to each place that doesn't have one
+        for i, place in enumerate(places):
+            if 'query_id' not in place:
+                place['query_id'] = self.DEFAULT_QUERY_ID_PREFIX + str(i)
+
         results = []
         for i in range(0, len(places), batch_size):
             max_batch_idx = min(i + batch_size, len(places))
+            batch_query_ids = [p['query_id'] for p in places[i:max_batch_idx]]
 
             try:
                 res = self.lookup_batch(
@@ -208,41 +228,33 @@ 

Source code for placekey.api

                     strict_name_match=strict_name_match
                 )
             except RateLimitException:
-                logging.error(
+                self.logger.error(
                     'Fatal error encountered. Returning processed items.')
                 break
 
             # Catch case where all queries in batch having an error,
             # and generate rows for individual items.
             if isinstance(res, dict) and 'error' in res:
-                if verbose:
-                    self.logger.info(
-                        'All queries in batch (%s, %s) had errors', i, max_batch_idx)
+                self.logger.info(
+                    'All queries in batch (%s, %s) had errors', i, max_batch_idx)
 
-                res = [{'query_id': str(i), 'error': res['error']}
-                       for i in range(i, max_batch_idx)]
+                res = [{'query_id': query_id,  'error': res['error']}
+                       for query_id in batch_query_ids]
 
             # Catch other server-side errors
             elif 'message' in res:
-                if verbose:
-                    self.logger.error(res['message'])
-                    self.logger.error('Returning completed queries')
+                self.logger.error(res['message'])
+                self.logger.error('Returning completed queries')
                 break
-            else:
-                # Remap the 'query_id' field to match address index
-                for r in res:
-                    if r['query_id'].isdigit():
-                        r['query_id'] = str(int(r['query_id']) + i)
 
             results.append(res)
 
-            if verbose and max_batch_idx % (10 * batch_size) == 0 and i > 0:
-                logging.info('Processed %s items', max_batch_idx)
+            if max_batch_idx % (10 * batch_size) == 0 and i > 0:
+                self.logger.info('Processed %s items', max_batch_idx)
 
         result_list = list(itertools.chain.from_iterable(results))
-        if verbose:
-            logging.info('Processed %s items', len(result_list))
-            logging.info('Done')
+        self.logger.info('Processed %s items', len(result_list))
+        self.logger.info('Done')
 
         return result_list
diff --git a/docs/placekey.html b/docs/placekey.html index 6ed64a2..767d1b4 100644 --- a/docs/placekey.html +++ b/docs/placekey.html @@ -46,7 +46,7 @@

Submodules

placekey.api

-class placekey.api.PlacekeyAPI(api_key=None, max_retries=20, logger=<RootLogger root (INFO)>)[source]
+class placekey.api.PlacekeyAPI(api_key=None, max_retries=20, logger=<RootLogger root (ERROR)>)[source]

Bases: object

PlacekeyAPI class

This class provides functionality for looking up Placekeys using the Placekey @@ -128,9 +128,12 @@

Submodules
Parameters
    diff --git a/docs/searchindex.js b/docs/searchindex.js index f6fc2f1..0fedde3 100644 --- a/docs/searchindex.js +++ b/docs/searchindex.js @@ -1 +1 @@ -Search.setIndex({docnames:["index","modules","placekey"],envversion:{"sphinx.domains.c":2,"sphinx.domains.changeset":1,"sphinx.domains.citation":1,"sphinx.domains.cpp":3,"sphinx.domains.index":1,"sphinx.domains.javascript":2,"sphinx.domains.math":2,"sphinx.domains.python":2,"sphinx.domains.rst":2,"sphinx.domains.std":1,"sphinx.ext.viewcode":1,sphinx:56},filenames:["index.rst","modules.rst","placekey.rst"],objects:{"placekey.api":{PlacekeyAPI:[2,1,1,""]},"placekey.api.PlacekeyAPI":{lookup_batch:[2,2,1,""],lookup_placekey:[2,2,1,""],lookup_placekeys:[2,2,1,""]},"placekey.placekey":{geo_to_placekey:[2,3,1,""],geojson_to_placekeys:[2,3,1,""],get_prefix_distance_dict:[2,3,1,""],h3_int_to_placekey:[2,3,1,""],h3_to_placekey:[2,3,1,""],placekey_distance:[2,3,1,""],placekey_format_is_valid:[2,3,1,""],placekey_to_geo:[2,3,1,""],placekey_to_geojson:[2,3,1,""],placekey_to_h3:[2,3,1,""],placekey_to_h3_int:[2,3,1,""],placekey_to_hex_boundary:[2,3,1,""],placekey_to_polygon:[2,3,1,""],placekey_to_wkt:[2,3,1,""],polygon_to_placekeys:[2,3,1,""],wkt_to_placekeys:[2,3,1,""]},placekey:{api:[2,0,0,"-"],placekey:[2,0,0,"-"]}},objnames:{"0":["py","module","Python module"],"1":["py","class","Python class"],"2":["py","method","Python method"],"3":["py","function","Python function"]},objtypes:{"0":"py:module","1":"py:class","2":"py:method","3":"py:function"},terms:{"100":2,"boolean":2,"class":2,"default":2,"float":2,"function":2,"int":2,"long":2,"return":2,"true":2,The:2,about:0,addit:2,address:2,allow:2,also:2,api:1,api_kei:2,argument:2,around:2,assum:2,backoff:2,base:2,batch:2,batch_siz:2,befor:2,between:2,boundari:2,can:2,cannot:2,center:2,check:2,citi:2,clockwis:2,consol:2,contain:2,content:0,convert:2,coordin:2,correspond:2,count:2,counter:2,describ:2,descript:2,desir:2,dicitonari:2,dict:2,dictionari:2,differ:2,distanc:2,document:2,due:2,each:2,encod:2,encount:2,equal:2,error:2,exceed:2,fail:2,fals:2,fatal:2,field:2,first:2,follow:2,format:2,geo:2,geo_json:2,geo_to_placekei:2,geojson:2,geojson_to_placekei:2,get:2,get_prefix_distance_dict:2,given:2,h3_int_to_placekei:2,h3_integ:2,h3_string:2,h3_to_placekei:2,halt:2,handl:2,hexadecim:2,hexagon:2,how:2,ident:2,includ:2,include_touch:2,index:[0,2],indic:2,info:2,inform:[0,2],input:2,integ:2,interior:2,intersect:2,iso_country_cod:2,iter:2,kei:2,keyword:2,known:2,kwarg:2,last:2,lat:2,latitud:2,length:2,librari:0,limit:2,list:2,locat:2,location_nam:2,log:2,logger:2,logic:2,longitud:2,look:2,lookup:2,lookup_batch:2,lookup_placekei:2,mai:2,map:2,match:2,max_retri:2,maxim:2,maximum:2,meter:2,method:2,modul:[0,2],more:[0,2],most:2,must:2,none:2,note:2,number:2,object:2,onli:2,orient:2,otherwis:2,page:0,paramet:2,partial:2,pass:2,place:2,place_kei:2,placekey_1:2,placekey_2:2,placekey_dist:2,placekey_format_is_valid:2,placekey_to_geo:2,placekey_to_geojson:2,placekey_to_h3:2,placekey_to_h3_int:2,placekey_to_hex_boundari:2,placekey_to_polygon:2,placekey_to_wkt:2,placekeyapi:2,point:2,poli:2,polygon:2,polygon_to_placekei:2,postal_cod:2,prefix:2,process:2,provid:2,queri:2,query_id:2,rate:2,region:2,relat:2,request:2,respect:2,respons:2,result:2,retri:2,root:2,rootlogg:2,search:0,see:[0,2],sent:2,set:2,shape:2,share:2,singl:2,site:0,size:2,sourc:2,specifi:2,street_address:2,strict:2,strict_address_match:2,strict_name_match:2,string:2,submodul:[0,1],subset:2,text:2,thi:[0,2],time:2,touch:2,tupl:2,two:2,type:2,use:2,used:2,uses:2,using:2,util:2,valid:2,valu:2,verbos:2,well:2,whether:2,which:2,whose:2,wkt:2,wkt_to_placekei:2,wrapper:2},titles:["Placekey-py documentation","Placekey","Submodules"],titleterms:{api:2,document:0,indic:0,placekei:[0,1,2],submodul:2,tabl:0}}) \ No newline at end of file +Search.setIndex({docnames:["index","modules","placekey"],envversion:{"sphinx.domains.c":2,"sphinx.domains.changeset":1,"sphinx.domains.citation":1,"sphinx.domains.cpp":3,"sphinx.domains.index":1,"sphinx.domains.javascript":2,"sphinx.domains.math":2,"sphinx.domains.python":2,"sphinx.domains.rst":2,"sphinx.domains.std":1,"sphinx.ext.viewcode":1,sphinx:56},filenames:["index.rst","modules.rst","placekey.rst"],objects:{"placekey.api":{PlacekeyAPI:[2,1,1,""]},"placekey.api.PlacekeyAPI":{lookup_batch:[2,2,1,""],lookup_placekey:[2,2,1,""],lookup_placekeys:[2,2,1,""]},"placekey.placekey":{geo_to_placekey:[2,3,1,""],geojson_to_placekeys:[2,3,1,""],get_prefix_distance_dict:[2,3,1,""],h3_int_to_placekey:[2,3,1,""],h3_to_placekey:[2,3,1,""],placekey_distance:[2,3,1,""],placekey_format_is_valid:[2,3,1,""],placekey_to_geo:[2,3,1,""],placekey_to_geojson:[2,3,1,""],placekey_to_h3:[2,3,1,""],placekey_to_h3_int:[2,3,1,""],placekey_to_hex_boundary:[2,3,1,""],placekey_to_polygon:[2,3,1,""],placekey_to_wkt:[2,3,1,""],polygon_to_placekeys:[2,3,1,""],wkt_to_placekeys:[2,3,1,""]},placekey:{api:[2,0,0,"-"],placekey:[2,0,0,"-"]}},objnames:{"0":["py","module","Python module"],"1":["py","class","Python class"],"2":["py","method","Python method"],"3":["py","function","Python function"]},objtypes:{"0":"py:module","1":"py:class","2":"py:method","3":"py:function"},terms:{"100":2,"boolean":2,"class":2,"default":2,"float":2,"function":2,"int":2,"long":2,"return":2,"true":2,The:2,about:0,addit:2,address:2,allow:2,also:2,api:1,api_kei:2,argument:2,around:2,assum:2,backoff:2,base:2,batch:2,batch_siz:2,befor:2,between:2,boundari:2,can:2,cannot:2,center:2,check:2,citi:2,clockwis:2,consol:2,contain:2,content:0,convert:2,coordin:2,correspond:2,count:2,counter:2,describ:2,descript:2,desir:2,dicitonari:2,dict:2,dictionari:2,differ:2,distanc:2,document:2,due:2,each:2,encod:2,encount:2,equal:2,error:2,exceed:2,fail:2,fals:2,fatal:2,field:2,first:2,follow:2,format:2,gener:2,geo:2,geo_json:2,geo_to_placekei:2,geojson:2,geojson_to_placekei:2,get:2,get_prefix_distance_dict:2,given:2,h3_int_to_placekei:2,h3_integ:2,h3_string:2,h3_to_placekei:2,halt:2,handl:2,have:2,hexadecim:2,hexagon:2,how:2,ident:2,includ:2,include_touch:2,index:[0,2],indic:2,inform:[0,2],input:2,integ:2,interior:2,intersect:2,iso_country_cod:2,item:2,iter:2,kei:2,keyword:2,known:2,kwarg:2,last:2,lat:2,latitud:2,length:2,librari:0,limit:2,list:2,locat:2,location_nam:2,log:2,logger:2,logic:2,longitud:2,look:2,lookup:2,lookup_batch:2,lookup_placekei:2,mai:2,map:2,match:2,max_retri:2,maxim:2,maximum:2,meter:2,method:2,modul:[0,2],more:[0,2],most:2,must:2,none:2,note:2,number:2,object:2,one:2,onli:2,orient:2,otherwis:2,page:0,paramet:2,partial:2,pass:2,place:2,place_0:2,place_kei:2,placekey_1:2,placekey_2:2,placekey_dist:2,placekey_format_is_valid:2,placekey_to_geo:2,placekey_to_geojson:2,placekey_to_h3:2,placekey_to_h3_int:2,placekey_to_hex_boundari:2,placekey_to_polygon:2,placekey_to_wkt:2,placekeyapi:2,point:2,poli:2,polygon:2,polygon_to_placekei:2,postal_cod:2,prefix:2,process:2,provid:2,queri:2,query_id:2,rate:2,region:2,relat:2,request:2,respect:2,respons:2,result:2,retri:2,root:2,rootlogg:2,search:0,see:[0,2],sent:2,set:2,shape:2,share:2,singl:2,site:0,size:2,sourc:2,specifi:2,street_address:2,strict:2,strict_address_match:2,strict_name_match:2,string:2,submodul:[0,1],subset:2,text:2,them:2,thi:[0,2],through:2,time:2,touch:2,tupl:2,two:2,type:2,use:2,used:2,user:2,uses:2,using:2,util:2,valid:2,valu:2,verbos:2,well:2,whether:2,which:2,whose:2,without:2,wkt:2,wkt_to_placekei:2,wrapper:2},titles:["Placekey-py documentation","Placekey","Submodules"],titleterms:{api:2,document:0,indic:0,placekei:[0,1,2],submodul:2,tabl:0}}) \ No newline at end of file diff --git a/placekey/__init__.py b/placekey/__init__.py index 4e8b504..c1409d6 100644 --- a/placekey/__init__.py +++ b/placekey/__init__.py @@ -1,3 +1,3 @@ from .placekey import * -__version__ = '0.0.7' +__version__ = '0.0.8' __all__ = ['placekey', 'api'] diff --git a/placekey/api.py b/placekey/api.py index afedec4..8be2232 100644 --- a/placekey/api.py +++ b/placekey/api.py @@ -65,6 +65,8 @@ class PlacekeyAPI: 'query_id' } + DEFAULT_QUERY_ID_PREFIX = "place_" + def __init__(self, api_key=None, max_retries=DEFAULT_MAX_RETRIES, logger=log): self.api_key = api_key self.max_retries = max_retries @@ -134,9 +136,14 @@ def lookup_placekeys(self, Lookup Placekeys for an iterable of places specified by place dictionaries. This method checks that the place dictionaries are valid before querying the API, and it will return partial results if it encounters a fatal error. - This method follows the rate limits of the Placekey API. This function is a - wrapper for `lookup_batch`, and that function may be used if different error - handling or logic around batch processing is desired. + Places without a `query_id` will have one generated for them based on their + index in `places`, e.g., "place_0" for the first item in the list, but a + user-provided `query_id` will be passed through as is. + + This function is a wrapper for `lookup_batch`, and that function may be + used if different error handling or logic around batch processing is desired. + + This method follows the rate limits of the Placekey API. :param places: An iterable of of place dictionaries. :param strict_address_match: Boolean for whether or not to strict match @@ -165,9 +172,15 @@ def lookup_placekeys(self, self.logger.setLevel(logging.ERROR) logging.getLogger('backoff').setLevel(logging.ERROR) + # Add a query_id to each place that doesn't have one + for i, place in enumerate(places): + if 'query_id' not in place: + place['query_id'] = self.DEFAULT_QUERY_ID_PREFIX + str(i) + results = [] for i in range(0, len(places), batch_size): max_batch_idx = min(i + batch_size, len(places)) + batch_query_ids = [p['query_id'] for p in places[i:max_batch_idx]] try: res = self.lookup_batch( @@ -186,19 +199,14 @@ def lookup_placekeys(self, self.logger.info( 'All queries in batch (%s, %s) had errors', i, max_batch_idx) - res = [{'query_id': str(i), 'error': res['error']} - for i in range(i, max_batch_idx)] + res = [{'query_id': query_id, 'error': res['error']} + for query_id in batch_query_ids] # Catch other server-side errors elif 'message' in res: self.logger.error(res['message']) self.logger.error('Returning completed queries') break - else: - # Remap the 'query_id' field to match address index - for r in res: - if r['query_id'].isdigit(): - r['query_id'] = str(int(r['query_id']) + i) results.append(res) diff --git a/setup.py b/setup.py index 46999bd..060269d 100644 --- a/setup.py +++ b/setup.py @@ -5,7 +5,7 @@ setuptools.setup( name="placekey", - version="0.0.7", + version="0.0.8", author="SafeGraph Inc.", author_email="russ@safegraph.com", description="Utilities for working with Placekeys",