ragaai-catalyst 2.2.4.1b4__py3-none-any.whl → 2.2.4.1b5__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,124 @@
1
+ import logging
2
+ import os
3
+ import threading
4
+
5
+ from requests.adapters import HTTPAdapter
6
+ from urllib3.util.retry import Retry
7
+ from urllib3.exceptions import PoolError, MaxRetryError, NewConnectionError
8
+ from requests.exceptions import ConnectionError, Timeout
9
+ from ragaai_catalyst import RagaAICatalyst
10
+ import requests
11
+
12
+ logger = logging.getLogger(__name__)
13
+
14
+
15
+ class SessionManager:
16
+ """Shared session manager with connection pooling for HTTP requests"""
17
+ _instance = None
18
+ _session = None
19
+ _lock = threading.Lock()
20
+
21
+ def __new__(cls):
22
+ if cls._instance is None:
23
+ with cls._lock: # Thread-safe singleton
24
+ if cls._instance is None: # Double-check locking
25
+ logger.info("Creating new SessionManager singleton instance")
26
+ cls._instance = super(SessionManager, cls).__new__(cls)
27
+ cls._instance._initialize_session()
28
+ else:
29
+ logger.debug("SessionManager instance already exists, returning existing instance")
30
+ else:
31
+ logger.debug("SessionManager instance exists, returning existing instance")
32
+ return cls._instance
33
+
34
+ def _initialize_session(self):
35
+ """Initialize session with connection pooling and retry strategy"""
36
+ logger.info("Initializing HTTP session with connection pooling and retry strategy")
37
+ self._session = requests.Session()
38
+
39
+ retry_strategy = Retry(
40
+ total=3, # number of retries
41
+ backoff_factor=0.5, # wait 0.5, 1, 2... seconds between retries
42
+ status_forcelist=[500, 502, 503, 504] # HTTP status codes to retry on
43
+ )
44
+
45
+ adapter = HTTPAdapter(
46
+ max_retries=retry_strategy,
47
+ pool_connections=5, # number of connection pools to cache (per host)
48
+ pool_maxsize=50, # maximum number of connections in each pool
49
+ pool_block=True # Block/wait when pool is full rather than raising error
50
+ )
51
+
52
+ self._session.mount("http://", adapter)
53
+ self._session.mount("https://", adapter)
54
+
55
+ logger.info("HTTP session initialized successfully with adapters mounted for http:// and https://")
56
+
57
+ # Warm up connection pool using RagaAICatalyst.BASE_URL
58
+ if os.getenv("RAGAAI_CATALYST_BASE_URL") is not None:
59
+ base_url = os.getenv("RAGAAI_CATALYST_BASE_URL")
60
+ logger.info(f"Warming up connection pool using RagaAICatalyst.BASE_URL: {base_url}")
61
+ self.warm_up_connections(base_url)
62
+ else:
63
+ logger.warning(f"RAGAAI_CATALYST_BASE_URL {base_url} not available, skipping connection warmup")
64
+
65
+ @property
66
+ def session(self):
67
+ if self._session is None:
68
+ logger.warning("Session accessed but not initialized, reinitializing...")
69
+ self._initialize_session()
70
+ return self._session
71
+
72
+ def warm_up_connections(self, base_url, num_connections=3):
73
+ """
74
+ Warm up the connection pool by making lightweight requests to healthcheck endpoint.
75
+ This can help prevent RemoteDisconnected errors on initial requests.
76
+ """
77
+ if not self._session:
78
+ return
79
+
80
+ # Construct healthcheck URL
81
+ healthcheck_url = f"{base_url.rstrip('/')}/healthcheck"
82
+ logger.info(f"Warming up connection pool with {num_connections} connections to {healthcheck_url}")
83
+
84
+ for i in range(num_connections):
85
+ try:
86
+ # Make a lightweight HEAD request to the healthcheck endpoint to warm up the connection
87
+ response = self._session.head(healthcheck_url, timeout=5)
88
+ logger.info(f"Warmup connection {i+1}: Status {response.status_code}")
89
+ except Exception as e:
90
+ logger.error(f"Warmup connection {i+1} failed (this is normal): {e}")
91
+ # Ignore failures during warmup as they're expected
92
+ continue
93
+
94
+ logger.info("Connection pool warmup completed")
95
+
96
+ def close(self):
97
+ """Close the session"""
98
+ if self._session:
99
+ logger.info("Closing HTTP session")
100
+ self._session.close()
101
+ self._session = None
102
+ logger.info("HTTP session closed successfully")
103
+ else:
104
+ logger.debug("Close called but session was already None")
105
+
106
+ def handle_request_exceptions(self, e, operation_name):
107
+ """Handle common request exceptions with appropriate logging"""
108
+ logger.error(f"Exception occurred during {operation_name}")
109
+ if isinstance(e, (PoolError, MaxRetryError)):
110
+ logger.error(f"Connection pool exhausted during {operation_name}: {e}")
111
+ elif isinstance(e, NewConnectionError):
112
+ logger.error(f"Failed to establish new connection during {operation_name}: {e}")
113
+ elif isinstance(e, ConnectionError):
114
+ logger.error(f"Connection error during {operation_name}: {e}")
115
+ elif isinstance(e, Timeout):
116
+ logger.error(f"Request timeout during {operation_name}: {e}")
117
+ else:
118
+ logger.error(f"Unexpected error during {operation_name}: {e}")
119
+
120
+
121
+ # Global session manager instance
122
+ logger.info("Creating global SessionManager instance")
123
+ session_manager = SessionManager()
124
+ logger.info(f"Global SessionManager instance created with ID: {id(session_manager)}")
@@ -22,6 +22,7 @@ from typing import Dict, Any, Optional
22
22
  import threading
23
23
  import uuid
24
24
 
25
+
25
26
  # Set up logging
26
27
  log_dir = os.path.join(tempfile.gettempdir(), "ragaai_logs")
27
28
  os.makedirs(log_dir, exist_ok=True)
@@ -49,11 +50,13 @@ try:
49
50
  from ragaai_catalyst.tracers.agentic_tracing.upload.upload_code import upload_code
50
51
  # from ragaai_catalyst.tracers.agentic_tracing.upload.upload_trace_metric import upload_trace_metric
51
52
  from ragaai_catalyst.tracers.agentic_tracing.utils.create_dataset_schema import create_dataset_schema_with_trace
53
+ from ragaai_catalyst.tracers.agentic_tracing.upload.session_manager import session_manager
52
54
  from ragaai_catalyst import RagaAICatalyst
53
55
  IMPORTS_AVAILABLE = True
54
56
  except ImportError:
55
57
  logger.warning("RagaAI Catalyst imports not available - running in test mode")
56
58
  IMPORTS_AVAILABLE = False
59
+ session_manager = None
57
60
 
58
61
  # Define task queue directory
59
62
  QUEUE_DIR = os.path.join(tempfile.gettempdir(), "ragaai_tasks")
@@ -72,6 +75,10 @@ _executor_lock = threading.Lock()
72
75
  _futures: Dict[str, Any] = {}
73
76
  _futures_lock = threading.Lock()
74
77
 
78
+ # Dataset creation cache to avoid redundant API calls
79
+ _dataset_cache: Dict[str, Dict[str, Any]] = {}
80
+ _dataset_cache_lock = threading.Lock()
81
+ DATASET_CACHE_DURATION = 600 # 10 minutes in seconds
75
82
 
76
83
  _cleanup_lock = threading.Lock()
77
84
  _last_cleanup = 0
@@ -88,7 +95,7 @@ def get_executor(max_workers=None):
88
95
  if _executor is None:
89
96
  # Calculate optimal worker count
90
97
  if max_workers is None:
91
- max_workers = min(32, (os.cpu_count() or 1) * 4)
98
+ max_workers = min(8, (os.cpu_count() or 1) * 4)
92
99
 
93
100
  logger.info(f"Creating ThreadPoolExecutor with {max_workers} workers")
