Skip to content
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
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ jobs:
runs-on: ubuntu-latest
timeout-minutes: 30
env:
LANGFUSE_HOST: "http://localhost:3000"
LANGFUSE_BASE_URL: "http://localhost:3000"
LANGFUSE_PUBLIC_KEY: "pk-lf-1234567890"
LANGFUSE_SECRET_KEY: "sk-lf-1234567890"
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
Expand Down
18 changes: 13 additions & 5 deletions langfuse/_client/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
)
from langfuse._client.datasets import DatasetClient, DatasetItemClient
from langfuse._client.environment_variables import (
LANGFUSE_BASE_URL,
LANGFUSE_DEBUG,
LANGFUSE_HOST,
LANGFUSE_PUBLIC_KEY,
Expand Down Expand Up @@ -134,7 +135,8 @@ class Langfuse:
Parameters:
public_key (Optional[str]): Your Langfuse public API key. Can also be set via LANGFUSE_PUBLIC_KEY environment variable.
secret_key (Optional[str]): Your Langfuse secret API key. Can also be set via LANGFUSE_SECRET_KEY environment variable.
host (Optional[str]): The Langfuse API host URL. Defaults to "https://cloud.langfuse.com". Can also be set via LANGFUSE_HOST environment variable.
base_url (Optional[str]): The Langfuse API base URL. Defaults to "https://cloud.langfuse.com". Can also be set via LANGFUSE_BASE_URL environment variable.
host (Optional[str]): Deprecated. Use base_url instead. The Langfuse API host URL. Defaults to "https://cloud.langfuse.com".
timeout (Optional[int]): Timeout in seconds for API requests. Defaults to 5 seconds.
httpx_client (Optional[httpx.Client]): Custom httpx client for making non-tracing HTTP requests. If not provided, a default client will be created.
debug (bool): Enable debug logging. Defaults to False. Can also be set via LANGFUSE_DEBUG environment variable.
Expand Down Expand Up @@ -195,6 +197,7 @@ def __init__(
*,
public_key: Optional[str] = None,
secret_key: Optional[str] = None,
base_url: Optional[str] = None,
host: Optional[str] = None,
timeout: Optional[int] = None,
httpx_client: Optional[httpx.Client] = None,
Expand All @@ -211,7 +214,12 @@ def __init__(
additional_headers: Optional[Dict[str, str]] = None,
tracer_provider: Optional[TracerProvider] = None,
):
self._host = host or os.environ.get(LANGFUSE_HOST, "https://cloud.langfuse.com")
self._base_url = (
base_url
or os.environ.get(LANGFUSE_BASE_URL)
or host
or os.environ.get(LANGFUSE_HOST, "https://cloud.langfuse.com")
)
self._environment = environment or cast(
str, os.environ.get(LANGFUSE_TRACING_ENVIRONMENT)
)
Expand Down Expand Up @@ -269,7 +277,7 @@ def __init__(
self._resources = LangfuseResourceManager(
public_key=public_key,
secret_key=secret_key,
host=self._host,
base_url=self._base_url,
timeout=timeout,
environment=self._environment,
release=release,
Expand Down Expand Up @@ -2413,7 +2421,7 @@ def get_trace_url(self, *, trace_id: Optional[str] = None) -> Optional[str]:
final_trace_id = trace_id or self.get_current_trace_id()

return (
f"{self._host}/project/{project_id}/traces/{final_trace_id}"
f"{self._base_url}/project/{project_id}/traces/{final_trace_id}"
if project_id and final_trace_id
else None
)
Expand Down Expand Up @@ -2712,7 +2720,7 @@ async def process_item(item: ExperimentItem) -> ExperimentItemResult:
project_id = self._get_project_id()

if project_id:
dataset_run_url = f"{self._host}/project/{project_id}/datasets/{dataset_id}/runs/{dataset_run_id}"
dataset_run_url = f"{self._base_url}/project/{project_id}/datasets/{dataset_id}/runs/{dataset_run_id}"

except Exception:
pass # URL generation is optional
Expand Down
11 changes: 10 additions & 1 deletion langfuse/_client/environment_variables.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,20 @@
Secret API key of Langfuse project
"""

LANGFUSE_BASE_URL = "LANGFUSE_BASE_URL"
"""
.. envvar:: LANGFUSE_BASE_URL

Base URL of Langfuse API. Can be set via `LANGFUSE_BASE_URL` environment variable.

**Default value:** ``"https://cloud.langfuse.com"``
"""

LANGFUSE_HOST = "LANGFUSE_HOST"
"""
.. envvar:: LANGFUSE_HOST

Host of Langfuse API. Can be set via `LANGFUSE_HOST` environment variable.
Deprecated. Use LANGFUSE_BASE_URL instead. Host of Langfuse API. Can be set via `LANGFUSE_HOST` environment variable.

**Default value:** ``"https://cloud.langfuse.com"``
"""
Expand Down
2 changes: 1 addition & 1 deletion langfuse/_client/get_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ def _create_client_from_instance(
return Langfuse(
public_key=public_key or instance.public_key,
secret_key=instance.secret_key,
host=instance.host,
base_url=instance.base_url,
tracing_enabled=instance.tracing_enabled,
environment=instance.environment,
timeout=instance.timeout,
Expand Down
28 changes: 18 additions & 10 deletions langfuse/_client/observe.py
Original file line number Diff line number Diff line change
Expand Up @@ -313,13 +313,17 @@ async def async_wrapper(*args: Tuple[Any], **kwargs: Dict[str, Any]) -> Any:
)

# handle starlette.StreamingResponse
if type(result).__name__ == "StreamingResponse" and hasattr(result, "body_iterator"):
if type(result).__name__ == "StreamingResponse" and hasattr(
result, "body_iterator"
):
is_return_type_generator = True

result.body_iterator = self._wrap_async_generator_result(
langfuse_span_or_generation,
result.body_iterator,
transform_to_string,
result.body_iterator = (
self._wrap_async_generator_result(
langfuse_span_or_generation,
result.body_iterator,
transform_to_string,
)
)

langfuse_span_or_generation.update(output=result)
Expand Down Expand Up @@ -427,13 +431,17 @@ def sync_wrapper(*args: Any, **kwargs: Any) -> Any:
)

# handle starlette.StreamingResponse
if type(result).__name__ == "StreamingResponse" and hasattr(result, "body_iterator"):
if type(result).__name__ == "StreamingResponse" and hasattr(
result, "body_iterator"
):
is_return_type_generator = True

result.body_iterator = self._wrap_async_generator_result(
langfuse_span_or_generation,
result.body_iterator,
transform_to_string,
result.body_iterator = (
self._wrap_async_generator_result(
langfuse_span_or_generation,
result.body_iterator,
transform_to_string,
)
)

langfuse_span_or_generation.update(output=result)
Expand Down
18 changes: 9 additions & 9 deletions langfuse/_client/resource_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ def __new__(
*,
public_key: str,
secret_key: str,
host: str,
base_url: str,
environment: Optional[str] = None,
release: Optional[str] = None,
timeout: Optional[int] = None,
Expand Down Expand Up @@ -115,7 +115,7 @@ def __new__(
instance._initialize_instance(
public_key=public_key,
secret_key=secret_key,
host=host,
base_url=base_url,
timeout=timeout,
environment=environment,
release=release,
Expand All @@ -142,7 +142,7 @@ def _initialize_instance(
*,
public_key: str,
secret_key: str,
host: str,
base_url: str,
environment: Optional[str] = None,
release: Optional[str] = None,
timeout: Optional[int] = None,
Expand All @@ -160,7 +160,7 @@ def _initialize_instance(
self.public_key = public_key
self.secret_key = secret_key
self.tracing_enabled = tracing_enabled
self.host = host
self.base_url = base_url
self.mask = mask
self.environment = environment

Expand All @@ -183,7 +183,7 @@ def _initialize_instance(
langfuse_processor = LangfuseSpanProcessor(
public_key=self.public_key,
secret_key=secret_key,
host=host,
base_url=base_url,
timeout=timeout,
flush_at=flush_at,
flush_interval=flush_interval,
Expand Down Expand Up @@ -212,7 +212,7 @@ def _initialize_instance(
self.httpx_client = httpx.Client(timeout=timeout, headers=client_headers)

self.api = FernLangfuse(
base_url=host,
base_url=base_url,
username=self.public_key,
password=secret_key,
x_langfuse_sdk_name="python",
Expand All @@ -222,7 +222,7 @@ def _initialize_instance(
timeout=timeout,
)
self.async_api = AsyncFernLangfuse(
base_url=host,
base_url=base_url,
username=self.public_key,
password=secret_key,
x_langfuse_sdk_name="python",
Expand All @@ -233,7 +233,7 @@ def _initialize_instance(
score_ingestion_client = LangfuseClient(
public_key=self.public_key,
secret_key=secret_key,
base_url=host,
base_url=base_url,
version=langfuse_version,
timeout=timeout or 20,
session=self.httpx_client,
Expand Down Expand Up @@ -290,7 +290,7 @@ def _initialize_instance(
langfuse_logger.info(
f"Startup: Langfuse tracer successfully initialized | "
f"public_key={self.public_key} | "
f"host={host} | "
f"base_url={base_url} | "
f"environment={environment or 'default'} | "
f"sample_rate={sample_rate if sample_rate is not None else 1.0} | "
f"media_threads={media_upload_thread_count or 1}"
Expand Down
6 changes: 4 additions & 2 deletions langfuse/_client/span.py
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,9 @@ def __init__(
{k: v for k, v in attributes.items() if v is not None}
)
# Set OTEL span status if level is ERROR
self._set_otel_span_status_if_error(level=level, status_message=status_message)
self._set_otel_span_status_if_error(
level=level, status_message=status_message
)

def end(self, *, end_time: Optional[int] = None) -> "LangfuseObservationWrapper":
"""End the span, marking it as completed.
Expand Down Expand Up @@ -544,7 +546,7 @@ def _process_media_in_attribute(
return data

def _set_otel_span_status_if_error(
self, *, level: Optional[SpanLevel] = None, status_message: Optional[str] = None
self, *, level: Optional[SpanLevel] = None, status_message: Optional[str] = None
) -> None:
"""Set OpenTelemetry span status to ERROR if level is ERROR.

Expand Down
6 changes: 3 additions & 3 deletions langfuse/_client/span_processor.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ def __init__(
*,
public_key: str,
secret_key: str,
host: str,
base_url: str,
timeout: Optional[int] = None,
flush_at: Optional[int] = None,
flush_interval: Optional[float] = None,
Expand Down Expand Up @@ -94,9 +94,9 @@ def __init__(
traces_export_path = os.environ.get(LANGFUSE_OTEL_TRACES_EXPORT_PATH, None)

endpoint = (
f"{host}/{traces_export_path}"
f"{base_url}/{traces_export_path}"
if traces_export_path
else f"{host}/api/public/otel/v1/traces"
else f"{base_url}/api/public/otel/v1/traces"
)

langfuse_span_exporter = OTLPSpanExporter(
Expand Down
2 changes: 1 addition & 1 deletion tests/api_wrapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ def __init__(self, username=None, password=None, base_url=None):
username = username if username else os.environ["LANGFUSE_PUBLIC_KEY"]
password = password if password else os.environ["LANGFUSE_SECRET_KEY"]
self.auth = (username, password)
self.BASE_URL = base_url if base_url else os.environ["LANGFUSE_HOST"]
self.BASE_URL = base_url if base_url else os.environ["LANGFUSE_BASE_URL"]

def get_observation(self, observation_id):
sleep(1)
Expand Down
4 changes: 2 additions & 2 deletions tests/test_additional_headers_simple.py
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ def test_span_processor_has_additional_headers_in_otel_exporter(self):
processor = LangfuseSpanProcessor(
public_key="test-public-key",
secret_key="test-secret-key",
host="https://mock-host.com",
base_url="https://mock-host.com",
additional_headers=additional_headers,
)

Expand All @@ -170,7 +170,7 @@ def test_span_processor_none_additional_headers_works(self):
processor = LangfuseSpanProcessor(
public_key="test-public-key",
secret_key="test-secret-key",
host="https://mock-host.com",
base_url="https://mock-host.com",
additional_headers=None,
)

Expand Down
Loading