@@ -281,9 +281,8 @@ def get_evaluation_rows(
281281 from_timestamp : Optional [datetime ] = None ,
282282 to_timestamp : Optional [datetime ] = None ,
283283 include_tool_calls : bool = True ,
284- backend_sleep_between_gets : float = 0.1 ,
285- backend_max_retries : int = 3 ,
286- proxy_max_retries : int = 3 ,
284+ sleep_between_gets : float = 0.1 ,
285+ max_retries : int = 3 ,
287286 span_name : Optional [str ] = None ,
288287 converter : Optional [TraceDictConverter ] = None ,
289288 ) -> List [EvaluationRow ]:
@@ -305,10 +304,8 @@ def get_evaluation_rows(
305304 from_timestamp: Explicit start time (ISO format)
306305 to_timestamp: Explicit end time (ISO format)
307306 include_tool_calls: Whether to include tool calling traces
308- backend_sleep_between_gets: Sleep time between backend trace fetches (passed to proxy)
309- backend_max_retries: Maximum retries for backend operations (passed to proxy)
310- proxy_max_retries: Maximum retries when proxy returns 404 (client-side retries with exponential backoff)
311- span_name: If provided, extract messages from generations within this named span
307+ sleep_between_gets: Sleep time between polling attempts (default: 2.5s)
308+ max_retries: Max retry attempts used by proxy (default: 3)
312309 converter: Optional custom converter implementing TraceDictConverter protocol.
313310 If provided, this will be used instead of the default conversion logic.
314311
@@ -318,9 +315,9 @@ def get_evaluation_rows(
318315 Raises:
319316 ValueError: If tags list is empty
320317 """
321- # Validate that tags are provided (security requirement)
318+ # Validate that tags are provided
322319 if not tags or len (tags ) == 0 :
323- raise ValueError ("At least one tag is required to fetch traces (security: prevents fetching all traces) " )
320+ raise ValueError ("At least one tag is required to fetch traces" )
324321
325322 eval_rows = []
326323
@@ -339,58 +336,40 @@ def get_evaluation_rows(
339336 "hours_back" : hours_back ,
340337 "from_timestamp" : from_timestamp .isoformat () if from_timestamp else None ,
341338 "to_timestamp" : to_timestamp .isoformat () if to_timestamp else None ,
342- "sleep_between_gets" : backend_sleep_between_gets ,
343- "max_retries" : backend_max_retries ,
339+ "sleep_between_gets" : sleep_between_gets ,
340+ "max_retries" : max_retries ,
344341 }
345342
346343 # Remove None values
347344 params = {k : v for k , v in params .items () if v is not None }
348345
349- # Make request to proxy with retry logic
346+ # Make request to proxy
350347 if self .project_id :
351348 url = f"{ self .base_url } /v1/project_id/{ self .project_id } /traces"
352349 else :
353350 url = f"{ self .base_url } /v1/traces"
354351
355- # Retry loop for handling backend indexing delays (proxy returns 404)
356352 result = None
357- for attempt in range (proxy_max_retries ):
358- try :
359- response = requests .get (url , params = params , timeout = self .timeout )
360- response .raise_for_status ()
361- result = response .json ()
362- break # Success, exit retry loop
363- except requests .exceptions .HTTPError as e :
364- error_msg = str (e )
365- should_retry = False
366-
367- # Try to extract detail message from response
368- if e .response is not None :
369- try :
370- error_detail = e .response .json ().get ("detail" , "" )
371- error_msg = error_detail or e .response .text
372-
373- # Retry on 404 if it's due to incomplete/missing traces (backend still indexing)
374- if e .response .status_code == 404 :
375- should_retry = True
376- except Exception :
377- error_msg = e .response .text
378-
379- if should_retry and attempt < proxy_max_retries - 1 :
380- sleep_time = 2 ** (attempt + 1 )
381- logger .warning (error_msg )
382- time .sleep (sleep_time )
383- else :
384- # Final retry or non-retryable error
385- logger .error ("Failed to fetch traces from proxy: %s" , error_msg )
386- return eval_rows
387- except requests .exceptions .RequestException as e :
388- # Non-HTTP errors (network issues, timeouts, etc.)
389- logger .error ("Failed to fetch traces from proxy: %s" , str (e ))
390- return eval_rows
391-
392- if result is None :
393- logger .error ("Failed to fetch traces after %d retries" , proxy_max_retries )
353+ try :
354+ response = requests .get (url , params = params , timeout = self .timeout )
355+ response .raise_for_status ()
356+ result = response .json ()
357+ except requests .exceptions .HTTPError as e :
358+ error_msg = str (e )
359+
360+ # Try to extract detail message from response
361+ if e .response is not None :
362+ try :
363+ error_detail = e .response .json ().get ("detail" , {})
364+ error_msg = error_detail or e .response .text
365+ except Exception : # In case e.response.json() fails
366+ error_msg = f"Proxy error: { e .response .text } "
367+
368+ logger .error ("Failed to fetch traces from proxy: %s" , error_msg )
369+ return eval_rows
370+ except requests .exceptions .RequestException as e :
371+ # Non-HTTP errors (network issues, timeouts, etc.)
372+ logger .error ("Failed to fetch traces from proxy: %s" , str (e ))
394373 return eval_rows
395374
396375 # Extract traces from response
0 commit comments