94
101
  _executor = concurrent.futures.ThreadPoolExecutor(
@@ -110,9 +117,57 @@ def generate_unique_task_id():
110
117
  unique_id = str(uuid.uuid4())[:8] # Short UUID
111
118
  return f"task_{int(time.time())}_{os.getpid()}_{counter}_{unique_id}"
112
119
 
120
+ def _generate_dataset_cache_key(dataset_name: str, project_name: str, base_url: str) -> str:
121
+ """Generate a unique cache key for dataset creation"""
122
+ return f"{dataset_name}#{project_name}#{base_url}"
123
+
124
+ def _is_dataset_cached(cache_key: str) -> bool:
125
+ """Check if dataset creation is cached and still valid"""
126
+ with _dataset_cache_lock:
127
+ if cache_key not in _dataset_cache:
128
+ return False
129
+
130
+ cache_entry = _dataset_cache[cache_key]
131
+ cache_time = cache_entry.get('timestamp', 0)
132
+ current_time = time.time()
133
+
134
+ # Check if cache is still valid (within 10 minutes)
135
+ if current_time - cache_time <= DATASET_CACHE_DURATION:
136
+ logger.info(f"Dataset creation cache hit for key: {cache_key}")
137
+ return True
138
+ else:
139
+ # Cache expired, remove it
140
+ logger.info(f"Dataset creation cache expired for key: {cache_key}")
141
+ del _dataset_cache[cache_key]
142
+ return False
143
+
144
+ def _cache_dataset_creation(cache_key: str, response: Any) -> None:
145
+ """Cache successful dataset creation"""
146
+ with _dataset_cache_lock:
147
+ _dataset_cache[cache_key] = {
148
+ 'timestamp': time.time(),
149
+ 'response': response
150
+ }
151
+
152
+ def _cleanup_expired_cache_entries() -> None:
153
+ """Remove expired cache entries"""
154
+ current_time = time.time()
155
+ with _dataset_cache_lock:
156
+ expired_keys = []
157
+ for cache_key, cache_entry in _dataset_cache.items():
158
+ cache_time = cache_entry.get('timestamp', 0)
159
+ if current_time - cache_time > DATASET_CACHE_DURATION:
160
+ expired_keys.append(cache_key)
161
+
162
+ for key in expired_keys:
163
+ del _dataset_cache[key]
164
+
165
+ if expired_keys:
166
+ logger.info(f"Cleaned up {len(expired_keys)} expired dataset cache entries")
167
+
113
168
  def process_upload(task_id: str, filepath: str, hash_id: str, zip_path: str,
114
169
  project_name: str, project_id: str, dataset_name: str,
115
- user_details: Dict[str, Any], base_url: str, timeout=120, fail_on_trace_error=True) -> Dict[str, Any]:
170
+ user_details: Dict[str, Any], base_url: str, tracer_type, timeout=120, fail_on_trace_error=True) -> Dict[str, Any]:
116
171
  """
117
172
  Process a single upload task
118
173
 
@@ -165,20 +220,36 @@ def process_upload(task_id: str, filepath: str, hash_id: str, zip_path: str,
165
220
  save_task_status(result)
166
221
  return result
167
222
 
168
- # Step 1: Create dataset schema
223
+ # Step 1: Create dataset schema (with caching)
169
224
  logger.info(f"Creating dataset schema for {dataset_name} with base_url: {base_url} and timeout: {timeout}")
170
- try:
171
- response = create_dataset_schema_with_trace(
172
- dataset_name=dataset_name,
173
- project_name=project_name,
174
- base_url=base_url,
175
- user_details=user_details,
176
- timeout=timeout
177
- )
178
- logger.info(f"Dataset schema created: {response}")
179
- except Exception as e:
180
- logger.error(f"Error creating dataset schema: {e}")
181
- # Continue with other steps
225
+
226
+ # Generate cache key and check if dataset creation is already cached
227
+ cache_key = _generate_dataset_cache_key(dataset_name, project_name, base_url)
228
+
229
+ if _is_dataset_cached(cache_key):
230
+ logger.info(f"Dataset schema creation skipped (cached) for {dataset_name}")
231
+ else:
232
+ try:
233
+ # Clean up expired cache entries periodically
234
+ # _cleanup_expired_cache_entries()
235
+
236
+ response = create_dataset_schema_with_trace(
237
+ dataset_name=dataset_name,
238
+ project_name=project_name,
239
+ base_url=base_url,
240
+ user_details=user_details,
241
+ timeout=timeout
242
+ )
243
+ logger.info(f"Dataset schema created: {response}")
244
+
245
+ # Cache the response only if status code is 200
246
+ if response and hasattr(response, 'status_code') and response.status_code in [200, 201]:
247
+ _cache_dataset_creation(cache_key, response)
248
+ logger.info(f"Response cached successfully for dataset: {dataset_name} and key: {cache_key}")
249
+
250
+ except Exception as e:
251
+ logger.error(f"Error creating dataset schema: {e}")
252
+ # Continue with other steps
182
253
 
183
254
  # Step 2: Upload trace metrics
184
255
  # if filepath and os.path.exists(filepath):
@@ -238,28 +309,34 @@ def process_upload(task_id: str, filepath: str, hash_id: str, zip_path: str,
238
309
  logger.error(error_msg)
239
310
 
240
311
  # Step 4: Upload code hash
241
- if hash_id and zip_path and os.path.exists(zip_path):
242
- logger.info(f"Uploading code hash {hash_id} with base_url: {base_url} and timeout: {timeout}")
243
- try:
244
- response = upload_code(
245
- hash_id=hash_id,
246
- zip_path=zip_path,
247
- project_name=project_name,
248
- dataset_name=dataset_name,
249
- base_url=base_url,
250
- timeout=timeout
251
- )
252
- logger.info(f"Code hash uploaded: {response}")
253
- except Exception as e:
254
- logger.error(f"Error uploading code hash: {e}")
255
- else:
256
- logger.warning(f"Code zip {zip_path} not found, skipping code upload")
257
-
312
+ if tracer_type.startswith("agentic/"):
313
+ logger.info(f"Tracer type '{tracer_type}' matches agentic pattern, proceeding with code upload")
314
+ if hash_id and zip_path and os.path.exists(zip_path):
315
+ logger.info(f"Uploading code hash {hash_id} with base_url: {base_url} and timeout: {timeout}")
316
+ try:
317
+ response = upload_code(
318
+ hash_id=hash_id,
319
+ zip_path=zip_path,
320
+ project_name=project_name,
321
+ dataset_name=dataset_name,
322
+ base_url=base_url,
323
+ timeout=timeout
324
+ )
325
+ if response is None:
326
+ error_msg = "Code hash not uploaded"
327
+ logger.error(error_msg)
328
+ else:
329
+ logger.info(f"Code hash uploaded successfully: {response}")
330
+ except Exception as e:
331
+ logger.error(f"Error uploading code hash: {e}")
332
+ else:
333
+ logger.warning(f"Code zip {zip_path} not found, skipping code upload")
334
+
258
335
  # Mark task as completed
259
336
  result["status"] = STATUS_COMPLETED
260
337
  result["end_time"] = datetime.now().isoformat()
261
338
  logger.info(f"Task {task_id} completed successfully")
262
-
339
+
263
340
  except Exception as e:
264
341
  logger.error(f"Error processing task {task_id}: {e}")
265
342
  result["status"] = STATUS_FAILED
@@ -302,7 +379,8 @@ def save_task_status(task_status: Dict[str, Any]):
302
379
  with open(status_path, "w") as f:
303
380
  json.dump(task_status, f, indent=2)
304
381
 
305
- def submit_upload_task(filepath, hash_id, zip_path, project_name, project_id, dataset_name, user_details, base_url, timeout=120):
382
+ def submit_upload_task(filepath, hash_id, zip_path, project_name, project_id, dataset_name, user_details, base_url,
383
+ tracer_type, timeout=120):
306
384
  """
307
385
  Submit a new upload task using futures.
308
386
 
@@ -349,6 +427,7 @@ def submit_upload_task(filepath, hash_id, zip_path, project_name, project_id, da
349
427
  dataset_name=dataset_name,
350
428
  user_details=user_details,
351
429
  base_url=base_url,
430
+ tracer_type = tracer_type,
352
431
  timeout=timeout,
353
432
  fail_on_trace_error=True
354
433
  )
