1414API_VERSION = "/v2/"
1515
1616
17- async def _fetch (session , record , query_params , path , headers , attempts_left ):
18- """Internal fetch method."""
17+ async def _fetch (session , record , query_params , path , headers ):
18+ """Make an HTTP request to the API
19+
20+ Parameters
21+ ----------
22+ session : aiohttp.ClientSession
23+
24+ record : QueryRecord
25+
26+ query_params : dict
27+ Additional query parameters to pass to the API call
28+
29+ path : string
30+ Full path of the Versium Reach API endpoint
31+
32+ headers : dict
33+ Additional headers to pass with the HTTP request.
34+
35+ Returns
36+ -------
37+ QueryResult
38+ """
1939 if query_params is None :
2040 query_params = {}
2141 row_dict = {key : value for key , value in record .data .items () if value is not None }
2242 idx = record .index
43+ err_msg = ""
2344 result = QueryResult ()
2445
2546 params = {** query_params , ** row_dict }
@@ -32,8 +53,9 @@ async def _fetch(session, record, query_params, path, headers, attempts_left):
3253 result .headers = dict (response .headers )
3354
3455 if not result .success :
35- logger .error (f"Unsuccessful url fetch: { result .reason } \n \t Index: { idx } \n \t URL: { API_BASE_URL + path } ?{ urllib .parse .urlencode (params )} "
36- f"\n \t Response Status: { result .http_status } \n \t Attempts Left: { attempts_left :d} " )
56+ err_msg = f"Unsuccessful url fetch: { result .reason } \n \t Index: { idx } \n \t URL: { API_BASE_URL + path } ?{ urllib .parse .urlencode (params )} " \
57+ f"\n \t Response Status: { result .http_status } "
58+ result .error_msg = err_msg
3759 return result
3860
3961 result .body_raw = await response .read ()
@@ -51,13 +73,50 @@ async def _fetch(session, record, query_params, path, headers, attempts_left):
5173 except aiohttp .ClientError as e :
5274 result .request_error = e
5375 status = getattr (response , "status" , "UNKNOWN" )
54- logger .error (f"Error during url fetch: { e .message } \n \t Index: { idx } \n \t URL: { path } ?{ urllib .parse .urlencode (params )} "
55- f"\n \t Response Status: { status } \n \t Attempts Left: { attempts_left :d} " )
76+ err_msg = f"Error during url fetch: { e .message } \n \t Index: { idx } \n \t URL: { path } ?{ urllib .parse .urlencode (params )} " \
77+ f"\n \t Response Status: { status } "
78+ result .error_msg = err_msg
5679 return result
5780
5881
59- async def _create_tasks (api , records , query_params , headers = None , * , queries_per_second = 20 , n_connections = 100 , timeout = 20 , n_retry = 3 ,
60- retry_wait_time = 3 ):
82+ async def _create_tasks (api , records , query_params , headers = None , * , n_retry = 3 , queries_per_second = 20 , n_connections = 100 , retry_wait_time = 3 ,
83+ timeout = 20 ):
84+ """ Split the API calls into asynchronous tasks and wrap them in a rate limiter.
85+
86+ Parameters
87+ ----------
88+ api : string
89+ Specifies the name of the Versium Reach API endpoint to query ('contact', 'demographic', 'b2conlineaudience', etc.)
90+
91+ records : list[QueryRecord]
92+ List containing QueryRecord objects
93+
94+ query_params : dict
95+ Additional query parameters to pass to each API call (e.g. {'cfg_max_recs': 1})
96+
97+ headers : dict
98+ Additional header parameters to pass to the API call.
99+
100+ n_retry : int
101+ Number of times to retry the query if it fails.
102+
103+ queries_per_second : int
104+ Maximum number of queries to perform each second to avoid 429 errors.
105+
106+ n_connections : int
107+ Number of simultaneous calls to make when querying.
108+
109+ retry_wait_time : int
110+ Number of seconds to wait until retrying a failed query. The wait time is increased by a multiple of `retry_wait_time` every time
111+ the query fails (e.g. 0, 3, 6, 9, 12, etc.)
112+
113+ timeout : float
114+ Number of seconds to wait for the response before timing out.
115+
116+ Returns
117+ -------
118+ list[dict]: List of responses from the API calls. This will be in the same order as given in the input.
119+ """
61120 tasks = []
62121 limit = RateLimiter (max_calls = queries_per_second ,
63122 period = 1 ,
@@ -78,6 +137,42 @@ async def _create_tasks(api, records, query_params, headers=None, *, queries_per
78137
79138def query_api (api , records , query_params , headers = None , * , n_retry = 3 , queries_per_second = 20 , n_connections = 3 , retry_wait_time = 3 ,
80139 timeout = 3 ):
140+ """ Query the Versium Reach API and return the results.
141+
142+ Parameters
143+ ----------
144+ api : string
145+ Specifies the name of the Versium Reach API endpoint to query ('contact', 'demographic', 'b2conlineaudience', etc.)
146+
147+ records : list[dict]
148+ List containing records as key, value pairs e.g [{'first': 'John', 'last': 'Smith'}]
149+
150+ query_params : dict
151+ Additional query parameters to pass to each API call (e.g. {'cfg_max_recs': 1})
152+
153+ headers : dict
154+ Additional header parameters to pass to the API call.
155+
156+ n_retry : int
157+ Number of times to retry the query if it fails.
158+
159+ queries_per_second : int
160+ Maximum number of queries to perform each second to avoid 429 errors.
161+
162+ n_connections : int
163+ Number of simultaneous calls to make when querying.
164+
165+ retry_wait_time : int
166+ Number of seconds to wait until retrying a failed query. The wait time is increased by a multiple of `retry_wait_time` every time
167+ the query fails (e.g. 0, 3, 6, 9, 12, etc.)
168+
169+ timeout : float
170+ Number of seconds to wait for the response before timing out.
171+
172+ Returns
173+ -------
174+ list[dict]: List of responses from the API calls. This will be in the same order as given in the input.
175+ """
81176
82177 if len (records ) < 1 :
83178 logger .warning ("No input records were given." )
0 commit comments