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
20 changes: 20 additions & 0 deletions langfuse/api/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,14 @@
OptionalObservationBody,
OrganizationProject,
OrganizationProjectsResponse,
OtelAttribute,
OtelAttributeValue,
OtelResource,
OtelResourceSpan,
OtelScope,
OtelScopeSpan,
OtelSpan,
OtelTraceResponse,
PaginatedAnnotationQueueItems,
PaginatedAnnotationQueues,
PaginatedDatasetItems,
Expand All @@ -153,6 +161,7 @@
Prompt,
PromptMeta,
PromptMetaListResponse,
PromptType,
Prompt_Chat,
Prompt_Text,
ResourceMeta,
Expand Down Expand Up @@ -221,6 +230,7 @@
metrics,
models,
observations,
opentelemetry,
organizations,
projects,
prompt_version,
Expand Down Expand Up @@ -370,6 +380,14 @@
"OptionalObservationBody",
"OrganizationProject",
"OrganizationProjectsResponse",
"OtelAttribute",
"OtelAttributeValue",
"OtelResource",
"OtelResourceSpan",
"OtelScope",
"OtelScopeSpan",
"OtelSpan",
"OtelTraceResponse",
"PaginatedAnnotationQueueItems",
"PaginatedAnnotationQueues",
"PaginatedDatasetItems",
Expand All @@ -387,6 +405,7 @@
"Prompt",
"PromptMeta",
"PromptMetaListResponse",
"PromptType",
"Prompt_Chat",
"Prompt_Text",
"ResourceMeta",
Expand Down Expand Up @@ -455,6 +474,7 @@
"metrics",
"models",
"observations",
"opentelemetry",
"organizations",
"projects",
"prompt_version",
Expand Down
8 changes: 8 additions & 0 deletions langfuse/api/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@
from .resources.metrics.client import AsyncMetricsClient, MetricsClient
from .resources.models.client import AsyncModelsClient, ModelsClient
from .resources.observations.client import AsyncObservationsClient, ObservationsClient
from .resources.opentelemetry.client import (
AsyncOpentelemetryClient,
OpentelemetryClient,
)
from .resources.organizations.client import (
AsyncOrganizationsClient,
OrganizationsClient,
Expand Down Expand Up @@ -136,6 +140,7 @@ def __init__(
self.metrics = MetricsClient(client_wrapper=self._client_wrapper)
self.models = ModelsClient(client_wrapper=self._client_wrapper)
self.observations = ObservationsClient(client_wrapper=self._client_wrapper)
self.opentelemetry = OpentelemetryClient(client_wrapper=self._client_wrapper)
self.organizations = OrganizationsClient(client_wrapper=self._client_wrapper)
self.projects = ProjectsClient(client_wrapper=self._client_wrapper)
self.prompt_version = PromptVersionClient(client_wrapper=self._client_wrapper)
Expand Down Expand Up @@ -240,6 +245,9 @@ def __init__(
self.metrics = AsyncMetricsClient(client_wrapper=self._client_wrapper)
self.models = AsyncModelsClient(client_wrapper=self._client_wrapper)
self.observations = AsyncObservationsClient(client_wrapper=self._client_wrapper)
self.opentelemetry = AsyncOpentelemetryClient(
client_wrapper=self._client_wrapper
)
self.organizations = AsyncOrganizationsClient(
client_wrapper=self._client_wrapper
)
Expand Down
180 changes: 179 additions & 1 deletion langfuse/api/reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -2442,7 +2442,7 @@ client.health.health()

**Legacy endpoint for batch ingestion for Langfuse Observability.**

-> Please use the OpenTelemetry endpoint (`/api/public/otel`). Learn more: https://langfuse.com/integrations/native/opentelemetry
-> Please use the OpenTelemetry endpoint (`/api/public/otel/v1/traces`). Learn more: https://langfuse.com/integrations/native/opentelemetry

Within each batch, there can be multiple events.
Each event has a type, an id, a timestamp, metadata and a body.
Expand Down Expand Up @@ -3604,6 +3604,184 @@ client.observations.get_many()
<dl>
<dd>

**filter:** `typing.Optional[str]`

JSON string containing an array of filter conditions. When provided, this takes precedence over legacy filter parameters (userId, name, sessionId, tags, version, release, environment, fromTimestamp, toTimestamp).
Each filter condition has the following structure:
```json
[
{
"type": string, // Required. One of: "datetime", "string", "number", "stringOptions", "categoryOptions", "arrayOptions", "stringObject", "numberObject", "boolean", "null"
"column": string, // Required. Column to filter on
"operator": string, // Required. Operator based on type:
// - datetime: ">", "<", ">=", "<="
// - string: "=", "contains", "does not contain", "starts with", "ends with"
// - stringOptions: "any of", "none of"
// - categoryOptions: "any of", "none of"
// - arrayOptions: "any of", "none of", "all of"
// - number: "=", ">", "<", ">=", "<="
// - stringObject: "=", "contains", "does not contain", "starts with", "ends with"
// - numberObject: "=", ">", "<", ">=", "<="
// - boolean: "=", "<>"
// - null: "is null", "is not null"
"value": any, // Required (except for null type). Value to compare against. Type depends on filter type
"key": string // Required only for stringObject, numberObject, and categoryOptions types when filtering on nested fields like metadata
}
]
```

</dd>
</dl>

<dl>
<dd>

**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.

</dd>
</dl>
</dd>
</dl>


</dd>
</dl>
</details>

## Opentelemetry
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The section header uses "Opentelemetry" while the description below uses "OpenTelemetry". For consistency and clarity, please standardize the capitalization (preferably "OpenTelemetry").

Suggested change
## Opentelemetry
## OpenTelemetry

<details><summary><code>client.opentelemetry.<a href="src/langfuse/resources/opentelemetry/client.py">export_traces</a>(...)</code></summary>
<dl>
<dd>

#### 📝 Description

<dl>
<dd>

<dl>
<dd>

**OpenTelemetry Traces Ingestion Endpoint**

This endpoint implements the OTLP/HTTP specification for trace ingestion, providing native OpenTelemetry integration for Langfuse Observability.

**Supported Formats:**
- Binary Protobuf: `Content-Type: application/x-protobuf`
- JSON Protobuf: `Content-Type: application/json`
- Supports gzip compression via `Content-Encoding: gzip` header

**Specification Compliance:**
- Conforms to [OTLP/HTTP Trace Export](https://opentelemetry.io/docs/specs/otlp/#otlphttp)
- Implements `ExportTraceServiceRequest` message format

**Documentation:**
- Integration guide: https://langfuse.com/integrations/native/opentelemetry
- Data model: https://langfuse.com/docs/observability/data-model
</dd>
</dl>
</dd>
</dl>

#### 🔌 Usage

<dl>
<dd>

<dl>
<dd>

```python
from langfuse import (
OtelAttribute,
OtelAttributeValue,
OtelResource,
OtelResourceSpan,
OtelScope,
OtelScopeSpan,
OtelSpan,
)
from langfuse.client import FernLangfuse

client = FernLangfuse(
x_langfuse_sdk_name="YOUR_X_LANGFUSE_SDK_NAME",
x_langfuse_sdk_version="YOUR_X_LANGFUSE_SDK_VERSION",
x_langfuse_public_key="YOUR_X_LANGFUSE_PUBLIC_KEY",
username="YOUR_USERNAME",
password="YOUR_PASSWORD",
base_url="https://yourhost.com/path/to/api",
)
client.opentelemetry.export_traces(
resource_spans=[
OtelResourceSpan(
resource=OtelResource(
attributes=[
OtelAttribute(
key="service.name",
value=OtelAttributeValue(
string_value="my-service",
),
),
OtelAttribute(
key="service.version",
value=OtelAttributeValue(
string_value="1.0.0",
),
),
],
),
scope_spans=[
OtelScopeSpan(
scope=OtelScope(
name="langfuse-sdk",
version="2.60.3",
),
spans=[
OtelSpan(
trace_id="0123456789abcdef0123456789abcdef",
span_id="0123456789abcdef",
name="my-operation",
kind=1,
start_time_unix_nano="1747872000000000000",
end_time_unix_nano="1747872001000000000",
attributes=[
OtelAttribute(
key="langfuse.observation.type",
value=OtelAttributeValue(
string_value="generation",
),
)
],
status={},
)
],
)
],
)
],
)

```
</dd>
</dl>
</dd>
</dl>

#### ⚙️ Parameters

<dl>
<dd>

<dl>
<dd>

**resource_spans:** `typing.Sequence[OtelResourceSpan]` — Array of resource spans containing trace data as defined in the OTLP specification

</dd>
</dl>

<dl>
<dd>

**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.

</dd>
Expand Down
22 changes: 22 additions & 0 deletions langfuse/api/resources/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
metrics,
models,
observations,
opentelemetry,
organizations,
projects,
prompt_version,
Expand Down Expand Up @@ -175,6 +176,16 @@
from .metrics import MetricsResponse
from .models import CreateModelRequest, PaginatedModels
from .observations import Observations, ObservationsViews
from .opentelemetry import (
OtelAttribute,
OtelAttributeValue,
OtelResource,
OtelResourceSpan,
OtelScope,
OtelScopeSpan,
OtelSpan,
OtelTraceResponse,
)
from .organizations import (
DeleteMembershipRequest,
MembershipDeletionResponse,
Expand Down Expand Up @@ -210,6 +221,7 @@
Prompt,
PromptMeta,
PromptMetaListResponse,
PromptType,
Prompt_Chat,
Prompt_Text,
TextPrompt,
Expand Down Expand Up @@ -389,6 +401,14 @@
"OptionalObservationBody",
"OrganizationProject",
"OrganizationProjectsResponse",
"OtelAttribute",
"OtelAttributeValue",
"OtelResource",
"OtelResourceSpan",
"OtelScope",
"OtelScopeSpan",
"OtelSpan",
"OtelTraceResponse",
"PaginatedAnnotationQueueItems",
"PaginatedAnnotationQueues",
"PaginatedDatasetItems",
Expand All @@ -406,6 +426,7 @@
"Prompt",
"PromptMeta",
"PromptMetaListResponse",
"PromptType",
"Prompt_Chat",
"Prompt_Text",
"ResourceMeta",
Expand Down Expand Up @@ -474,6 +495,7 @@
"metrics",
"models",
"observations",
"opentelemetry",
"organizations",
"projects",
"prompt_version",
Expand Down
4 changes: 2 additions & 2 deletions langfuse/api/resources/ingestion/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ def batch(
"""
**Legacy endpoint for batch ingestion for Langfuse Observability.**

-> Please use the OpenTelemetry endpoint (`/api/public/otel`). Learn more: https://langfuse.com/integrations/native/opentelemetry
-> Please use the OpenTelemetry endpoint (`/api/public/otel/v1/traces`). Learn more: https://langfuse.com/integrations/native/opentelemetry

Within each batch, there can be multiple events.
Each event has a type, an id, a timestamp, metadata and a body.
Expand Down Expand Up @@ -151,7 +151,7 @@ async def batch(
"""
**Legacy endpoint for batch ingestion for Langfuse Observability.**

-> Please use the OpenTelemetry endpoint (`/api/public/otel`). Learn more: https://langfuse.com/integrations/native/opentelemetry
-> Please use the OpenTelemetry endpoint (`/api/public/otel/v1/traces`). Learn more: https://langfuse.com/integrations/native/opentelemetry

Within each batch, there can be multiple events.
Each event has a type, an id, a timestamp, metadata and a body.
Expand Down
Loading