| 145 | auth_thread.start() |
| 146 | |
| 147 | def init(self, **kwargs: Any) -> None: # Return type updated to None |
| 148 | # Recreate the Config object to parse environment variables at the time of initialization |
| 149 | # This allows re-init with new env vars if needed, though true singletons usually init once. |
| 150 | self.config = Config() |
| 151 | self.configure(**kwargs) |
| 152 | |
| 153 | # Only treat as re-initialization if a different non-None API key is explicitly provided |
| 154 | provided_api_key = kwargs.get("api_key") |
| 155 | if self.initialized and provided_api_key is not None and provided_api_key != self.config.api_key: |
| 156 | logger.warning("AgentOps Client being re-initialized with a different API key. This is unusual.") |
| 157 | # Reset initialization status to allow re-init with new key/config |
| 158 | self._initialized = False |
| 159 | if self._init_trace_context and self._init_trace_context.span.is_recording(): |
| 160 | logger.warning("Ending previously auto-started trace due to re-initialization.") |
| 161 | tracer.end_trace(self._init_trace_context, "Reinitialized") |
| 162 | self._init_trace_context = None |
| 163 | self._legacy_session_for_init_trace = None |
| 164 | |
| 165 | if self.initialized: |
| 166 | logger.debug("AgentOps Client already initialized.") |
| 167 | # If auto_start_session was true, return the existing legacy session wrapper |
| 168 | if self.config.auto_start_session: |
| 169 | return self._legacy_session_for_init_trace |
| 170 | return None # If not auto-starting, and already initialized, return None |
| 171 | |
| 172 | if not self.config.api_key: |
| 173 | logger.warning( |
| 174 | "No API key provided. AgentOps will initialize but authentication will fail. " |
| 175 | "Set AGENTOPS_API_KEY environment variable or pass api_key parameter." |
| 176 | ) |
| 177 | # Continue without API key - spans will be created but exports will fail gracefully |
| 178 | |
| 179 | configure_logging(self.config) |
| 180 | intercept_opentelemetry_logging() |
| 181 | |
| 182 | self.api = ApiClient(self.config.endpoint) |
| 183 | |
| 184 | # Initialize tracer with JWT provider for dynamic updates |
| 185 | tracing_config = self.config.dict() |
| 186 | tracing_config["project_id"] = "temporary" # Will be updated when auth completes |
| 187 | |
| 188 | # Create JWT provider function for dynamic updates |
| 189 | def jwt_provider(): |
| 190 | return self.get_current_jwt() |
| 191 | |
| 192 | # Initialize tracer with JWT provider |
| 193 | tracer.initialize_from_config(tracing_config, jwt_provider=jwt_provider) |
| 194 | |
| 195 | if self.config.instrument_llm_calls: |
| 196 | instrument_all() |
| 197 | |
| 198 | # Start authentication task only if we have an API key |
| 199 | if self.config.api_key: |
| 200 | self._start_auth_task(self.config.api_key) |
| 201 | else: |
| 202 | logger.debug("No API key available - skipping authentication task") |
| 203 | |
| 204 | global _atexit_registered |