Skip to content

Read tracing API data lazily #289

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Mar 21, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 18 additions & 3 deletions src/agents/tracing/processors.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import random
import threading
import time
from functools import cached_property
from typing import Any

import httpx
Expand Down Expand Up @@ -50,9 +51,9 @@ def __init__(
base_delay: Base delay (in seconds) for the first backoff.
max_delay: Maximum delay (in seconds) for backoff growth.
"""
self.api_key = api_key or os.environ.get("OPENAI_API_KEY")
self.organization = organization or os.environ.get("OPENAI_ORG_ID")
self.project = project or os.environ.get("OPENAI_PROJECT_ID")
self._api_key = api_key
self._organization = organization
self._project = project
self.endpoint = endpoint
self.max_retries = max_retries
self.base_delay = base_delay
Expand All @@ -68,8 +69,22 @@ def set_api_key(self, api_key: str):
api_key: The OpenAI API key to use. This is the same key used by the OpenAI Python
client.
"""
# We're specifically setting the underlying cached property as well
self._api_key = api_key
self.api_key = api_key

@cached_property
def api_key(self):
return self._api_key or os.environ.get("OPENAI_API_KEY")

@cached_property
def organization(self):
return self._organization or os.environ.get("OPENAI_ORG_ID")

@cached_property
def project(self):
return self._project or os.environ.get("OPENAI_PROJECT_ID")

def export(self, items: list[Trace | Span[Any]]) -> None:
if not items:
return
Expand Down
27 changes: 27 additions & 0 deletions tests/tracing/test_processor_api_key.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import pytest

from agents.tracing.processors import BackendSpanExporter


@pytest.mark.asyncio
async def test_processor_api_key(monkeypatch):
# If the API key is not set, it should be None
monkeypatch.delenv("OPENAI_API_KEY", None)
processor = BackendSpanExporter()
assert processor.api_key is None

# If we set it afterwards, it should be the new value
processor.set_api_key("test_api_key")
assert processor.api_key == "test_api_key"


@pytest.mark.asyncio
async def test_processor_api_key_from_env(monkeypatch):
# If the API key is not set at creation time but set before access time, it should be the new
# value
monkeypatch.delenv("OPENAI_API_KEY", None)
processor = BackendSpanExporter()

# If we set it afterwards, it should be the new value
monkeypatch.setenv("OPENAI_API_KEY", "foo_bar_123")
assert processor.api_key == "foo_bar_123"