Skip to content

Commit 42382f0

Browse files
committed
feat(client): allow setting additional headers
1 parent a44be25 commit 42382f0

3 files changed

Lines changed: 32 additions & 8 deletions

File tree

langfuse/_client/client.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ class Langfuse:
105105
sample_rate (Optional[float]): Sampling rate for traces (0.0 to 1.0). Defaults to 1.0 (100% of traces are sampled). Can also be set via LANGFUSE_SAMPLE_RATE environment variable.
106106
mask (Optional[MaskFunction]): Function to mask sensitive data in traces before sending to the API.
107107
blocked_instrumentation_scopes (Optional[List[str]]): List of instrumentation scope names to block from being exported to Langfuse. Spans from these scopes will be filtered out before being sent to the API. Useful for filtering out spans from specific libraries or frameworks. For exported spans, you can see the instrumentation scope name in the span metadata in Langfuse (`metadata.scope.name`)
108+
additional_headers (Optional[Dict[str, str]]): Additional headers to include in all API requests and OTLPSpanExporter requests. These headers will be merged with default headers.
108109
109110
Example:
110111
```python
@@ -163,6 +164,7 @@ def __init__(
163164
sample_rate: Optional[float] = None,
164165
mask: Optional[MaskFunction] = None,
165166
blocked_instrumentation_scopes: Optional[List[str]] = None,
167+
additional_headers: Optional[Dict[str, str]] = None,
166168
):
167169
self._host = host or os.environ.get(LANGFUSE_HOST, "https://cloud.langfuse.com")
168170
self._environment = environment or os.environ.get(LANGFUSE_TRACING_ENVIRONMENT)
@@ -225,6 +227,7 @@ def __init__(
225227
mask=mask,
226228
tracing_enabled=self._tracing_enabled,
227229
blocked_instrumentation_scopes=blocked_instrumentation_scopes,
230+
additional_headers=additional_headers,
228231
)
229232
self._mask = self._resources.mask
230233

langfuse/_client/resource_manager.py

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ def __new__(
9494
mask: Optional[MaskFunction] = None,
9595
tracing_enabled: Optional[bool] = None,
9696
blocked_instrumentation_scopes: Optional[List[str]] = None,
97+
additional_headers: Optional[Dict[str, str]] = None,
9798
) -> "LangfuseResourceManager":
9899
if public_key in cls._instances:
99100
return cls._instances[public_key]
@@ -119,6 +120,7 @@ def __new__(
119120
if tracing_enabled is not None
120121
else True,
121122
blocked_instrumentation_scopes=blocked_instrumentation_scopes,
123+
additional_headers=additional_headers,
122124
)
123125

124126
cls._instances[public_key] = instance
@@ -142,6 +144,7 @@ def _initialize_instance(
142144
mask: Optional[MaskFunction] = None,
143145
tracing_enabled: bool = True,
144146
blocked_instrumentation_scopes: Optional[List[str]] = None,
147+
additional_headers: Optional[Dict[str, str]] = None,
145148
):
146149
self.public_key = public_key
147150
self.secret_key = secret_key
@@ -163,6 +166,7 @@ def _initialize_instance(
163166
flush_at=flush_at,
164167
flush_interval=flush_interval,
165168
blocked_instrumentation_scopes=blocked_instrumentation_scopes,
169+
additional_headers=additional_headers,
166170
)
167171
tracer_provider.add_span_processor(langfuse_processor)
168172

@@ -179,7 +183,17 @@ def _initialize_instance(
179183
## use connection pools with limited capacity. Creating multiple instances
180184
## could exhaust the OS's maximum number of available TCP sockets (file descriptors),
181185
## leading to connection errors.
182-
self.httpx_client = httpx_client or httpx.Client(timeout=timeout)
186+
if httpx_client is not None:
187+
self.httpx_client = httpx_client
188+
# If additional_headers are provided and httpx_client is provided,
189+
# we merge the headers into the existing client
190+
if additional_headers:
191+
merged_headers = {**(httpx_client.headers or {}), **additional_headers}
192+
self.httpx_client.headers = merged_headers
193+
else:
194+
# Create a new httpx client with additional_headers if provided
195+
client_headers = additional_headers if additional_headers else {}
196+
self.httpx_client = httpx.Client(timeout=timeout, headers=client_headers)
183197
self.api = FernLangfuse(
184198
base_url=host,
185199
username=self.public_key,

langfuse/_client/span_processor.py

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313

1414
import base64
1515
import os
16-
from typing import List, Optional
16+
from typing import Dict, List, Optional
1717

1818
from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter
1919
from opentelemetry.sdk.trace import ReadableSpan
@@ -56,6 +56,7 @@ def __init__(
5656
flush_at: Optional[int] = None,
5757
flush_interval: Optional[float] = None,
5858
blocked_instrumentation_scopes: Optional[List[str]] = None,
59+
additional_headers: Optional[Dict[str, str]] = None,
5960
):
6061
self.public_key = public_key
6162
self.blocked_instrumentation_scopes = (
@@ -78,14 +79,20 @@ def __init__(
7879
f"{public_key}:{secret_key}".encode("utf-8")
7980
).decode("ascii")
8081

82+
# Prepare default headers
83+
default_headers = {
84+
"Authorization": basic_auth_header,
85+
"x_langfuse_sdk_name": "python",
86+
"x_langfuse_sdk_version": langfuse_version,
87+
"x_langfuse_public_key": public_key,
88+
}
89+
90+
# Merge additional headers if provided
91+
headers = {**default_headers, **(additional_headers or {})}
92+
8193
langfuse_span_exporter = OTLPSpanExporter(
8294
endpoint=f"{host}/api/public/otel/v1/traces",
83-
headers={
84-
"Authorization": basic_auth_header,
85-
"x_langfuse_sdk_name": "python",
86-
"x_langfuse_sdk_version": langfuse_version,
87-
"x_langfuse_public_key": public_key,
88-
},
95+
headers=headers,
8996
timeout=timeout,
9097
)
9198

0 commit comments

Comments
 (0)