@@ -379,6 +458,7 @@ def submit_upload_task(filepath, hash_id, zip_path, project_name, project_id, da
379
458
  dataset_name=dataset_name,
380
459
  user_details=user_details,
381
460
  base_url=base_url,
461
+ tracer_type=tracer_type,
382
462
  timeout=timeout,
383
463
  fail_on_trace_error=True
384
464
  )
@@ -550,6 +630,14 @@ def shutdown(timeout=120):
550
630
 
551
631
  _executor = None
552
632
 
633
+ # Close the session manager to clean up HTTP connections
634
+ if session_manager is not None:
635
+ try:
636
+ session_manager.close()
637
+ logger.info("Session manager closed successfully")
638
+ except Exception as e:
639
+ logger.error(f"Error closing session manager: {e}")
640
+
553
641
  # Register shutdown handler
554
642
  atexit.register(shutdown)
555
643
 
@@ -4,13 +4,13 @@ import os
4
4
  import re
5
5
  import time
6
6
  from urllib.parse import urlparse, urlunparse
7
+ from urllib3.exceptions import PoolError, MaxRetryError, NewConnectionError
8
+ from requests.exceptions import ConnectionError, Timeout, RequestException
9
+ from .session_manager import session_manager
7
10
 
8
11
  import requests
9
12
 
10
13
  logger = logging.getLogger(__name__)
11
- logging_level = (
12
- logger.setLevel(logging.DEBUG) if os.getenv("DEBUG") == "1" else logging.INFO
13
- )
14
14
 
15
15
  from ragaai_catalyst.ragaai_catalyst import RagaAICatalyst
16
16
 
@@ -47,42 +47,36 @@ class UploadAgenticTraces:
47
47
  "X-Project-Name": self.project_name,
48
48
  }
49
49
 
50
- logger.debug("Started getting presigned url: ")
51
- logger.debug(f"Payload: {payload}")
52
- logger.debug(f"Headers: {headers}")
53
50
  try:
54
51
  start_time = time.time()
55
52
  endpoint = f"{self.base_url}/v1/llm/presigned-url"
56
53
  # Changed to POST from GET
