diff --git a/aieng-agents/aieng/agents/env_vars.py b/aieng-agents/aieng/agents/env_vars.py index 6168699..59e948f 100644 --- a/aieng-agents/aieng/agents/env_vars.py +++ b/aieng-agents/aieng/agents/env_vars.py @@ -79,7 +79,10 @@ class Configs(BaseSettings): """ model_config = SettingsConfigDict( - env_file=".env", env_file_encoding="utf-8", env_ignore_empty=True + env_file=".env", + env_file_encoding="utf-8", + env_ignore_empty=True, + extra="ignore", ) openai_base_url: str = "https://generativelanguage.googleapis.com/v1beta/openai/" diff --git a/aieng-agents/aieng/agents/langfuse/__init__.py b/aieng-agents/aieng/agents/langfuse/__init__.py index daea837..abb4161 100644 --- a/aieng-agents/aieng/agents/langfuse/__init__.py +++ b/aieng-agents/aieng/agents/langfuse/__init__.py @@ -1,8 +1,24 @@ """Utilities for Langfuse integration.""" +from typing import TYPE_CHECKING + from aieng.agents.langfuse.oai_sdk_setup import setup_langfuse_tracer from aieng.agents.langfuse.otlp_env_setup import set_up_langfuse_otlp_env_vars -from aieng.agents.langfuse.shared_client import flush_langfuse, langfuse_client +from aieng.agents.langfuse.shared_client import flush_langfuse + + +if TYPE_CHECKING: + from langfuse import Langfuse + +langfuse_client: "Langfuse" # noqa: F822 -- lazily initialized via __getattr__ + + +def __getattr__(name: str) -> "Langfuse": + if name == "langfuse_client": + from aieng.agents.langfuse.shared_client import _manager # noqa: PLC0415 + + return _manager.client + raise AttributeError(f"module has no attribute '{name}'") __all__ = [ diff --git a/aieng-agents/aieng/agents/langfuse/shared_client.py b/aieng-agents/aieng/agents/langfuse/shared_client.py index 55e1506..0117687 100644 --- a/aieng-agents/aieng/agents/langfuse/shared_client.py +++ b/aieng-agents/aieng/agents/langfuse/shared_client.py @@ -1,23 +1,40 @@ """Shared instance of langfuse client.""" +from functools import cached_property + from aieng.agents.env_vars import Configs from langfuse import Langfuse from rich.progress import Progress, SpinnerColumn, TextColumn -__all__ = ["flush_langfuse", "langfuse_client"] +class _LangfuseClientManager: + @cached_property + def config(self) -> Configs: + return Configs() + + @cached_property + def client(self) -> Langfuse: + return Langfuse( + public_key=self.config.langfuse_public_key, + secret_key=self.config.langfuse_secret_key, + ) + +_manager = _LangfuseClientManager() +langfuse_client: Langfuse # noqa: F822 -- lazily initialized via __getattr__ -config = Configs() -langfuse_client = Langfuse( - public_key=config.langfuse_public_key, secret_key=config.langfuse_secret_key -) +def __getattr__(name: str) -> Langfuse: + """Module-level lazy loading for backward compatibility.""" + if name == "langfuse_client": + return _manager.client + raise AttributeError(f"module has no attribute '{name}'") -def flush_langfuse(client: "Langfuse | None" = None) -> None: + +def flush_langfuse(client: Langfuse | None = None) -> None: """Flush shared LangFuse Client. Rich Progress included.""" if client is None: - client = langfuse_client + client = _manager.client with Progress( SpinnerColumn(), @@ -25,4 +42,7 @@ def flush_langfuse(client: "Langfuse | None" = None) -> None: transient=True, ) as progress: progress.add_task("Finalizing Langfuse annotations...", total=None) - langfuse_client.flush() + client.flush() + + +__all__ = ["flush_langfuse", "langfuse_client"] diff --git a/aieng-agents/pyproject.toml b/aieng-agents/pyproject.toml index 2449033..7261083 100644 --- a/aieng-agents/pyproject.toml +++ b/aieng-agents/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "aieng-agents" -version = "0.1.0" +version = "0.1.1" description = "Helper modules for Vector Institute AI Engineering Agents Bootcamp implementations" authors = [{name = "Vector AI Engineering", email = "ai_engineering@vectorinstitute.ai"}] requires-python = ">=3.12" diff --git a/pyproject.toml b/pyproject.toml index 184bf1e..d5cf853 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -7,7 +7,7 @@ authors = [ {name = "Vector AI Engineering", email = "ai_engineering@vectorinsti license = "MIT" requires-python = ">=3.12" dependencies = [ - "aieng-agents>=0.1.0", + "aieng-agents>=0.1.1", "numpy<2.3.0", "plotly>=6.2.0", "scikit-learn>=1.7.0", diff --git a/uv.lock b/uv.lock index f8d80a5..040ea33 100644 --- a/uv.lock +++ b/uv.lock @@ -90,7 +90,7 @@ docs = [ [[package]] name = "aieng-agents" -version = "0.1.0" +version = "0.1.1" source = { editable = "aieng-agents" } dependencies = [ { name = "backoff" },