57
- response = requests.request(
54
+ response = session_manager.session.request(
58
55
  "POST", endpoint, headers=headers, data=payload, timeout=self.timeout
59
56
  )
60
57
  elapsed_ms = (time.time() - start_time) * 1000
61
58
  logger.debug(
62
59
  f"API Call: [POST] {endpoint} | Status: {response.status_code} | Time: {elapsed_ms:.2f}ms"
63
60
  )
64
- if response.status_code in [200, 201]:
61
+
62
+ if response.status_code == 200:
65
63
  presignedURLs = response.json()["data"]["presignedUrls"][0]
66
- logger.debug(f"Got presigned url: {presignedURLs}")
67
64
  presignedurl = self.update_presigned_url(presignedURLs, self.base_url)
68
- logger.debug(f"Updated presigned url: {presignedurl}")
69
65
  return presignedurl
70
66
  else:
71
67
  # If POST fails, try GET
72
- response = requests.request(
68
+ response = session_manager.session.request(
73
69
  "GET", endpoint, headers=headers, data=payload, timeout=self.timeout
74
70
  )
75
71
  elapsed_ms = (time.time() - start_time) * 1000
76
72
  logger.debug(
77
73
  f"API Call: [GET] {endpoint} | Status: {response.status_code} | Time: {elapsed_ms:.2f}ms"
78
74
  )
79
- if response.status_code in [200, 201]:
75
+ if response.status_code == 200:
80
76
  presignedURLs = response.json()["data"]["presignedUrls"][0]
81
- logger.debug(f"Got presigned url: {presignedURLs}")
82
77
  presignedurl = self.update_presigned_url(
83
78
  presignedURLs, self.base_url
84
79
  )
85
- logger.debug(f"Updated presigned url: {presignedurl}")
86
80
  return presignedurl
87
81
  elif response.status_code == 401:
88
82
  logger.warning("Received 401 error. Attempting to refresh token.")
@@ -92,7 +86,7 @@ class UploadAgenticTraces:
92
86
  "Authorization": f"Bearer {token}",
93
87
  "X-Project-Name": self.project_name,
94
88
  }
95
- response = requests.request(
89
+ response = session_manager.session.request(
96
90
  "POST",
97
91
  endpoint,
98
92
  headers=headers,
@@ -103,13 +97,11 @@ class UploadAgenticTraces:
103
97
  logger.debug(
104
98
  f"API Call: [POST] {endpoint} | Status: {response.status_code} | Time: {elapsed_ms:.2f}ms"
105
99
  )
106
- if response.status_code in [200, 201]:
100
+ if response.status_code == 200:
107
101
  presignedURLs = response.json()["data"]["presignedUrls"][0]
108
- logger.debug(f"Got presigned url: {presignedURLs}")
109
102
  presignedurl = self.update_presigned_url(
110
103
  presignedURLs, self.base_url
111
104
  )
112
- logger.debug(f"Updated presigned url: {presignedurl}")
113
105
  return presignedurl
114
106
  else:
115
107
  logger.error(
@@ -121,8 +113,10 @@ class UploadAgenticTraces:
121
113
  f"Error while getting presigned url: {response.json()['message']}"
122
114
  )
123
115
  return None
124
-
125
- except requests.exceptions.RequestException as e:
116
+ except (PoolError, MaxRetryError, NewConnectionError, ConnectionError, Timeout) as e:
117
+ session_manager.handle_request_exceptions(e, "getting presigned URL")
118
+ return None
119
+ except RequestException as e:
126
120
  logger.error(f"Error while getting presigned url: {e}")
127
121
  return None
128
122
 
@@ -149,16 +143,16 @@ class UploadAgenticTraces:
149
143
 
150
144
  if "blob.core.windows.net" in presignedUrl: # Azure
151
145
  headers["x-ms-blob-type"] = "BlockBlob"
152
- print("Uploading agentic traces...")
146
+ logger.info("Uploading agentic traces to presigned URL...")
153
147
  try:
154
148
  with open(filename) as f:
155
149
  payload = f.read().replace("\n", "").replace("\r", "").encode()
156
150
  except Exception as e:
157
- print(f"Error while reading file: {e}")
151
+ logger.error(f"Error while reading file: {e}")
158
152
  return False
159
153
  try:
160
154
  start_time = time.time()
161
- response = requests.request(
155
+ response = session_manager.session.request(
162
156
  "PUT", presignedUrl, headers=headers, data=payload, timeout=self.timeout
163
157
  )
164
158
  elapsed_ms = (time.time() - start_time) * 1000
@@ -168,8 +162,11 @@ class UploadAgenticTraces:
168
162
  if response.status_code != 200 or response.status_code != 201:
169
163
  return response, response.status_code
170
164
  return True
171
- except requests.exceptions.RequestException as e:
172
- print(f"Error while uploading to presigned url: {e}")
165
+ except (PoolError, MaxRetryError, NewConnectionError, ConnectionError, Timeout) as e:
166
+ session_manager.handle_request_exceptions(e, "uploading trace to presigned URL")
167
+ return False
168
+ except RequestException as e:
169
+ logger.error(f"Error while uploading trace to presigned url: {e}")
173
170
  return False
174
171
 
175
172
  def insert_traces(self, presignedUrl):
@@ -185,21 +182,18 @@ class UploadAgenticTraces:
185
182
  "datasetSpans": self._get_dataset_spans(), # Extra key for agentic traces
186
183
  }
187
184
  )
188
- logger.debug(f"Inserting agentic traces to presigned url: {presignedUrl}")
189
185
  try:
190
186
  start_time = time.time()
191
187
  endpoint = f"{self.base_url}/v1/llm/insert/trace"
192
- response = requests.request(
188
+ response = session_manager.session.request(
193
189
  "POST", endpoint, headers=headers, data=payload, timeout=self.timeout
194
190
  )
195
- logger.debug(f"Payload: {payload}")
196
- logger.debug(f"Headers: {headers}")
197
191
  elapsed_ms = (time.time() - start_time) * 1000
198
192
  logger.debug(
199
193
  f"API Call: [POST] {endpoint} | Status: {response.status_code} | Time: {elapsed_ms:.2f}ms"
200
194
  )
201
195
  if response.status_code in [200, 201]:
202
- logger.debug("Successfully inserted traces")
196
+ logger.info(f"Traces inserted successfully: {response.json()['message']}")
203
197
  return True
204
198
  elif response.status_code == 401:
205
199
  logger.warning("Received 401 error. Attempting to refresh token.")
@@ -209,7 +203,7 @@ class UploadAgenticTraces:
209
203
  "Content-Type": "application/json",
210
204
  "X-Project-Name": self.project_name,
211
205
  }
212
- response = requests.request(
206
+ response = session_manager.session.request(
213
207
  "POST",
214
208
  endpoint,
215
209
  headers=headers,
@@ -221,24 +215,27 @@ class UploadAgenticTraces:
221
215
  f"API Call: [POST] {endpoint} | Status: {response.status_code} | Time: {elapsed_ms:.2f}ms"
222
216
  )
223
217
  if response.status_code in [200, 201]:
224
- logger.debug("Successfully inserted traces")
218
+ logger.info(f"Traces inserted successfully: {response.json()['message']}")
225
219
  return True
226
220
  else:
227
- logger.debug("Error while inserting traces")
221
+ logger.error(f"Error while inserting traces after 401: {response.json()['message']}")
228
222
  return False
229
223
  else:
230
- logger.debug("Error while inserting traces")
224
+ logger.error(f"Error while inserting traces: {response.json()['message']}")
231
225
  return False
232
- except requests.exceptions.RequestException as e:
233
- logger.debug(f"Error while inserting traces: {e}")
234
- return None
226
+ except (PoolError, MaxRetryError, NewConnectionError, ConnectionError, Timeout) as e:
227
+ session_manager.handle_request_exceptions(e, "inserting traces")
228
+ return False
229
+ except RequestException as e:
230
+ logger.error(f"Error while inserting traces: {e}")
231
+ return False
235
232
 
236
233
  def _get_dataset_spans(self):
237
234
  try:
238
235
  with open(self.json_file_path) as f:
239
236
  data = json.load(f)
240
237
  except Exception as e:
241
- logger.debug(f"Error while reading file: {e}")
238
+ print(f"Error while reading file: {e}")
242
239
  return None
243
240
  try:
244
241
  spans = data["data"][0]["spans"]
@@ -260,41 +257,41 @@ class UploadAgenticTraces:
260
257
  continue
261
258
  return dataset_spans
262
259
  except Exception as e:
263
- logger.debug(f"Error while reading dataset spans: {e}")
260
+ logger.error(f"Error while reading dataset spans: {e}")
264
261
  return None
265
262
 
266
263
  def upload_agentic_traces(self):
267
264
  try:
268
265
  presigned_url = self._get_presigned_url()
269
266
  if presigned_url is None:
270
- logger.debug("Warning: Failed to obtain presigned URL")
267
+ logger.warning("Warning: Failed to obtain presigned URL")
271
268
  return False
272
269
 
273
270
  # Upload the file using the presigned URL
274
271
  upload_result = self._put_presigned_url(presigned_url, self.json_file_path)
275
272
  if not upload_result:
276
- logger.debug("Error: Failed to upload file to presigned URL")
273
+ logger.error("Error: Failed to upload file to presigned URL")
277
274
  return False
278
275
  elif isinstance(upload_result, tuple):
279
276
  response, status_code = upload_result
280
277
  if status_code not in [200, 201]:
281
- logger.debug(
282
- f"Error: Upload failed with status code {status_code}: {response.text if hasattr(response, 'text') else 'Unknown error'}")
278
+ logger.error(
279
+ f"Error: Uploading agentic traces failed with status code {status_code}: {response.text if hasattr(response, 'text') else 'Unknown error'}")
283
280
  return False
284
281
  # Insert trace records
285
282
  insert_success = self.insert_traces(presigned_url)
286
283
  if not insert_success:
287
- logger.debug("Error: Failed to insert trace records")
284
+ print("Error: Failed to insert trace records")
288
285
  return False
289
286
 
290
- logger.debug("Successfully uploaded agentic traces")
287
+ logger.info("Successfully uploaded agentic traces")
291
288
  return True
292
289
  except FileNotFoundError:
293
- logger.debug(f"Error: Trace file not found at {self.json_file_path}")
290
+ logger.error(f"Error: Trace file not found at {self.json_file_path}")
294
291
  return False
295
292
  except ConnectionError as e:
296
- logger.debug(f"Error: Network connection failed while uploading traces: {e}")
293
+ logger.error(f"Error: Network connection failed while uploading traces: {e}")
297
294
  return False
298
295
  except Exception as e:
299
- logger.debug(f"Error while uploading agentic traces: {e}")
296
+ logger.error(f"Error while uploading agentic traces: {e}")
300
297
  return False
@@ -1,15 +1,18 @@
1
- import json
2
1
  import logging
3
2
  import os
4
3
  import time
4
+ import re
5
+ import json
6
+ from urllib.parse import urlparse, urlunparse
7
+ from urllib3.exceptions import PoolError, MaxRetryError, NewConnectionError
8
+ from requests.exceptions import ConnectionError, Timeout, RequestException
5
9
 
6
10
  import requests
7
11
 
8
12
  from ragaai_catalyst.ragaai_catalyst import RagaAICatalyst
13
+ from .session_manager import session_manager
9
14
 
10
15
  logger = logging.getLogger(__name__)
11
- import re
12
- from urllib.parse import urlparse, urlunparse
13
16
 
14
17
 
15
18
  def upload_code(
@@ -19,11 +22,26 @@ def upload_code(
19
22
  project_name, dataset_name, base_url, timeout=timeout
20
23
  )
21
24
 
25
+ # Handle None case during exceptions - do not proceed
26
+ if code_hashes_list is None:
27
+ logger.error("Failed to fetch existing code hashes, cannot proceed with upload")
28
+ return None
29
+
22
30
  if hash_id not in code_hashes_list:
23
31
  presigned_url = _fetch_presigned_url(
24
32
  project_name, dataset_name, base_url, timeout=timeout
25
33
  )
26
- _put_zip_presigned_url(project_name, presigned_url, zip_path, timeout=timeout)
34
+ # Handle None case for presigned URL
35
+ if presigned_url is None:
36
+ logger.error("Failed to fetch presigned URL, cannot proceed with upload")
37
+ return None
38
+
39
+ upload_result = _put_zip_presigned_url(project_name, presigned_url, zip_path, timeout=timeout)
40
+
41
+ # Handle upload failure
42
+ if upload_result is False or (isinstance(upload_result, tuple) and upload_result[1] not in [200, 201]):
43
+ logger.error("Failed to upload zip file")
44
+ return None
27
45
 
28
46
  response = _insert_code(
29
47
  dataset_name,
@@ -33,6 +51,10 @@ def upload_code(
33
51
  base_url,
34
52
  timeout=timeout,
35
53
  )
54
+ # Handle None response from insert_code
55
+ if response is None:
56
+ logger.error("Failed to insert code metadata")
57
+ return None
36
58
  return response
37
59
  else:
38
60
  return "Code already exists"
@@ -49,7 +71,7 @@ def _fetch_dataset_code_hashes(project_name, dataset_name, base_url=None, timeou
49
71
  url_base = base_url if base_url is not None else RagaAICatalyst.BASE_URL
50
72
  start_time = time.time()
51
73
  endpoint = f"{url_base}/v2/llm/dataset/code?datasetName={dataset_name}"
52
- response = requests.request(
74
+ response = session_manager.session.request(
53
75
  "GET", endpoint, headers=headers, data=payload, timeout=timeout
54
76
  )
55
77
  elapsed_ms = (time.time() - start_time) * 1000
@@ -57,7 +79,7 @@ def _fetch_dataset_code_hashes(project_name, dataset_name, base_url=None, timeou
57
79
  f"API Call: [GET] {endpoint} | Status: {response.status_code} | Time: {elapsed_ms:.2f}ms"
58
80
  )
59
81
 
60
- if response.status_code == 200:
82
+ if response.status_code in [200, 201]:
61
83
  return response.json()["data"]["codeHashes"]
62
84
  elif response.status_code == 401:
63
85
  logger.warning("Received 401 error. Attempting to refresh token.")
@@ -66,22 +88,25 @@ def _fetch_dataset_code_hashes(project_name, dataset_name, base_url=None, timeou
66
88
  "Authorization": f"Bearer {os.getenv('RAGAAI_CATALYST_TOKEN')}",
67
89
  "X-Project-Name": project_name,
68
90
  }
69
- response = requests.request(
91
+ response = session_manager.session.request(
70
92
  "GET", endpoint, headers=headers, data=payload, timeout=timeout
71
93
  )
72
94
  elapsed_ms = (time.time() - start_time) * 1000
73
- logger.debug(
74
- f"API Call: [GET] {endpoint} | Status: {response.status_code} | Time: {elapsed_ms:.2f}ms"
75
- )
76
- if response.status_code == 200:
95
+ logger.debug(f"API Call: [GET] {endpoint} | Status: {response.status_code} | Time: {elapsed_ms:.2f}ms")
96
+ if response.status_code in [200, 201]:
77
97
  return response.json()["data"]["codeHashes"]
78
98
  else:
79
- logger.error(
80
- f"Failed to fetch code hashes: {response.json()['message']}"
81
- )
82
- except requests.exceptions.RequestException as e:
99
+ logger.error(f"Failed to fetch code hashes: {response.json()['message']}")
100
+ return None
101
+ else:
102
+ logger.error(f"Error while fetching dataset code hashes: {response.json()['message']}")
103
+ return None
104
+ except (PoolError, MaxRetryError, NewConnectionError, ConnectionError, Timeout) as e:
105
+ session_manager.handle_request_exceptions(e, "fetching dataset code hashes")
106
+ return None
107
+ except RequestException as e:
83
108
  logger.error(f"Failed to list datasets: {e}")
84
- pass
109
+ return None
85
110
 
86
111
 
87
112
  def update_presigned_url(presigned_url, base_url):
@@ -156,7 +181,7 @@ def _fetch_presigned_url(project_name, dataset_name, base_url=None, timeout=120)
156
181
  logger.debug(
157
182
  f"API Call: [POST] {endpoint} | Status: {response.status_code} | Time: {elapsed_ms:.2f}ms"
158
183
  )
159
- if response.status_code == 200:
184
+ if response.status_code in [200, 201]:
160
185
  presigned_url = response.json()["data"]["presignedUrls"][0]
161
186
  presigned_url = update_presigned_url(presigned_url, url_base)
162
187
  return presigned_url
@@ -168,9 +193,10 @@ def _fetch_presigned_url(project_name, dataset_name, base_url=None, timeout=120)
168
193
  logger.error(
169
194
  f"Failed to fetch code hashes: {response.json()['message']}"
170
195
  )
196
+ return None
171
197
  except requests.exceptions.RequestException as e:
172
198
  logger.error(f"Failed to list datasets: {e}")
173
- pass
199
+ return None
174
200
 
175
201
 
176
202
  def _put_zip_presigned_url(project_name, presignedUrl, filename, timeout=120):
@@ -181,21 +207,28 @@ def _put_zip_presigned_url(project_name, presignedUrl, filename, timeout=120):
181
207
 
182
208
  if "blob.core.windows.net" in presignedUrl: # Azure
183
209
  headers["x-ms-blob-type"] = "BlockBlob"
184
- print("Uploading code...")
185
- with open(filename, "rb") as f:
186
- payload = f.read()
187
-
188
- start_time = time.time()
189
- response = requests.request(
190
- "PUT", presignedUrl, headers=headers, data=payload, timeout=timeout
191
- )
192
- elapsed_ms = (time.time() - start_time) * 1000
193
- logger.debug(
194
- f"API Call: [PUT] {presignedUrl} | Status: {response.status_code} | Time: {elapsed_ms:.2f}ms"
195
- )
196
- if response.status_code != 200 or response.status_code != 201:
197
- return response, response.status_code
210
+ logger.info("Uploading code to presigned URL...")
211
+ try:
212
+ with open(filename, "rb") as f:
213
+ payload = f.read()
198
214
 
215
+ start_time = time.time()
216
+ response = session_manager.session.request(
217
+ "PUT", presignedUrl, headers=headers, data=payload, timeout=timeout
218
+ )
219
+ elapsed_ms = (time.time() - start_time) * 1000
220
+ logger.debug(
221
+ f"API Call: [PUT] {presignedUrl} | Status: {response.status_code} | Time: {elapsed_ms:.2f}ms"
222
+ )
223
+ if response.status_code not in [200, 201]:
224
+ return response, response.status_code
225
+ return True
226
+ except (PoolError, MaxRetryError, NewConnectionError, ConnectionError, Timeout) as e:
227
+ session_manager.handle_request_exceptions(e, "uploading zip to presigned URL")
228
+ return False
229
+ except RequestException as e:
230
+ logger.error(f"Failed to upload zip: {e}")
231
+ return False
199
232
 
200
233
  def _insert_code(
201
234
  dataset_name, hash_id, presigned_url, project_name, base_url=None, timeout=120
@@ -218,39 +251,43 @@ def _insert_code(
218
251
  url_base = base_url if base_url is not None else RagaAICatalyst.BASE_URL
219
252
  start_time = time.time()
220
253
  endpoint = f"{url_base}/v2/llm/dataset/code"
221
- response = requests.request(
254
+ response = session_manager.session.request(
222
255
  "POST", endpoint, headers=headers, data=payload, timeout=timeout
223
256
  )
224
257
  elapsed_ms = (time.time() - start_time) * 1000
225
258
  logger.debug(
226
259
  f"API Call: [POST] {endpoint} | Status: {response.status_code} | Time: {elapsed_ms:.2f}ms"
227
260
  )
228
- if response.status_code == 200:
261
+ if response.status_code in [200, 201]:
229
262
  return response.json()["message"]
230
263
 
231
264
  elif response.status_code == 401:
232
- logger.warning("Received 401 error. Attempting to refresh token.")
265
+ logger.warning("Received 401 error during inserting code. Attempting to refresh token.")
233
266
  token = RagaAICatalyst.get_token(force_refresh=True)
234
267
  headers = {
235
268
  "X-Project-Name": project_name,
236
269
  "Content-Type": "application/json",
237
270
  "Authorization": f"Bearer {token}",
238
271
  }
239
- response = requests.request(
272
+ response = session_manager.session.request(
240
273
  "POST", endpoint, headers=headers, data=payload, timeout=timeout
241
274
  )
242
275
  elapsed_ms = (time.time() - start_time) * 1000
243
276
  logger.debug(
244
277
  f"API Call: [POST] {endpoint} | Status: {response.status_code} | Time: {elapsed_ms:.2f}ms"
245
278
  )
246
- if response.status_code == 200:
279
+ if response.status_code in [200, 201]:
280
+ logger.info(f"Code inserted successfully after 401: {response.json()['message']}")
247
281
  return response.json()["message"]
248
282
  else:
249
- logger.error(f"Failed to insert code: {response.json()['message']}")
250
- pass
283
+ logger.error(f"Failed to insert code after 401: {response.json()['message']}")
284
+ return None
251
285
  else:
252
286
  logger.error(f"Failed to insert code: {response.json()['message']}")
253
- pass
254
- except requests.exceptions.RequestException as e:
287
+ return None
288
+ except (PoolError, MaxRetryError, NewConnectionError, ConnectionError, Timeout) as e:
289
+ session_manager.handle_request_exceptions(e, "inserting code")
290
+ return None
291
+ except RequestException as e:
255
292
  logger.error(f"Failed to insert code: {e}")
256
- pass
293
+ return None
@@ -19,7 +19,7 @@ from ragaai_catalyst.tracers.agentic_tracing.utils.zip_list_of_unique_files impo
19
19
  )
20
20
  from ragaai_catalyst.tracers.utils.trace_json_converter import convert_json_format
21
21
 
22
- logger = logging.getLogger(__name__)
22
+ logger = logging.getLogger("RagaAICatalyst")
23
23
  logging_level = (
24
24
  logger.setLevel(logging.DEBUG) if os.getenv("DEBUG") == "1" else logging.INFO
25
25
  )
@@ -46,7 +46,6 @@ class RAGATraceExporter(SpanExporter):
46
46
  self.external_id = external_id
47
47
 
48
48
  def export(self, spans):
49
- logger.debug("Starting export of span: ")
50
49
  for span in spans:
51
50
  try:
52
51
  span_json = json.loads(span.to_json())
@@ -61,11 +60,8 @@ class RAGATraceExporter(SpanExporter):
61
60
 
62
61
  if span_json["parent_id"] is None:
63
62
  trace = self.trace_spans[trace_id]
64
- logger.debug("End of trace found: ")
65
63
  try:
66
- logger.debug("Started processing complete trace: ")
67
64
  self.process_complete_trace(trace, trace_id)
68
- logger.debug("Completed processing complete trace: ")
69
65
  except Exception as e:
70
66
  logger.error(f"Error processing complete trace: {e}")
71
67
  try:
@@ -88,11 +84,9 @@ class RAGATraceExporter(SpanExporter):
88
84
  def process_complete_trace(self, spans, trace_id):
89
85
  # Convert the trace to ragaai trace format
90
86
  try:
91
- logger.debug("Started preparing trace to trace format: ")
92
87
  ragaai_trace_details = self.prepare_trace(spans, trace_id)
93
- logger.debug("Completed preparing trace to trace format: ")
94
88
  except Exception as e:
95
- logger.error(f"Error preparing trace {trace_id}: {e}")
89
+ print(f"Error converting trace {trace_id}: {e}")
96
90
  return # Exit early if conversion fails
97
91
 
98
92
  # Check if trace details are None (conversion failed)
@@ -102,118 +96,98 @@ class RAGATraceExporter(SpanExporter):
102
96
 
103
97
  # Upload the trace if upload_trace function is provided
104
98
  try:
105
- logger.debug("Started uploading trace: ")
106
99
  if self.post_processor!=None:
107
100
  ragaai_trace_details['trace_file_path'] = self.post_processor(ragaai_trace_details['trace_file_path'])
108
101
  self.upload_trace(ragaai_trace_details, trace_id)
109
- logger.debug("Completed uploading trace: ")
110
102
  except Exception as e:
111
- logger.error(f"Error uploading trace {trace_id}: {e}")
103
+ print(f"Error uploading trace {trace_id}: {e}")
112
104
 
113
105
  def prepare_trace(self, spans, trace_id):
114
106
  try:
115
107
  try:
116
- logger.debug("Started converting trace to trace format: ")
117
108
  ragaai_trace = convert_json_format(spans, self.custom_model_cost, self.user_context, self.user_gt,self.external_id)
118
- logger.debug("Completed converting trace to trace format: ")
119
109
  except Exception as e:
120
- logger.error(f"Error in convert_json_format function: {trace_id}: {e}")
110
+ print(f"Error in convert_json_format function: {trace_id}: {e}")
121
111
  return None
122
112
 
123
113
  try:
124
- logger.debug("Started formatting interactions: ")
125
114
  interactions = format_interactions(ragaai_trace)
126
115
  ragaai_trace["workflow"] = interactions['workflow']
127
- logger.debug("Completed formatting interactions: ")
128
116
  except Exception as e:
129
- logger.error(f"Error in format_interactions function: {trace_id}: {e}")
117
+ print(f"Error in format_interactions function: {trace_id}: {e}")
130
118
  return None
131
119
 
132
- # try:
133
- # logger.debug("Started zipping source code: ")
134
- # # Add source code hash
135
- # hash_id, zip_path = zip_list_of_unique_files(
136
- # self.files_to_zip, output_dir=self.tmp_dir
137
- # )
138
- # logger.debug("Completed zipping source code: ")
139
- # except Exception as e:
140
- # logger.error(f"Error in zip_list_of_unique_files function: {trace_id}: {e}")
141
- # return None
120
+ try:
121
+ # Add source code hash
122
+ hash_id, zip_path = zip_list_of_unique_files(
123
+ self.files_to_zip, output_dir=self.tmp_dir
124
+ )
125
+ except Exception as e:
126
+ print(f"Error in zip_list_of_unique_files function: {trace_id}: {e}")
127
+ return None
142
128
 
143
129
  try:
144
- logger.debug("Started adding system info: ")
145
130
  ragaai_trace["metadata"]["system_info"] = asdict(self.system_monitor.get_system_info())
146
131
  ragaai_trace["metadata"]["resources"] = asdict(self.system_monitor.get_resources())
147
- logger.debug("Completed adding system info: ")
148
132
  except Exception as e:
149
- logger.error(f"Error in get_system_info or get_resources function: {trace_id}: {e}")
133
+ print(f"Error in get_system_info or get_resources function: {trace_id}: {e}")
150
134
  return None
151
135
 
152
136
  try:
153
- logger.debug("Started adding source code hash: ")
154
- ragaai_trace["metadata"]["system_info"]["source_code"] = ""
155
- logger.debug("Completed adding source code hash: ")
137
+ ragaai_trace["metadata"]["system_info"]["source_code"] = hash_id
156
138
  except Exception as e:
157
- logger.error(f"Error in adding source code hash: {trace_id}: {e}")
139
+ print(f"Error in adding source code hash: {trace_id}: {e}")
158
140
  return None
159
141
 
160
142
  try:
161
143
  ragaai_trace["data"][0]["start_time"] = ragaai_trace["start_time"]
162
144
  ragaai_trace["data"][0]["end_time"] = ragaai_trace["end_time"]
163
145
  except Exception as e:
164
- logger.error(f"Error in adding start_time or end_time: {trace_id}: {e}")
146
+ print(f"Error in adding start_time or end_time: {trace_id}: {e}")
165
147
  return None
166
148
 
167
149
  try:
168
- logger.debug("Started adding project name: ")
169
150
  ragaai_trace["project_name"] = self.project_name
170
- logger.debug("Completed adding project name: ")
171
151
  except Exception as e:
172
- logger.error(f"Error in adding project name: {trace_id}: {e}")
152
+ print(f"Error in adding project name: {trace_id}: {e}")
173
153
  return None
174
154
 
175
155
  try:
176
- logger.debug("Started adding tracer type: ")
177
156
  # Add tracer type to the trace
178
157
  ragaai_trace["tracer_type"] = self.tracer_type
179
- logger.debug("Completed adding tracer type: ")
180
158
  except Exception as e:
181
- logger.error(f"Error in adding tracer type: {trace_id}: {e}")
159
+ print(f"Error in adding tracer type: {trace_id}: {e}")
182
160
  return None
183
161
 
184
162
  #Add user passed metadata to the trace
185
163
  try:
186
- logger.debug("Started adding user passed metadata: ")
187
164
  if self.user_details.get("trace_user_detail").get("metadata") and isinstance(self.user_details.get("trace_user_detail").get("metadata"), dict):
188
165
  for key, value in self.user_details.get("trace_user_detail").get("metadata").items():
189
166
  if key in ["log_source", "recorded_on"]:
190
167
  continue
191
168
  ragaai_trace["metadata"][key] = value
192
- logger.debug("Completed adding user passed metadata: ")
193
169
  except Exception as e:
194
- logger.error(f"Error in adding metadata: {trace_id}: {e}")
170
+ print(f"Error in adding metadata: {trace_id}: {e}")
195
171
  return None
196
172
 
197
173
  try:
198
- logger.debug("Started saving trace json: ")
199
174
  # Save the trace_json
200
175
  trace_file_path = os.path.join(self.tmp_dir, f"{trace_id}.json")
201
176
  with open(trace_file_path, "w") as file:
202
177
  json.dump(ragaai_trace, file, cls=TracerJSONEncoder, indent=2)
203
178
  with open(os.path.join(os.getcwd(), 'rag_agent_traces.json'), 'w') as f:
204
179
  json.dump(ragaai_trace, f, cls=TracerJSONEncoder, indent=2)
205
- logger.debug("Completed saving trace json: ")
206
180
  except Exception as e:
207
- logger.error(f"Error in saving trace json: {trace_id}: {e}")
181
+ print(f"Error in saving trace json: {trace_id}: {e}")
208
182
  return None
209
183
 
210
184
  return {
211
185
  'trace_file_path': trace_file_path,
212
- 'code_zip_path': "zip_path",
213
- 'hash_id': "absdsjkdhsjkfhjkdshfkjdshfjdsh"
186
+ 'code_zip_path': zip_path,
187
+ 'hash_id': hash_id
214
188
  }
215
189
  except Exception as e:
216
- logger.error(f"Error converting trace {trace_id}: {str(e)}")
190
+ print(f"Error converting trace {trace_id}: {str(e)}")
217
191
  return None
218
192
 
219
193
  def upload_trace(self, ragaai_trace_details, trace_id):
@@ -229,6 +203,7 @@ class RAGATraceExporter(SpanExporter):
229
203
  dataset_name=self.dataset_name,
230
204
  user_details=self.user_details,
231
205
  base_url=self.base_url,
206
+ tracer_type=self.tracer_type,
232
207
  timeout=self.timeout
233
208
  )
234
209
 
@@ -127,11 +127,9 @@ class Tracer(AgenticTracing):
127
127
  self.model_custom_cost = {}
128
128
  super().__init__(user_detail=user_detail, auto_instrumentation=auto_instrumentation)
129
129
 
130
- logger.debug(f"Setting up Tracer instance with project: {project_name}, dataset: {dataset_name}")
131
130
  self.project_name = project_name
132
131
  self.dataset_name = dataset_name
133
132
  self.tracer_type = tracer_type
134
- logger.debug(f"Tracer type set to: {tracer_type}")
135
133
  self.metadata = self._improve_metadata(metadata, tracer_type)
136
134
  # self.metadata["total_cost"] = 0.0
137
135
  # self.metadata["total_tokens"] = 0
@@ -148,16 +146,12 @@ class Tracer(AgenticTracing):
148
146
  self.file_tracker = TrackName()
149
147
  self.post_processor = None
150
148
  self.max_upload_workers = max_upload_workers
151
- logger.debug(f"Max upload workers: {self.max_upload_workers}")
152
149
  self.user_details = self._pass_user_data()
153
150
  self.update_llm_cost = update_llm_cost
154
151
  self.auto_instrumentation = auto_instrumentation
155
152
  self.external_id = external_id
156
- if external_id:
157
- logger.debug(f"External ID provided: {external_id}")
158
153
 
159
154
  try:
160
- logger.debug(f"Fetching projects list from {self.base_url}/v2/llm/projects")
161
155
  response = requests.get(
162
156
  f"{self.base_url}/v2/llm/projects?size={self.num_projects}",
163
157
  headers={
@@ -171,13 +165,8 @@ class Tracer(AgenticTracing):
171
165
  project_list = [
172
166
  project["name"] for project in response.json()["data"]["content"]
173
167
  ]
174
- logger.debug(f"Found {len(project_list)} projects")
175
168
  if project_name not in project_list:
176
- logger.warning(f"Project '{project_name}' not found in available projects")
177
- logger.debug(f"Available projects: {project_list}")
178
- else:
179
- logger.debug(f"Project '{project_name}' found in available projects")
180
-
169
+ logger.error("Project not found. Please enter a valid project name")
181
170
 
182
171
  self.project_id = [
183
172
  project["id"] for project in response.json()["data"]["content"] if project["name"] == project_name
@@ -188,7 +177,6 @@ class Tracer(AgenticTracing):
188
177
 
189
178
  except requests.exceptions.RequestException as e:
190
179
  logger.error(f"Failed to retrieve projects list: {e}")
191
- logger.debug(f"Request exception details: {str(e)}, URL: {self.base_url}/v2/llm/projects")
192
180
 
193
181
  # if tracer_type == "langchain":
194
182
  # instrumentors = []
@@ -203,16 +191,13 @@ class Tracer(AgenticTracing):
203
191
  # from openinference.instrumentation.langchain import LangChainInstrumentor
204
192
  # instrumentors += [(LangChainInstrumentor, [])]
205
193
  # self._setup_agentic_tracer(instrumentors)
206
-
207
194
  # Handle agentic tracers
208
- logger.debug(f"Starting Instrumentation for tracer type: {tracer_type}")
209
195
  if tracer_type == "agentic" or tracer_type.startswith("agentic/") or tracer_type == "langchain":
210
196
  # Setup instrumentors based on tracer type
211
197
  instrumentors = []
212
198
 
213
199
  # Add LLM Instrumentors
214
200
  if tracer_type in ['agentic/crewai']:
215
- logger.debug("Setting up instrumentors for CrewAI")
216
201
  try:
217
202
  from openinference.instrumentation.vertexai import VertexAIInstrumentor
218
203
  instrumentors.append((VertexAIInstrumentor, []))
@@ -325,38 +310,31 @@ class Tracer(AgenticTracing):
325
310
  elif tracer_type == "agentic/llamaindex" or tracer_type == "llamaindex":
326
311
  from openinference.instrumentation.llama_index import LlamaIndexInstrumentor
327
312
  instrumentors += [(LlamaIndexInstrumentor, [])]
328
- logger.info("Instrumenting LlamaIndex...")
329
313
 
330
314
  elif tracer_type == "agentic/langchain" or tracer_type == "agentic/langgraph" or tracer_type == "langchain":
331
315
  from openinference.instrumentation.langchain import LangChainInstrumentor
332
316
  instrumentors += [(LangChainInstrumentor, [])]
333
- logger.info("Instrumenting LangChain...")
334
317
 
335
318
  elif tracer_type == "agentic/crewai":
336
319
  from openinference.instrumentation.crewai import CrewAIInstrumentor
337
320
  from openinference.instrumentation.langchain import LangChainInstrumentor
338
321
  instrumentors += [(CrewAIInstrumentor, []), (LangChainInstrumentor, [])]
339
- logger.info("Instrumenting CrewAI...")
340
322
 
341
323
  elif tracer_type == "agentic/haystack":
342
324
  from openinference.instrumentation.haystack import HaystackInstrumentor
343
325
  instrumentors += [(HaystackInstrumentor, [])]
344
- logger.info("Instrumenting Haystack...")
345
326
 
346
327
  elif tracer_type == "agentic/autogen":
347
328
  from openinference.instrumentation.autogen import AutogenInstrumentor
348
329
  instrumentors += [(AutogenInstrumentor, [])]
349
- logger.info("Instrumenting Autogen...")
350
330
 
351
331
  elif tracer_type == "agentic/smolagents":
352
332
  from openinference.instrumentation.smolagents import SmolagentsInstrumentor
353
333
  instrumentors += [(SmolagentsInstrumentor, [])]
354
- logger.info("Instrumenting Smolagents...")
355
334
 
356
335
  elif tracer_type == "agentic/openai_agents":
357
336
  from openinference.instrumentation.openai_agents import OpenAIAgentsInstrumentor
358
337
  instrumentors += [(OpenAIAgentsInstrumentor, [])]
359
- logger.info("Instrumenting OpenAI Agents...")
360
338
 
361
339
  else:
362
340
  # Unknown agentic tracer type
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ragaai_catalyst
3
- Version: 2.2.4.1b4
3
+ Version: 2.2.4.1b5
4
4
  Summary: RAGA AI CATALYST
5
5
  Author-email: Kiran Scaria <kiran.scaria@raga.ai>, Kedar Gaikwad <kedar.gaikwad@raga.ai>, Dushyant Mahajan <dushyant.mahajan@raga.ai>, Siddhartha Kosti <siddhartha.kosti@raga.ai>, Ritika Goel <ritika.goel@raga.ai>, Vijay Chaurasia <vijay.chaurasia@raga.ai>, Tushar Kumar <tushar.kumar@raga.ai>, Rishabh Pandey <rishabh.pandey@raga.ai>, Jyotsana C G <jyotsana@raga.ai>
6
6
  Requires-Python: <=3.13.2,>=3.10
@@ -31,7 +31,7 @@ ragaai_catalyst/tracers/distributed.py,sha256=CGPuOh4CsgEk428PPibieLaAG2Tt3BVygF
31
31
  ragaai_catalyst/tracers/langchain_callback.py,sha256=CB75zzG3-DkYTELj0vI1MOHQTY0MuQJfoHIXz9Cl8S8,34568
32
32
  ragaai_catalyst/tracers/llamaindex_callback.py,sha256=ZY0BJrrlz-P9Mg2dX-ZkVKG3gSvzwqBtk7JL_05MiYA,14028
33
33
  ragaai_catalyst/tracers/llamaindex_instrumentation.py,sha256=Ys_jLkvVqo12bKgXDmkp4TxJu9HkBATrFE8cIcTYxWw,14329
34
- ragaai_catalyst/tracers/tracer.py,sha256=2JmeM9OkxNyS6XG0Ogqhx8q9lvy3vNLJnEVH2Vg2RNM,42768
34
+ ragaai_catalyst/tracers/tracer.py,sha256=hxVJN45CtIeU8Dc5G1kreXJa7Vv_3buBAHVz-Q3buKo,41435
35
35
  ragaai_catalyst/tracers/upload_traces.py,sha256=w1clGGfdOMpStUJX40NAlxe6dcFdN4pwcezyII0bGYA,6994
36
36
  ragaai_catalyst/tracers/agentic_tracing/README.md,sha256=X4QwLb7-Jg7GQMIXj-SerZIgDETfw-7VgYlczOR8ZeQ,4508
37
37
  ragaai_catalyst/tracers/agentic_tracing/__init__.py,sha256=yf6SKvOPSpH-9LiKaoLKXwqj5sez8F_5wkOb91yp0oE,260
@@ -54,9 +54,10 @@ ragaai_catalyst/tracers/agentic_tracing/tracers/network_tracer.py,sha256=m8CxYkl
54
54
  ragaai_catalyst/tracers/agentic_tracing/tracers/tool_tracer.py,sha256=xxrliKPfdfbIZRZqMnUewsaTD8_Hv0dbuoBivNZGD4U,21674
55
55
  ragaai_catalyst/tracers/agentic_tracing/tracers/user_interaction_tracer.py,sha256=bhSUhNQCuJXKjgJAXhjKEYjnHMpYN90FSZdR84fNIKU,4614
56
56
  ragaai_catalyst/tracers/agentic_tracing/upload/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
57
- ragaai_catalyst/tracers/agentic_tracing/upload/trace_uploader.py,sha256=iMUMFR9XVipCBunpv8_No8bCoP3lqG47M5dg-ugibWo,21006
58
- ragaai_catalyst/tracers/agentic_tracing/upload/upload_agentic_traces.py,sha256=KOtnB-QFpVFD0zKpJ2epOq8r0tSdFPRKe0rTA53A5Zo,12738
59
- ragaai_catalyst/tracers/agentic_tracing/upload/upload_code.py,sha256=2mxdi7k_SoDqQUFo1oQ__28CpmSIvVugYcbuRltUK9Q,9920
57
+ ragaai_catalyst/tracers/agentic_tracing/upload/session_manager.py,sha256=xgheT_XV2PFov709V0J5DwytW9-muvZnPTjbMsurGAw,5335
58
+ ragaai_catalyst/tracers/agentic_tracing/upload/trace_uploader.py,sha256=Ujbu0KDl7oDr-cFtLwrQK_i7ghMuPV92mFnRfobJ1aI,24822
59
+ ragaai_catalyst/tracers/agentic_tracing/upload/upload_agentic_traces.py,sha256=vH9at3012iNrNIA30TMr7qLyvWtKyZn9wpd5esmBg0A,12866
60
+ ragaai_catalyst/tracers/agentic_tracing/upload/upload_code.py,sha256=bpzL-eNCUaqXimSg7nl5YB0KlHbS_2sNvJTfKnfRjek,12027
60
61
  ragaai_catalyst/tracers/agentic_tracing/upload/upload_local_metric.py,sha256=m1O8lKpxKwtHofXLW3fTHX5yfqDW5GxoveARlg5cTw4,2571
61
62
  ragaai_catalyst/tracers/agentic_tracing/utils/__init__.py,sha256=XdB3X_ufe4RVvGorxSqAiB9dYv4UD7Hvvuw3bsDUppY,60
62
63
  ragaai_catalyst/tracers/agentic_tracing/utils/api_utils.py,sha256=ZduFA7MmTnWfQ2FzSD0hxMAAfNNTgBs4CXcHZdXJv6k,749
@@ -76,7 +77,7 @@ ragaai_catalyst/tracers/exporters/__init__.py,sha256=wQbaqyeIjVZxYprHCKZ9BeiqxeX
76
77
  ragaai_catalyst/tracers/exporters/dynamic_trace_exporter.py,sha256=Rm-QaLv1qMAKpHKcFOcK_HWaKHwFBoUH45_4QYipE-g,6843
77
78
  ragaai_catalyst/tracers/exporters/file_span_exporter.py,sha256=NZsD3rShUiC3rO9y3Y2vqEtS3MO51FXZy0p3q9cdDNY,6403
78
79
  ragaai_catalyst/tracers/exporters/raga_exporter.py,sha256=l-RfysTIXYxtvYkVlJbRvg-AzJbT4Fdb-YiZh0mfuDs,17868
79
- ragaai_catalyst/tracers/exporters/ragaai_trace_exporter.py,sha256=UNoXvMTJ2PArlcNWBk424WLQt7i5BZGGwztFo18iqlc,10800
80
+ ragaai_catalyst/tracers/exporters/ragaai_trace_exporter.py,sha256=VxO96ldBpG5mCncrN5mXErIZMlxQ1ewhNoMLfCrzegM,9025
80
81
  ragaai_catalyst/tracers/instrumentators/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
81
82
  ragaai_catalyst/tracers/utils/__init__.py,sha256=KeMaZtYaTojilpLv65qH08QmpYclfpacDA0U3wg6Ybw,64
82
83
  ragaai_catalyst/tracers/utils/convert_langchain_callbacks_output.py,sha256=SehrD7q8ytAiUYoWr406b4mWs3Lk0Rcy6Ekkihh22TI,1703
@@ -88,8 +89,8 @@ ragaai_catalyst/tracers/utils/rag_extraction_logic_final.py,sha256=3ygkRT__lLDRf
88
89
  ragaai_catalyst/tracers/utils/rag_trace_json_converter.py,sha256=54IEZO-YRjUAahV5nw8KClXqTF1LhfDry_TsZ4KGow4,20467
89
90
  ragaai_catalyst/tracers/utils/trace_json_converter.py,sha256=-HZVmijeUFLO7e9OAvi1RJdWVTxPRUHPd1MkKQlCD54,11785
90
91
  ragaai_catalyst/tracers/utils/utils.py,sha256=o-p9n2ZuophdrV0wrixu-BqRHCkovup_klc3mS8mU8g,2374
91
- ragaai_catalyst-2.2.4.1b4.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
92
- ragaai_catalyst-2.2.4.1b4.dist-info/METADATA,sha256=TOTjSMMYeaIMLvUPryfxf5AjEmbox9aTJapUJEUEFtQ,17681
93
- ragaai_catalyst-2.2.4.1b4.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
94
- ragaai_catalyst-2.2.4.1b4.dist-info/top_level.txt,sha256=HpgsdRgEJMk8nqrU6qdCYk3di7MJkDL0B19lkc7dLfM,16
95
- ragaai_catalyst-2.2.4.1b4.dist-info/RECORD,,
92
+ ragaai_catalyst-2.2.4.1b5.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
93
+ ragaai_catalyst-2.2.4.1b5.dist-info/METADATA,sha256=aZAvm_cDpbl_xbOO6d9Lp2kMLmRmdiViDe6EIWDufaI,17681
94
+ ragaai_catalyst-2.2.4.1b5.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
95
+ ragaai_catalyst-2.2.4.1b5.dist-info/top_level.txt,sha256=HpgsdRgEJMk8nqrU6qdCYk3di7MJkDL0B19lkc7dLfM,16
96
+ ragaai_catalyst-2.2.4.1b5.dist-info/RECORD,,