diff --git a/langfuse/api/README.md b/langfuse/api/README.md
index 93549c0d6..e1a87ffff 100644
--- a/langfuse/api/README.md
+++ b/langfuse/api/README.md
@@ -29,11 +29,10 @@ client = FernLangfuse(
)
client.comments.create(
request=CreateCommentRequest(
- project_id="string",
- object_type="string",
- object_id="string",
- content="string",
- author_user_id="string",
+ project_id="projectId",
+ object_type="objectType",
+ object_id="objectId",
+ content="content",
),
)
```
@@ -61,11 +60,10 @@ client = AsyncFernLangfuse(
async def main() -> None:
await client.comments.create(
request=CreateCommentRequest(
- project_id="string",
- object_type="string",
- object_id="string",
- content="string",
- author_user_id="string",
+ project_id="projectId",
+ object_type="objectType",
+ object_id="objectId",
+ content="content",
),
)
diff --git a/langfuse/api/__init__.py b/langfuse/api/__init__.py
index ec2bed17e..71adf3728 100644
--- a/langfuse/api/__init__.py
+++ b/langfuse/api/__init__.py
@@ -42,6 +42,9 @@
DatasetRunItem,
DatasetRunWithItems,
DatasetStatus,
+ DeleteDatasetItemResponse,
+ DeleteDatasetRunResponse,
+ DeleteTraceResponse,
Error,
GetCommentsResponse,
GetMediaResponse,
@@ -86,8 +89,9 @@
Observations,
ObservationsView,
ObservationsViews,
+ OpenAiCompletionUsageSchema,
+ OpenAiResponseUsageSchema,
OpenAiUsage,
- OpenAiUsageSchema,
OptionalObservationBody,
PaginatedDatasetItems,
PaginatedDatasetRuns,
@@ -198,6 +202,9 @@
"DatasetRunItem",
"DatasetRunWithItems",
"DatasetStatus",
+ "DeleteDatasetItemResponse",
+ "DeleteDatasetRunResponse",
+ "DeleteTraceResponse",
"Error",
"GetCommentsResponse",
"GetMediaResponse",
@@ -242,8 +249,9 @@
"Observations",
"ObservationsView",
"ObservationsViews",
+ "OpenAiCompletionUsageSchema",
+ "OpenAiResponseUsageSchema",
"OpenAiUsage",
- "OpenAiUsageSchema",
"OptionalObservationBody",
"PaginatedDatasetItems",
"PaginatedDatasetRuns",
diff --git a/langfuse/api/reference.md b/langfuse/api/reference.md
index 0b6bf964a..77f2b2a58 100644
--- a/langfuse/api/reference.md
+++ b/langfuse/api/reference.md
@@ -40,11 +40,10 @@ client = FernLangfuse(
)
client.comments.create(
request=CreateCommentRequest(
- project_id="string",
- object_type="string",
- object_id="string",
- content="string",
- author_user_id="string",
+ project_id="projectId",
+ object_type="objectType",
+ object_id="objectId",
+ content="content",
),
)
@@ -119,13 +118,7 @@ client = FernLangfuse(
password="YOUR_PASSWORD",
base_url="https://yourhost.com/path/to/api",
)
-client.comments.get(
- page=1,
- limit=1,
- object_type="string",
- object_id="string",
- author_user_id="string",
-)
+client.comments.get()
```
@@ -231,7 +224,7 @@ client = FernLangfuse(
base_url="https://yourhost.com/path/to/api",
)
client.comments.get_by_id(
- comment_id="string",
+ comment_id="commentId",
)
```
@@ -296,7 +289,7 @@ Create a dataset item
```python
-from langfuse import CreateDatasetItemRequest, DatasetStatus
+from langfuse import CreateDatasetItemRequest
from langfuse.client import FernLangfuse
client = FernLangfuse(
@@ -309,14 +302,7 @@ client = FernLangfuse(
)
client.dataset_items.create(
request=CreateDatasetItemRequest(
- dataset_name="string",
- input={"key": "value"},
- expected_output={"key": "value"},
- metadata={"key": "value"},
- source_trace_id="string",
- source_observation_id="string",
- id="string",
- status=DatasetStatus.ACTIVE,
+ dataset_name="datasetName",
),
)
@@ -392,7 +378,7 @@ client = FernLangfuse(
base_url="https://yourhost.com/path/to/api",
)
client.dataset_items.get(
- id="string",
+ id="id",
)
```
@@ -466,13 +452,7 @@ client = FernLangfuse(
password="YOUR_PASSWORD",
base_url="https://yourhost.com/path/to/api",
)
-client.dataset_items.list(
- dataset_name="string",
- source_trace_id="string",
- source_observation_id="string",
- page=1,
- limit=1,
-)
+client.dataset_items.list()
```
@@ -536,6 +516,81 @@ client.dataset_items.list(
+
+
+
+
+client.dataset_items.delete(...)
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+Delete a dataset item and all its run items. This action is irreversible.
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+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.dataset_items.delete(
+ id="id",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**id:** `str`
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
@@ -581,12 +636,8 @@ client = FernLangfuse(
)
client.dataset_run_items.create(
request=CreateDatasetRunItemRequest(
- run_name="string",
- run_description="string",
- metadata={"key": "value"},
- dataset_item_id="string",
- observation_id="string",
- trace_id="string",
+ run_name="runName",
+ dataset_item_id="datasetItemId",
),
)
@@ -662,10 +713,7 @@ client = FernLangfuse(
password="YOUR_PASSWORD",
base_url="https://yourhost.com/path/to/api",
)
-client.datasets.list(
- page=1,
- limit=1,
-)
+client.datasets.list()
```
@@ -747,7 +795,7 @@ client = FernLangfuse(
base_url="https://yourhost.com/path/to/api",
)
client.datasets.get(
- dataset_name="string",
+ dataset_name="datasetName",
)
```
@@ -824,9 +872,7 @@ client = FernLangfuse(
)
client.datasets.create(
request=CreateDatasetRequest(
- name="string",
- description="string",
- metadata={"key": "value"},
+ name="name",
),
)
@@ -902,8 +948,92 @@ client = FernLangfuse(
base_url="https://yourhost.com/path/to/api",
)
client.datasets.get_run(
- dataset_name="string",
- run_name="string",
+ dataset_name="datasetName",
+ run_name="runName",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**dataset_name:** `str`
+
+
+
+
+
+-
+
+**run_name:** `str`
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.datasets.delete_run(...)
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+Delete a dataset run and all its run items. This action is irreversible.
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+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.datasets.delete_run(
+ dataset_name="datasetName",
+ run_name="runName",
)
```
@@ -986,9 +1116,7 @@ client = FernLangfuse(
base_url="https://yourhost.com/path/to/api",
)
client.datasets.get_runs(
- dataset_name="string",
- page=1,
- limit=1,
+ dataset_name="datasetName",
)
```
@@ -1131,7 +1259,6 @@ The event.body.id is the ID of the actual trace and will be used for updates and
I.e. if you want to update a trace, you'd use the same body id, but separate event IDs.
Notes:
-
- Introduction to data model: https://langfuse.com/docs/tracing-data-model
- Batch sizes are limited to 3.5 MB in total. You need to adjust the number of events per batch accordingly.
- The API does not return a 4xx status code for input errors. Instead, it responds with a 207 status code, which includes a list of the encountered errors.
@@ -1170,6 +1297,7 @@ client.ingestion.batch(
trace_id="1234-5678-90ab-cdef",
name="My Score",
value=0.9,
+ environment="default",
),
)
],
@@ -1256,7 +1384,7 @@ client = FernLangfuse(
base_url="https://yourhost.com/path/to/api",
)
client.media.get(
- media_id="string",
+ media_id="mediaId",
)
```
@@ -1334,14 +1462,12 @@ client = FernLangfuse(
base_url="https://yourhost.com/path/to/api",
)
client.media.patch(
- media_id="string",
+ media_id="mediaId",
request=PatchMediaBody(
uploaded_at=datetime.datetime.fromisoformat(
"2024-01-15 09:30:00+00:00",
),
upload_http_status=1,
- upload_http_error="string",
- upload_time_ms=1,
),
)
@@ -1427,12 +1553,11 @@ client = FernLangfuse(
)
client.media.get_upload_url(
request=GetMediaUploadUrlRequest(
- trace_id="string",
- observation_id="string",
+ trace_id="traceId",
content_type=MediaContentType.IMAGE_PNG,
content_length=1,
- sha_256_hash="string",
- field="string",
+ sha_256_hash="sha256Hash",
+ field="field",
),
)
@@ -1498,8 +1623,6 @@ Get daily metrics of the Langfuse project
-
```python
-import datetime
-
from langfuse.client import FernLangfuse
client = FernLangfuse(
@@ -1510,19 +1633,7 @@ client = FernLangfuse(
password="YOUR_PASSWORD",
base_url="https://yourhost.com/path/to/api",
)
-client.metrics.daily(
- page=1,
- limit=1,
- trace_name="string",
- user_id="string",
- tags="string",
- from_timestamp=datetime.datetime.fromisoformat(
- "2024-01-15 09:30:00+00:00",
- ),
- to_timestamp=datetime.datetime.fromisoformat(
- "2024-01-15 09:30:00+00:00",
- ),
-)
+client.metrics.daily()
```
@@ -1578,6 +1689,14 @@ client.metrics.daily(
-
+**environment:** `typing.Optional[typing.Union[str, typing.Sequence[str]]]` — Optional filter for metrics where events include any of these environments
+
+
+
+
+
+-
+
**from_timestamp:** `typing.Optional[dt.datetime]` — Optional filter to only include traces and observations on or after a certain datetime (ISO 8601)
@@ -1634,9 +1753,7 @@ Create a model
-
```python
-import datetime
-
-from langfuse import CreateModelRequest, ModelUsageUnit
+from langfuse import CreateModelRequest
from langfuse.client import FernLangfuse
client = FernLangfuse(
@@ -1649,17 +1766,8 @@ client = FernLangfuse(
)
client.models.create(
request=CreateModelRequest(
- model_name="string",
- match_pattern="string",
- start_date=datetime.datetime.fromisoformat(
- "2024-01-15 09:30:00+00:00",
- ),
- unit=ModelUsageUnit.CHARACTERS,
- input_price=1.1,
- output_price=1.1,
- total_price=1.1,
- tokenizer_id="string",
- tokenizer_config={"key": "value"},
+ model_name="modelName",
+ match_pattern="matchPattern",
),
)
@@ -1734,10 +1842,7 @@ client = FernLangfuse(
password="YOUR_PASSWORD",
base_url="https://yourhost.com/path/to/api",
)
-client.models.list(
- page=1,
- limit=1,
-)
+client.models.list()
```
@@ -1819,7 +1924,7 @@ client = FernLangfuse(
base_url="https://yourhost.com/path/to/api",
)
client.models.get(
- id="string",
+ id="id",
)
```
@@ -1894,7 +1999,7 @@ client = FernLangfuse(
base_url="https://yourhost.com/path/to/api",
)
client.models.delete(
- id="string",
+ id="id",
)
```
@@ -1970,7 +2075,7 @@ client = FernLangfuse(
base_url="https://yourhost.com/path/to/api",
)
client.observations.get(
- observation_id="string",
+ observation_id="observationId",
)
```
@@ -2034,8 +2139,6 @@ Get a list of observations
-
```python
-import datetime
-
from langfuse.client import FernLangfuse
client = FernLangfuse(
@@ -2046,22 +2149,7 @@ client = FernLangfuse(
password="YOUR_PASSWORD",
base_url="https://yourhost.com/path/to/api",
)
-client.observations.get_many(
- page=1,
- limit=1,
- name="string",
- user_id="string",
- type="string",
- trace_id="string",
- parent_observation_id="string",
- from_start_time=datetime.datetime.fromisoformat(
- "2024-01-15 09:30:00+00:00",
- ),
- to_start_time=datetime.datetime.fromisoformat(
- "2024-01-15 09:30:00+00:00",
- ),
- version="string",
-)
+client.observations.get_many()
```
@@ -2133,6 +2221,14 @@ client.observations.get_many(
-
+**environment:** `typing.Optional[typing.Union[str, typing.Sequence[str]]]` — Optional filter for observations where the environment is one of the provided values.
+
+
+
+
+
+-
+
**from_start_time:** `typing.Optional[dt.datetime]` — Retrieve only observations with a start_time or or after this datetime (ISO 8601).
@@ -2274,9 +2370,9 @@ client = FernLangfuse(
base_url="https://yourhost.com/path/to/api",
)
client.prompt_version.update(
- name="string",
+ name="name",
version=1,
- new_labels=["string"],
+ new_labels=["newLabels", "newLabels"],
)
```
@@ -2368,9 +2464,7 @@ client = FernLangfuse(
base_url="https://yourhost.com/path/to/api",
)
client.prompts.get(
- prompt_name="string",
- version=1,
- label="string",
+ prompt_name="promptName",
)
```
@@ -2450,8 +2544,6 @@ Get a list of prompt names with versions and labels
-
```python
-import datetime
-
from langfuse.client import FernLangfuse
client = FernLangfuse(
@@ -2462,19 +2554,7 @@ client = FernLangfuse(
password="YOUR_PASSWORD",
base_url="https://yourhost.com/path/to/api",
)
-client.prompts.list(
- name="string",
- label="string",
- tag="string",
- page=1,
- limit=1,
- from_updated_at=datetime.datetime.fromisoformat(
- "2024-01-15 09:30:00+00:00",
- ),
- to_updated_at=datetime.datetime.fromisoformat(
- "2024-01-15 09:30:00+00:00",
- ),
-)
+client.prompts.list()
```
@@ -2598,17 +2678,17 @@ client = FernLangfuse(
)
client.prompts.create(
request=CreatePromptRequest_Chat(
- name="string",
+ name="name",
prompt=[
ChatMessage(
- role="string",
- content="string",
- )
+ role="role",
+ content="content",
+ ),
+ ChatMessage(
+ role="role",
+ content="content",
+ ),
],
- config={"key": "value"},
- labels=["string"],
- tags=["string"],
- commit_message="string",
),
)
@@ -2674,7 +2754,7 @@ Create a score configuration (config). Score configs are used to define the stru
-
```python
-from langfuse import ConfigCategory, CreateScoreConfigRequest, ScoreDataType
+from langfuse import CreateScoreConfigRequest, ScoreDataType
from langfuse.client import FernLangfuse
client = FernLangfuse(
@@ -2687,17 +2767,8 @@ client = FernLangfuse(
)
client.score_configs.create(
request=CreateScoreConfigRequest(
- name="string",
+ name="name",
data_type=ScoreDataType.NUMERIC,
- categories=[
- ConfigCategory(
- value=1.1,
- label="string",
- )
- ],
- min_value=1.1,
- max_value=1.1,
- description="string",
),
)
@@ -2772,10 +2843,7 @@ client = FernLangfuse(
password="YOUR_PASSWORD",
base_url="https://yourhost.com/path/to/api",
)
-client.score_configs.get(
- page=1,
- limit=1,
-)
+client.score_configs.get()
```
@@ -2857,7 +2925,7 @@ client = FernLangfuse(
base_url="https://yourhost.com/path/to/api",
)
client.score_configs.get_by_id(
- config_id="string",
+ config_id="configId",
)
```
@@ -2935,9 +3003,9 @@ client = FernLangfuse(
)
client.score.create(
request=CreateScoreRequest(
- name="novelty",
- value=0.9,
- trace_id="cdef-1234-5678-90ab",
+ trace_id="traceId",
+ name="name",
+ value=1.1,
),
)
@@ -3002,9 +3070,6 @@ Get a list of scores
-
```python
-import datetime
-
-from langfuse import ScoreDataType, ScoreSource
from langfuse.client import FernLangfuse
client = FernLangfuse(
@@ -3015,26 +3080,7 @@ client = FernLangfuse(
password="YOUR_PASSWORD",
base_url="https://yourhost.com/path/to/api",
)
-client.score.get(
- page=1,
- limit=1,
- user_id="string",
- name="string",
- from_timestamp=datetime.datetime.fromisoformat(
- "2024-01-15 09:30:00+00:00",
- ),
- to_timestamp=datetime.datetime.fromisoformat(
- "2024-01-15 09:30:00+00:00",
- ),
- source=ScoreSource.ANNOTATION,
- operator="string",
- value=1.1,
- score_ids="string",
- config_id="string",
- queue_id="string",
- data_type=ScoreDataType.NUMERIC,
- trace_tags="string",
-)
+client.score.get()
```
@@ -3098,6 +3144,14 @@ client.score.get(
-
+**environment:** `typing.Optional[typing.Union[str, typing.Sequence[str]]]` — Optional filter for scores where the environment is one of the provided values.
+
+
+
+
+
+-
+
**source:** `typing.Optional[ScoreSource]` — Retrieve only scores from a specific source.
@@ -3212,7 +3266,7 @@ client = FernLangfuse(
base_url="https://yourhost.com/path/to/api",
)
client.score.get_by_id(
- score_id="string",
+ score_id="scoreId",
)
```
@@ -3287,7 +3341,7 @@ client = FernLangfuse(
base_url="https://yourhost.com/path/to/api",
)
client.score.delete(
- score_id="string",
+ score_id="scoreId",
)
```
@@ -3352,8 +3406,6 @@ Get sessions
-
```python
-import datetime
-
from langfuse.client import FernLangfuse
client = FernLangfuse(
@@ -3364,16 +3416,7 @@ client = FernLangfuse(
password="YOUR_PASSWORD",
base_url="https://yourhost.com/path/to/api",
)
-client.sessions.list(
- page=1,
- limit=1,
- from_timestamp=datetime.datetime.fromisoformat(
- "2024-01-15 09:30:00+00:00",
- ),
- to_timestamp=datetime.datetime.fromisoformat(
- "2024-01-15 09:30:00+00:00",
- ),
-)
+client.sessions.list()
```
@@ -3421,6 +3464,14 @@ client.sessions.list(
-
+**environment:** `typing.Optional[typing.Union[str, typing.Sequence[str]]]` — Optional filter for sessions where the environment is one of the provided values.
+
+
+
+
+
+-
+
**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
@@ -3471,7 +3522,7 @@ client = FernLangfuse(
base_url="https://yourhost.com/path/to/api",
)
client.sessions.get(
- session_id="string",
+ session_id="sessionId",
)
```
@@ -3547,7 +3598,7 @@ client = FernLangfuse(
base_url="https://yourhost.com/path/to/api",
)
client.trace.get(
- trace_id="string",
+ trace_id="traceId",
)
```
@@ -3580,6 +3631,81 @@ client.trace.get(
+
+
+
+
+client.trace.delete(...)
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+Delete a specific trace
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+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.trace.delete(
+ trace_id="traceId",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**trace_id:** `str` — The unique langfuse identifier of the trace to delete
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
@@ -3611,8 +3737,6 @@ Get list of traces
```python
-import datetime
-
from langfuse.client import FernLangfuse
client = FernLangfuse(
@@ -3623,23 +3747,7 @@ client = FernLangfuse(
password="YOUR_PASSWORD",
base_url="https://yourhost.com/path/to/api",
)
-client.trace.list(
- page=1,
- limit=1,
- user_id="string",
- name="string",
- session_id="string",
- from_timestamp=datetime.datetime.fromisoformat(
- "2024-01-15 09:30:00+00:00",
- ),
- to_timestamp=datetime.datetime.fromisoformat(
- "2024-01-15 09:30:00+00:00",
- ),
- order_by="string",
- tags="string",
- version="string",
- release="string",
-)
+client.trace.list()
```
@@ -3743,6 +3851,89 @@ client.trace.list(
-
+**environment:** `typing.Optional[typing.Union[str, typing.Sequence[str]]]` — Optional filter for traces where the environment is one of the provided values.
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.trace.delete_multiple(...)
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+Delete multiple traces
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+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.trace.delete_multiple(
+ trace_ids=["traceIds", "traceIds"],
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**trace_ids:** `typing.Sequence[str]` — List of trace IDs to delete
+
+
+
+
+
+-
+
**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
diff --git a/langfuse/api/resources/__init__.py b/langfuse/api/resources/__init__.py
index 6ebdcbe69..bc0dfbfef 100644
--- a/langfuse/api/resources/__init__.py
+++ b/langfuse/api/resources/__init__.py
@@ -62,9 +62,18 @@
UnauthorizedError,
Usage,
)
-from .dataset_items import CreateDatasetItemRequest, PaginatedDatasetItems
+from .dataset_items import (
+ CreateDatasetItemRequest,
+ DeleteDatasetItemResponse,
+ PaginatedDatasetItems,
+)
from .dataset_run_items import CreateDatasetRunItemRequest
-from .datasets import CreateDatasetRequest, PaginatedDatasetRuns, PaginatedDatasets
+from .datasets import (
+ CreateDatasetRequest,
+ DeleteDatasetRunResponse,
+ PaginatedDatasetRuns,
+ PaginatedDatasets,
+)
from .health import HealthResponse, ServiceUnavailableError
from .ingestion import (
BaseEvent,
@@ -92,8 +101,9 @@
IngestionUsage,
ObservationBody,
ObservationType,
+ OpenAiCompletionUsageSchema,
+ OpenAiResponseUsageSchema,
OpenAiUsage,
- OpenAiUsageSchema,
OptionalObservationBody,
ScoreBody,
ScoreEvent,
@@ -151,7 +161,7 @@
)
from .score_configs import CreateScoreConfigRequest, ScoreConfigs
from .sessions import PaginatedSessions
-from .trace import Sort, Traces
+from .trace import DeleteTraceResponse, Sort, Traces
__all__ = [
"AccessDeniedError",
@@ -195,6 +205,9 @@
"DatasetRunItem",
"DatasetRunWithItems",
"DatasetStatus",
+ "DeleteDatasetItemResponse",
+ "DeleteDatasetRunResponse",
+ "DeleteTraceResponse",
"Error",
"GetCommentsResponse",
"GetMediaResponse",
@@ -239,8 +252,9 @@
"Observations",
"ObservationsView",
"ObservationsViews",
+ "OpenAiCompletionUsageSchema",
+ "OpenAiResponseUsageSchema",
"OpenAiUsage",
- "OpenAiUsageSchema",
"OptionalObservationBody",
"PaginatedDatasetItems",
"PaginatedDatasetRuns",
diff --git a/langfuse/api/resources/comments/client.py b/langfuse/api/resources/comments/client.py
index 9d84948a3..9c78ca23f 100644
--- a/langfuse/api/resources/comments/client.py
+++ b/langfuse/api/resources/comments/client.py
@@ -61,11 +61,10 @@ def create(
)
client.comments.create(
request=CreateCommentRequest(
- project_id="string",
- object_type="string",
- object_id="string",
- content="string",
- author_user_id="string",
+ project_id="projectId",
+ object_type="objectType",
+ object_id="objectId",
+ content="content",
),
)
"""
@@ -151,13 +150,7 @@ def get(
password="YOUR_PASSWORD",
base_url="https://yourhost.com/path/to/api",
)
- client.comments.get(
- page=1,
- limit=1,
- object_type="string",
- object_id="string",
- author_user_id="string",
- )
+ client.comments.get()
"""
_response = self._client_wrapper.httpx_client.request(
"api/public/comments",
@@ -231,7 +224,7 @@ def get_by_id(
base_url="https://yourhost.com/path/to/api",
)
client.comments.get_by_id(
- comment_id="string",
+ comment_id="commentId",
)
"""
_response = self._client_wrapper.httpx_client.request(
@@ -310,11 +303,10 @@ async def create(
async def main() -> None:
await client.comments.create(
request=CreateCommentRequest(
- project_id="string",
- object_type="string",
- object_id="string",
- content="string",
- author_user_id="string",
+ project_id="projectId",
+ object_type="objectType",
+ object_id="objectId",
+ content="content",
),
)
@@ -408,13 +400,7 @@ async def get(
async def main() -> None:
- await client.comments.get(
- page=1,
- limit=1,
- object_type="string",
- object_id="string",
- author_user_id="string",
- )
+ await client.comments.get()
asyncio.run(main())
@@ -496,7 +482,7 @@ async def get_by_id(
async def main() -> None:
await client.comments.get_by_id(
- comment_id="string",
+ comment_id="commentId",
)
diff --git a/langfuse/api/resources/commons/types/session.py b/langfuse/api/resources/commons/types/session.py
index 230bf004b..46a0a6b96 100644
--- a/langfuse/api/resources/commons/types/session.py
+++ b/langfuse/api/resources/commons/types/session.py
@@ -11,6 +11,10 @@ class Session(pydantic_v1.BaseModel):
id: str
created_at: dt.datetime = pydantic_v1.Field(alias="createdAt")
project_id: str = pydantic_v1.Field(alias="projectId")
+ environment: typing.Optional[str] = pydantic_v1.Field(default=None)
+ """
+ The environment from which this session originated.
+ """
def json(self, **kwargs: typing.Any) -> str:
kwargs_with_defaults: typing.Any = {
diff --git a/langfuse/api/resources/dataset_items/__init__.py b/langfuse/api/resources/dataset_items/__init__.py
index 2a0693046..06d2ae527 100644
--- a/langfuse/api/resources/dataset_items/__init__.py
+++ b/langfuse/api/resources/dataset_items/__init__.py
@@ -1,5 +1,13 @@
# This file was auto-generated by Fern from our API Definition.
-from .types import CreateDatasetItemRequest, PaginatedDatasetItems
+from .types import (
+ CreateDatasetItemRequest,
+ DeleteDatasetItemResponse,
+ PaginatedDatasetItems,
+)
-__all__ = ["CreateDatasetItemRequest", "PaginatedDatasetItems"]
+__all__ = [
+ "CreateDatasetItemRequest",
+ "DeleteDatasetItemResponse",
+ "PaginatedDatasetItems",
+]
diff --git a/langfuse/api/resources/dataset_items/client.py b/langfuse/api/resources/dataset_items/client.py
index 7cab6f51c..8ece3a790 100644
--- a/langfuse/api/resources/dataset_items/client.py
+++ b/langfuse/api/resources/dataset_items/client.py
@@ -15,6 +15,7 @@
from ..commons.errors.unauthorized_error import UnauthorizedError
from ..commons.types.dataset_item import DatasetItem
from .types.create_dataset_item_request import CreateDatasetItemRequest
+from .types.delete_dataset_item_response import DeleteDatasetItemResponse
from .types.paginated_dataset_items import PaginatedDatasetItems
# this is used as the default value for optional parameters
@@ -47,7 +48,7 @@ def create(
Examples
--------
- from langfuse import CreateDatasetItemRequest, DatasetStatus
+ from langfuse import CreateDatasetItemRequest
from langfuse.client import FernLangfuse
client = FernLangfuse(
@@ -60,14 +61,7 @@ def create(
)
client.dataset_items.create(
request=CreateDatasetItemRequest(
- dataset_name="string",
- input={"key": "value"},
- expected_output={"key": "value"},
- metadata={"key": "value"},
- source_trace_id="string",
- source_observation_id="string",
- id="string",
- status=DatasetStatus.ACTIVE,
+ dataset_name="datasetName",
),
)
"""
@@ -134,7 +128,7 @@ def get(
base_url="https://yourhost.com/path/to/api",
)
client.dataset_items.get(
- id="string",
+ id="id",
)
"""
_response = self._client_wrapper.httpx_client.request(
@@ -214,13 +208,7 @@ def list(
password="YOUR_PASSWORD",
base_url="https://yourhost.com/path/to/api",
)
- client.dataset_items.list(
- dataset_name="string",
- source_trace_id="string",
- source_observation_id="string",
- page=1,
- limit=1,
- )
+ client.dataset_items.list()
"""
_response = self._client_wrapper.httpx_client.request(
"api/public/dataset-items",
@@ -260,6 +248,72 @@ def list(
raise ApiError(status_code=_response.status_code, body=_response.text)
raise ApiError(status_code=_response.status_code, body=_response_json)
+ def delete(
+ self, id: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> DeleteDatasetItemResponse:
+ """
+ Delete a dataset item and all its run items. This action is irreversible.
+
+ Parameters
+ ----------
+ id : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ DeleteDatasetItemResponse
+
+ Examples
+ --------
+ 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.dataset_items.delete(
+ id="id",
+ )
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"api/public/dataset-items/{jsonable_encoder(id)}",
+ method="DELETE",
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ return pydantic_v1.parse_obj_as(
+ DeleteDatasetItemResponse, _response.json()
+ ) # type: ignore
+ if _response.status_code == 400:
+ raise Error(pydantic_v1.parse_obj_as(typing.Any, _response.json())) # type: ignore
+ if _response.status_code == 401:
+ raise UnauthorizedError(
+ pydantic_v1.parse_obj_as(typing.Any, _response.json())
+ ) # type: ignore
+ if _response.status_code == 403:
+ raise AccessDeniedError(
+ pydantic_v1.parse_obj_as(typing.Any, _response.json())
+ ) # type: ignore
+ if _response.status_code == 405:
+ raise MethodNotAllowedError(
+ pydantic_v1.parse_obj_as(typing.Any, _response.json())
+ ) # type: ignore
+ if _response.status_code == 404:
+ raise NotFoundError(
+ pydantic_v1.parse_obj_as(typing.Any, _response.json())
+ ) # type: ignore
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, body=_response.text)
+ raise ApiError(status_code=_response.status_code, body=_response_json)
+
class AsyncDatasetItemsClient:
def __init__(self, *, client_wrapper: AsyncClientWrapper):
@@ -289,7 +343,7 @@ async def create(
--------
import asyncio
- from langfuse import CreateDatasetItemRequest, DatasetStatus
+ from langfuse import CreateDatasetItemRequest
from langfuse.client import AsyncFernLangfuse
client = AsyncFernLangfuse(
@@ -305,14 +359,7 @@ async def create(
async def main() -> None:
await client.dataset_items.create(
request=CreateDatasetItemRequest(
- dataset_name="string",
- input={"key": "value"},
- expected_output={"key": "value"},
- metadata={"key": "value"},
- source_trace_id="string",
- source_observation_id="string",
- id="string",
- status=DatasetStatus.ACTIVE,
+ dataset_name="datasetName",
),
)
@@ -387,7 +434,7 @@ async def get(
async def main() -> None:
await client.dataset_items.get(
- id="string",
+ id="id",
)
@@ -475,13 +522,7 @@ async def list(
async def main() -> None:
- await client.dataset_items.list(
- dataset_name="string",
- source_trace_id="string",
- source_observation_id="string",
- page=1,
- limit=1,
- )
+ await client.dataset_items.list()
asyncio.run(main())
@@ -523,3 +564,77 @@ async def main() -> None:
except JSONDecodeError:
raise ApiError(status_code=_response.status_code, body=_response.text)
raise ApiError(status_code=_response.status_code, body=_response_json)
+
+ async def delete(
+ self, id: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> DeleteDatasetItemResponse:
+ """
+ Delete a dataset item and all its run items. This action is irreversible.
+
+ Parameters
+ ----------
+ id : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ DeleteDatasetItemResponse
+
+ Examples
+ --------
+ import asyncio
+
+ from langfuse.client import AsyncFernLangfuse
+
+ client = AsyncFernLangfuse(
+ 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",
+ )
+
+
+ async def main() -> None:
+ await client.dataset_items.delete(
+ id="id",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"api/public/dataset-items/{jsonable_encoder(id)}",
+ method="DELETE",
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ return pydantic_v1.parse_obj_as(
+ DeleteDatasetItemResponse, _response.json()
+ ) # type: ignore
+ if _response.status_code == 400:
+ raise Error(pydantic_v1.parse_obj_as(typing.Any, _response.json())) # type: ignore
+ if _response.status_code == 401:
+ raise UnauthorizedError(
+ pydantic_v1.parse_obj_as(typing.Any, _response.json())
+ ) # type: ignore
+ if _response.status_code == 403:
+ raise AccessDeniedError(
+ pydantic_v1.parse_obj_as(typing.Any, _response.json())
+ ) # type: ignore
+ if _response.status_code == 405:
+ raise MethodNotAllowedError(
+ pydantic_v1.parse_obj_as(typing.Any, _response.json())
+ ) # type: ignore
+ if _response.status_code == 404:
+ raise NotFoundError(
+ pydantic_v1.parse_obj_as(typing.Any, _response.json())
+ ) # type: ignore
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, body=_response.text)
+ raise ApiError(status_code=_response.status_code, body=_response_json)
diff --git a/langfuse/api/resources/dataset_items/types/__init__.py b/langfuse/api/resources/dataset_items/types/__init__.py
index 24023de7b..214adce0e 100644
--- a/langfuse/api/resources/dataset_items/types/__init__.py
+++ b/langfuse/api/resources/dataset_items/types/__init__.py
@@ -1,6 +1,11 @@
# This file was auto-generated by Fern from our API Definition.
from .create_dataset_item_request import CreateDatasetItemRequest
+from .delete_dataset_item_response import DeleteDatasetItemResponse
from .paginated_dataset_items import PaginatedDatasetItems
-__all__ = ["CreateDatasetItemRequest", "PaginatedDatasetItems"]
+__all__ = [
+ "CreateDatasetItemRequest",
+ "DeleteDatasetItemResponse",
+ "PaginatedDatasetItems",
+]
diff --git a/langfuse/api/resources/dataset_items/types/delete_dataset_item_response.py b/langfuse/api/resources/dataset_items/types/delete_dataset_item_response.py
new file mode 100644
index 000000000..4d700ff75
--- /dev/null
+++ b/langfuse/api/resources/dataset_items/types/delete_dataset_item_response.py
@@ -0,0 +1,45 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import datetime as dt
+import typing
+
+from ....core.datetime_utils import serialize_datetime
+from ....core.pydantic_utilities import deep_union_pydantic_dicts, pydantic_v1
+
+
+class DeleteDatasetItemResponse(pydantic_v1.BaseModel):
+ message: str = pydantic_v1.Field()
+ """
+ Success message after deletion
+ """
+
+ def json(self, **kwargs: typing.Any) -> str:
+ kwargs_with_defaults: typing.Any = {
+ "by_alias": True,
+ "exclude_unset": True,
+ **kwargs,
+ }
+ return super().json(**kwargs_with_defaults)
+
+ def dict(self, **kwargs: typing.Any) -> typing.Dict[str, typing.Any]:
+ kwargs_with_defaults_exclude_unset: typing.Any = {
+ "by_alias": True,
+ "exclude_unset": True,
+ **kwargs,
+ }
+ kwargs_with_defaults_exclude_none: typing.Any = {
+ "by_alias": True,
+ "exclude_none": True,
+ **kwargs,
+ }
+
+ return deep_union_pydantic_dicts(
+ super().dict(**kwargs_with_defaults_exclude_unset),
+ super().dict(**kwargs_with_defaults_exclude_none),
+ )
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic_v1.Extra.allow
+ json_encoders = {dt.datetime: serialize_datetime}
diff --git a/langfuse/api/resources/dataset_run_items/client.py b/langfuse/api/resources/dataset_run_items/client.py
index c4c923a9b..4f5426568 100644
--- a/langfuse/api/resources/dataset_run_items/client.py
+++ b/langfuse/api/resources/dataset_run_items/client.py
@@ -58,12 +58,8 @@ def create(
)
client.dataset_run_items.create(
request=CreateDatasetRunItemRequest(
- run_name="string",
- run_description="string",
- metadata={"key": "value"},
- dataset_item_id="string",
- observation_id="string",
- trace_id="string",
+ run_name="runName",
+ dataset_item_id="datasetItemId",
),
)
"""
@@ -145,12 +141,8 @@ async def create(
async def main() -> None:
await client.dataset_run_items.create(
request=CreateDatasetRunItemRequest(
- run_name="string",
- run_description="string",
- metadata={"key": "value"},
- dataset_item_id="string",
- observation_id="string",
- trace_id="string",
+ run_name="runName",
+ dataset_item_id="datasetItemId",
),
)
diff --git a/langfuse/api/resources/datasets/__init__.py b/langfuse/api/resources/datasets/__init__.py
index d8a7fab0e..dd30a359d 100644
--- a/langfuse/api/resources/datasets/__init__.py
+++ b/langfuse/api/resources/datasets/__init__.py
@@ -1,5 +1,15 @@
# This file was auto-generated by Fern from our API Definition.
-from .types import CreateDatasetRequest, PaginatedDatasetRuns, PaginatedDatasets
+from .types import (
+ CreateDatasetRequest,
+ DeleteDatasetRunResponse,
+ PaginatedDatasetRuns,
+ PaginatedDatasets,
+)
-__all__ = ["CreateDatasetRequest", "PaginatedDatasetRuns", "PaginatedDatasets"]
+__all__ = [
+ "CreateDatasetRequest",
+ "DeleteDatasetRunResponse",
+ "PaginatedDatasetRuns",
+ "PaginatedDatasets",
+]
diff --git a/langfuse/api/resources/datasets/client.py b/langfuse/api/resources/datasets/client.py
index 5d535b949..aff7293a0 100644
--- a/langfuse/api/resources/datasets/client.py
+++ b/langfuse/api/resources/datasets/client.py
@@ -16,6 +16,7 @@
from ..commons.types.dataset import Dataset
from ..commons.types.dataset_run_with_items import DatasetRunWithItems
from .types.create_dataset_request import CreateDatasetRequest
+from .types.delete_dataset_run_response import DeleteDatasetRunResponse
from .types.paginated_dataset_runs import PaginatedDatasetRuns
from .types.paginated_datasets import PaginatedDatasets
@@ -64,10 +65,7 @@ def list(
password="YOUR_PASSWORD",
base_url="https://yourhost.com/path/to/api",
)
- client.datasets.list(
- page=1,
- limit=1,
- )
+ client.datasets.list()
"""
_response = self._client_wrapper.httpx_client.request(
"api/public/v2/datasets",
@@ -134,7 +132,7 @@ def get(
base_url="https://yourhost.com/path/to/api",
)
client.datasets.get(
- dataset_name="string",
+ dataset_name="datasetName",
)
"""
_response = self._client_wrapper.httpx_client.request(
@@ -203,9 +201,7 @@ def create(
)
client.datasets.create(
request=CreateDatasetRequest(
- name="string",
- description="string",
- metadata={"key": "value"},
+ name="name",
),
)
"""
@@ -278,8 +274,8 @@ def get_run(
base_url="https://yourhost.com/path/to/api",
)
client.datasets.get_run(
- dataset_name="string",
- run_name="string",
+ dataset_name="datasetName",
+ run_name="runName",
)
"""
_response = self._client_wrapper.httpx_client.request(
@@ -313,6 +309,79 @@ def get_run(
raise ApiError(status_code=_response.status_code, body=_response.text)
raise ApiError(status_code=_response.status_code, body=_response_json)
+ def delete_run(
+ self,
+ dataset_name: str,
+ run_name: str,
+ *,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> DeleteDatasetRunResponse:
+ """
+ Delete a dataset run and all its run items. This action is irreversible.
+
+ Parameters
+ ----------
+ dataset_name : str
+
+ run_name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ DeleteDatasetRunResponse
+
+ Examples
+ --------
+ 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.datasets.delete_run(
+ dataset_name="datasetName",
+ run_name="runName",
+ )
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"api/public/datasets/{jsonable_encoder(dataset_name)}/runs/{jsonable_encoder(run_name)}",
+ method="DELETE",
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ return pydantic_v1.parse_obj_as(
+ DeleteDatasetRunResponse, _response.json()
+ ) # type: ignore
+ if _response.status_code == 400:
+ raise Error(pydantic_v1.parse_obj_as(typing.Any, _response.json())) # type: ignore
+ if _response.status_code == 401:
+ raise UnauthorizedError(
+ pydantic_v1.parse_obj_as(typing.Any, _response.json())
+ ) # type: ignore
+ if _response.status_code == 403:
+ raise AccessDeniedError(
+ pydantic_v1.parse_obj_as(typing.Any, _response.json())
+ ) # type: ignore
+ if _response.status_code == 405:
+ raise MethodNotAllowedError(
+ pydantic_v1.parse_obj_as(typing.Any, _response.json())
+ ) # type: ignore
+ if _response.status_code == 404:
+ raise NotFoundError(
+ pydantic_v1.parse_obj_as(typing.Any, _response.json())
+ ) # type: ignore
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, body=_response.text)
+ raise ApiError(status_code=_response.status_code, body=_response_json)
+
def get_runs(
self,
dataset_name: str,
@@ -354,9 +423,7 @@ def get_runs(
base_url="https://yourhost.com/path/to/api",
)
client.datasets.get_runs(
- dataset_name="string",
- page=1,
- limit=1,
+ dataset_name="datasetName",
)
"""
_response = self._client_wrapper.httpx_client.request(
@@ -438,10 +505,7 @@ async def list(
async def main() -> None:
- await client.datasets.list(
- page=1,
- limit=1,
- )
+ await client.datasets.list()
asyncio.run(main())
@@ -516,7 +580,7 @@ async def get(
async def main() -> None:
await client.datasets.get(
- dataset_name="string",
+ dataset_name="datasetName",
)
@@ -593,9 +657,7 @@ async def create(
async def main() -> None:
await client.datasets.create(
request=CreateDatasetRequest(
- name="string",
- description="string",
- metadata={"key": "value"},
+ name="name",
),
)
@@ -676,8 +738,8 @@ async def get_run(
async def main() -> None:
await client.datasets.get_run(
- dataset_name="string",
- run_name="string",
+ dataset_name="datasetName",
+ run_name="runName",
)
@@ -714,6 +776,87 @@ async def main() -> None:
raise ApiError(status_code=_response.status_code, body=_response.text)
raise ApiError(status_code=_response.status_code, body=_response_json)
+ async def delete_run(
+ self,
+ dataset_name: str,
+ run_name: str,
+ *,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> DeleteDatasetRunResponse:
+ """
+ Delete a dataset run and all its run items. This action is irreversible.
+
+ Parameters
+ ----------
+ dataset_name : str
+
+ run_name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ DeleteDatasetRunResponse
+
+ Examples
+ --------
+ import asyncio
+
+ from langfuse.client import AsyncFernLangfuse
+
+ client = AsyncFernLangfuse(
+ 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",
+ )
+
+
+ async def main() -> None:
+ await client.datasets.delete_run(
+ dataset_name="datasetName",
+ run_name="runName",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"api/public/datasets/{jsonable_encoder(dataset_name)}/runs/{jsonable_encoder(run_name)}",
+ method="DELETE",
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ return pydantic_v1.parse_obj_as(
+ DeleteDatasetRunResponse, _response.json()
+ ) # type: ignore
+ if _response.status_code == 400:
+ raise Error(pydantic_v1.parse_obj_as(typing.Any, _response.json())) # type: ignore
+ if _response.status_code == 401:
+ raise UnauthorizedError(
+ pydantic_v1.parse_obj_as(typing.Any, _response.json())
+ ) # type: ignore
+ if _response.status_code == 403:
+ raise AccessDeniedError(
+ pydantic_v1.parse_obj_as(typing.Any, _response.json())
+ ) # type: ignore
+ if _response.status_code == 405:
+ raise MethodNotAllowedError(
+ pydantic_v1.parse_obj_as(typing.Any, _response.json())
+ ) # type: ignore
+ if _response.status_code == 404:
+ raise NotFoundError(
+ pydantic_v1.parse_obj_as(typing.Any, _response.json())
+ ) # type: ignore
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, body=_response.text)
+ raise ApiError(status_code=_response.status_code, body=_response_json)
+
async def get_runs(
self,
dataset_name: str,
@@ -760,9 +903,7 @@ async def get_runs(
async def main() -> None:
await client.datasets.get_runs(
- dataset_name="string",
- page=1,
- limit=1,
+ dataset_name="datasetName",
)
diff --git a/langfuse/api/resources/datasets/types/__init__.py b/langfuse/api/resources/datasets/types/__init__.py
index befecc4c0..f3304a59f 100644
--- a/langfuse/api/resources/datasets/types/__init__.py
+++ b/langfuse/api/resources/datasets/types/__init__.py
@@ -1,7 +1,13 @@
# This file was auto-generated by Fern from our API Definition.
from .create_dataset_request import CreateDatasetRequest
+from .delete_dataset_run_response import DeleteDatasetRunResponse
from .paginated_dataset_runs import PaginatedDatasetRuns
from .paginated_datasets import PaginatedDatasets
-__all__ = ["CreateDatasetRequest", "PaginatedDatasetRuns", "PaginatedDatasets"]
+__all__ = [
+ "CreateDatasetRequest",
+ "DeleteDatasetRunResponse",
+ "PaginatedDatasetRuns",
+ "PaginatedDatasets",
+]
diff --git a/langfuse/api/resources/datasets/types/delete_dataset_run_response.py b/langfuse/api/resources/datasets/types/delete_dataset_run_response.py
new file mode 100644
index 000000000..cf52eca14
--- /dev/null
+++ b/langfuse/api/resources/datasets/types/delete_dataset_run_response.py
@@ -0,0 +1,42 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import datetime as dt
+import typing
+
+from ....core.datetime_utils import serialize_datetime
+from ....core.pydantic_utilities import deep_union_pydantic_dicts, pydantic_v1
+
+
+class DeleteDatasetRunResponse(pydantic_v1.BaseModel):
+ message: str
+
+ def json(self, **kwargs: typing.Any) -> str:
+ kwargs_with_defaults: typing.Any = {
+ "by_alias": True,
+ "exclude_unset": True,
+ **kwargs,
+ }
+ return super().json(**kwargs_with_defaults)
+
+ def dict(self, **kwargs: typing.Any) -> typing.Dict[str, typing.Any]:
+ kwargs_with_defaults_exclude_unset: typing.Any = {
+ "by_alias": True,
+ "exclude_unset": True,
+ **kwargs,
+ }
+ kwargs_with_defaults_exclude_none: typing.Any = {
+ "by_alias": True,
+ "exclude_none": True,
+ **kwargs,
+ }
+
+ return deep_union_pydantic_dicts(
+ super().dict(**kwargs_with_defaults_exclude_unset),
+ super().dict(**kwargs_with_defaults_exclude_none),
+ )
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic_v1.Extra.allow
+ json_encoders = {dt.datetime: serialize_datetime}
diff --git a/langfuse/api/resources/ingestion/__init__.py b/langfuse/api/resources/ingestion/__init__.py
index 6bd1373be..9e072dc17 100644
--- a/langfuse/api/resources/ingestion/__init__.py
+++ b/langfuse/api/resources/ingestion/__init__.py
@@ -26,8 +26,9 @@
IngestionUsage,
ObservationBody,
ObservationType,
+ OpenAiCompletionUsageSchema,
+ OpenAiResponseUsageSchema,
OpenAiUsage,
- OpenAiUsageSchema,
OptionalObservationBody,
ScoreBody,
ScoreEvent,
@@ -70,8 +71,9 @@
"IngestionUsage",
"ObservationBody",
"ObservationType",
+ "OpenAiCompletionUsageSchema",
+ "OpenAiResponseUsageSchema",
"OpenAiUsage",
- "OpenAiUsageSchema",
"OptionalObservationBody",
"ScoreBody",
"ScoreEvent",
diff --git a/langfuse/api/resources/ingestion/client.py b/langfuse/api/resources/ingestion/client.py
index 7fd19ea06..9d6784856 100644
--- a/langfuse/api/resources/ingestion/client.py
+++ b/langfuse/api/resources/ingestion/client.py
@@ -42,7 +42,6 @@ def batch(
I.e. if you want to update a trace, you'd use the same body id, but separate event IDs.
Notes:
-
- Introduction to data model: https://langfuse.com/docs/tracing-data-model
- Batch sizes are limited to 3.5 MB in total. You need to adjust the number of events per batch accordingly.
- The API does not return a 4xx status code for input errors. Instead, it responds with a 207 status code, which includes a list of the encountered errors.
@@ -87,6 +86,7 @@ def batch(
timestamp=datetime.datetime.fromisoformat(
"2022-01-01 00:00:00+00:00",
),
+ environment="production",
name="My Trace",
user_id="1234-5678-90ab-cdef",
input="My input",
@@ -159,7 +159,6 @@ async def batch(
I.e. if you want to update a trace, you'd use the same body id, but separate event IDs.
Notes:
-
- Introduction to data model: https://langfuse.com/docs/tracing-data-model
- Batch sizes are limited to 3.5 MB in total. You need to adjust the number of events per batch accordingly.
- The API does not return a 4xx status code for input errors. Instead, it responds with a 207 status code, which includes a list of the encountered errors.
@@ -208,6 +207,7 @@ async def main() -> None:
timestamp=datetime.datetime.fromisoformat(
"2022-01-01 00:00:00+00:00",
),
+ environment="production",
name="My Trace",
user_id="1234-5678-90ab-cdef",
input="My input",
diff --git a/langfuse/api/resources/ingestion/types/__init__.py b/langfuse/api/resources/ingestion/types/__init__.py
index 95fa2559e..a3490e4dc 100644
--- a/langfuse/api/resources/ingestion/types/__init__.py
+++ b/langfuse/api/resources/ingestion/types/__init__.py
@@ -27,8 +27,9 @@
from .ingestion_usage import IngestionUsage
from .observation_body import ObservationBody
from .observation_type import ObservationType
+from .open_ai_completion_usage_schema import OpenAiCompletionUsageSchema
+from .open_ai_response_usage_schema import OpenAiResponseUsageSchema
from .open_ai_usage import OpenAiUsage
-from .open_ai_usage_schema import OpenAiUsageSchema
from .optional_observation_body import OptionalObservationBody
from .score_body import ScoreBody
from .score_event import ScoreEvent
@@ -70,8 +71,9 @@
"IngestionUsage",
"ObservationBody",
"ObservationType",
+ "OpenAiCompletionUsageSchema",
+ "OpenAiResponseUsageSchema",
"OpenAiUsage",
- "OpenAiUsageSchema",
"OptionalObservationBody",
"ScoreBody",
"ScoreEvent",
diff --git a/langfuse/api/resources/ingestion/types/open_ai_completion_usage_schema.py b/langfuse/api/resources/ingestion/types/open_ai_completion_usage_schema.py
new file mode 100644
index 000000000..461c8eee4
--- /dev/null
+++ b/langfuse/api/resources/ingestion/types/open_ai_completion_usage_schema.py
@@ -0,0 +1,50 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import datetime as dt
+import typing
+
+from ....core.datetime_utils import serialize_datetime
+from ....core.pydantic_utilities import deep_union_pydantic_dicts, pydantic_v1
+
+
+class OpenAiCompletionUsageSchema(pydantic_v1.BaseModel):
+ """
+ OpenAI Usage schema from (Chat-)Completion APIs
+ """
+
+ prompt_tokens: int
+ completion_tokens: int
+ total_tokens: int
+ prompt_tokens_details: typing.Optional[typing.Dict[str, int]] = None
+ completion_tokens_details: typing.Optional[typing.Dict[str, int]] = None
+
+ def json(self, **kwargs: typing.Any) -> str:
+ kwargs_with_defaults: typing.Any = {
+ "by_alias": True,
+ "exclude_unset": True,
+ **kwargs,
+ }
+ return super().json(**kwargs_with_defaults)
+
+ def dict(self, **kwargs: typing.Any) -> typing.Dict[str, typing.Any]:
+ kwargs_with_defaults_exclude_unset: typing.Any = {
+ "by_alias": True,
+ "exclude_unset": True,
+ **kwargs,
+ }
+ kwargs_with_defaults_exclude_none: typing.Any = {
+ "by_alias": True,
+ "exclude_none": True,
+ **kwargs,
+ }
+
+ return deep_union_pydantic_dicts(
+ super().dict(**kwargs_with_defaults_exclude_unset),
+ super().dict(**kwargs_with_defaults_exclude_none),
+ )
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic_v1.Extra.allow
+ json_encoders = {dt.datetime: serialize_datetime}
diff --git a/langfuse/api/resources/ingestion/types/open_ai_response_usage_schema.py b/langfuse/api/resources/ingestion/types/open_ai_response_usage_schema.py
new file mode 100644
index 000000000..99b0bbfa0
--- /dev/null
+++ b/langfuse/api/resources/ingestion/types/open_ai_response_usage_schema.py
@@ -0,0 +1,50 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import datetime as dt
+import typing
+
+from ....core.datetime_utils import serialize_datetime
+from ....core.pydantic_utilities import deep_union_pydantic_dicts, pydantic_v1
+
+
+class OpenAiResponseUsageSchema(pydantic_v1.BaseModel):
+ """
+ OpenAI Usage schema from Response API
+ """
+
+ input_tokens: int
+ output_tokens: int
+ total_tokens: int
+ input_tokens_details: typing.Optional[typing.Dict[str, int]] = None
+ output_tokens_details: typing.Optional[typing.Dict[str, int]] = None
+
+ def json(self, **kwargs: typing.Any) -> str:
+ kwargs_with_defaults: typing.Any = {
+ "by_alias": True,
+ "exclude_unset": True,
+ **kwargs,
+ }
+ return super().json(**kwargs_with_defaults)
+
+ def dict(self, **kwargs: typing.Any) -> typing.Dict[str, typing.Any]:
+ kwargs_with_defaults_exclude_unset: typing.Any = {
+ "by_alias": True,
+ "exclude_unset": True,
+ **kwargs,
+ }
+ kwargs_with_defaults_exclude_none: typing.Any = {
+ "by_alias": True,
+ "exclude_none": True,
+ **kwargs,
+ }
+
+ return deep_union_pydantic_dicts(
+ super().dict(**kwargs_with_defaults_exclude_unset),
+ super().dict(**kwargs_with_defaults_exclude_none),
+ )
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic_v1.Extra.allow
+ json_encoders = {dt.datetime: serialize_datetime}
diff --git a/langfuse/api/resources/ingestion/types/usage_details.py b/langfuse/api/resources/ingestion/types/usage_details.py
index 89c0fc2e9..beb98cbd0 100644
--- a/langfuse/api/resources/ingestion/types/usage_details.py
+++ b/langfuse/api/resources/ingestion/types/usage_details.py
@@ -2,6 +2,9 @@
import typing
-from .open_ai_usage_schema import OpenAiUsageSchema
+from .open_ai_completion_usage_schema import OpenAiCompletionUsageSchema
+from .open_ai_response_usage_schema import OpenAiResponseUsageSchema
-UsageDetails = typing.Union[typing.Dict[str, int], OpenAiUsageSchema]
+UsageDetails = typing.Union[
+ typing.Dict[str, int], OpenAiCompletionUsageSchema, OpenAiResponseUsageSchema
+]
diff --git a/langfuse/api/resources/media/client.py b/langfuse/api/resources/media/client.py
index 0dcd75e8e..bb8e4b149 100644
--- a/langfuse/api/resources/media/client.py
+++ b/langfuse/api/resources/media/client.py
@@ -57,7 +57,7 @@ def get(
base_url="https://yourhost.com/path/to/api",
)
client.media.get(
- media_id="string",
+ media_id="mediaId",
)
"""
_response = self._client_wrapper.httpx_client.request(
@@ -131,14 +131,12 @@ def patch(
base_url="https://yourhost.com/path/to/api",
)
client.media.patch(
- media_id="string",
+ media_id="mediaId",
request=PatchMediaBody(
uploaded_at=datetime.datetime.fromisoformat(
"2024-01-15 09:30:00+00:00",
),
upload_http_status=1,
- upload_http_error="string",
- upload_time_ms=1,
),
)
"""
@@ -210,12 +208,11 @@ def get_upload_url(
)
client.media.get_upload_url(
request=GetMediaUploadUrlRequest(
- trace_id="string",
- observation_id="string",
+ trace_id="traceId",
content_type=MediaContentType.IMAGE_PNG,
content_length=1,
- sha_256_hash="string",
- field="string",
+ sha_256_hash="sha256Hash",
+ field="field",
),
)
"""
@@ -295,7 +292,7 @@ async def get(
async def main() -> None:
await client.media.get(
- media_id="string",
+ media_id="mediaId",
)
@@ -376,14 +373,12 @@ async def patch(
async def main() -> None:
await client.media.patch(
- media_id="string",
+ media_id="mediaId",
request=PatchMediaBody(
uploaded_at=datetime.datetime.fromisoformat(
"2024-01-15 09:30:00+00:00",
),
upload_http_status=1,
- upload_http_error="string",
- upload_time_ms=1,
),
)
@@ -463,12 +458,11 @@ async def get_upload_url(
async def main() -> None:
await client.media.get_upload_url(
request=GetMediaUploadUrlRequest(
- trace_id="string",
- observation_id="string",
+ trace_id="traceId",
content_type=MediaContentType.IMAGE_PNG,
content_length=1,
- sha_256_hash="string",
- field="string",
+ sha_256_hash="sha256Hash",
+ field="field",
),
)
diff --git a/langfuse/api/resources/metrics/client.py b/langfuse/api/resources/metrics/client.py
index 6447b1133..9ae8666c9 100644
--- a/langfuse/api/resources/metrics/client.py
+++ b/langfuse/api/resources/metrics/client.py
@@ -29,6 +29,7 @@ def daily(
trace_name: typing.Optional[str] = None,
user_id: typing.Optional[str] = None,
tags: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None,
+ environment: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None,
from_timestamp: typing.Optional[dt.datetime] = None,
to_timestamp: typing.Optional[dt.datetime] = None,
request_options: typing.Optional[RequestOptions] = None,
@@ -53,6 +54,9 @@ def daily(
tags : typing.Optional[typing.Union[str, typing.Sequence[str]]]
Optional filter for metrics where traces include all of these tags
+ environment : typing.Optional[typing.Union[str, typing.Sequence[str]]]
+ Optional filter for metrics where events include any of these environments
+
from_timestamp : typing.Optional[dt.datetime]
Optional filter to only include traces and observations on or after a certain datetime (ISO 8601)
@@ -68,8 +72,6 @@ def daily(
Examples
--------
- import datetime
-
from langfuse.client import FernLangfuse
client = FernLangfuse(
@@ -80,19 +82,7 @@ def daily(
password="YOUR_PASSWORD",
base_url="https://yourhost.com/path/to/api",
)
- client.metrics.daily(
- page=1,
- limit=1,
- trace_name="string",
- user_id="string",
- tags="string",
- from_timestamp=datetime.datetime.fromisoformat(
- "2024-01-15 09:30:00+00:00",
- ),
- to_timestamp=datetime.datetime.fromisoformat(
- "2024-01-15 09:30:00+00:00",
- ),
- )
+ client.metrics.daily()
"""
_response = self._client_wrapper.httpx_client.request(
"api/public/metrics/daily",
@@ -103,6 +93,7 @@ def daily(
"traceName": trace_name,
"userId": user_id,
"tags": tags,
+ "environment": environment,
"fromTimestamp": serialize_datetime(from_timestamp)
if from_timestamp is not None
else None,
@@ -151,6 +142,7 @@ async def daily(
trace_name: typing.Optional[str] = None,
user_id: typing.Optional[str] = None,
tags: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None,
+ environment: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None,
from_timestamp: typing.Optional[dt.datetime] = None,
to_timestamp: typing.Optional[dt.datetime] = None,
request_options: typing.Optional[RequestOptions] = None,
@@ -175,6 +167,9 @@ async def daily(
tags : typing.Optional[typing.Union[str, typing.Sequence[str]]]
Optional filter for metrics where traces include all of these tags
+ environment : typing.Optional[typing.Union[str, typing.Sequence[str]]]
+ Optional filter for metrics where events include any of these environments
+
from_timestamp : typing.Optional[dt.datetime]
Optional filter to only include traces and observations on or after a certain datetime (ISO 8601)
@@ -191,7 +186,6 @@ async def daily(
Examples
--------
import asyncio
- import datetime
from langfuse.client import AsyncFernLangfuse
@@ -206,19 +200,7 @@ async def daily(
async def main() -> None:
- await client.metrics.daily(
- page=1,
- limit=1,
- trace_name="string",
- user_id="string",
- tags="string",
- from_timestamp=datetime.datetime.fromisoformat(
- "2024-01-15 09:30:00+00:00",
- ),
- to_timestamp=datetime.datetime.fromisoformat(
- "2024-01-15 09:30:00+00:00",
- ),
- )
+ await client.metrics.daily()
asyncio.run(main())
@@ -232,6 +214,7 @@ async def main() -> None:
"traceName": trace_name,
"userId": user_id,
"tags": tags,
+ "environment": environment,
"fromTimestamp": serialize_datetime(from_timestamp)
if from_timestamp is not None
else None,
diff --git a/langfuse/api/resources/models/client.py b/langfuse/api/resources/models/client.py
index 1ebac9d07..4f4b727fa 100644
--- a/langfuse/api/resources/models/client.py
+++ b/langfuse/api/resources/models/client.py
@@ -47,9 +47,7 @@ def create(
Examples
--------
- import datetime
-
- from langfuse import CreateModelRequest, ModelUsageUnit
+ from langfuse import CreateModelRequest
from langfuse.client import FernLangfuse
client = FernLangfuse(
@@ -62,17 +60,8 @@ def create(
)
client.models.create(
request=CreateModelRequest(
- model_name="string",
- match_pattern="string",
- start_date=datetime.datetime.fromisoformat(
- "2024-01-15 09:30:00+00:00",
- ),
- unit=ModelUsageUnit.CHARACTERS,
- input_price=1.1,
- output_price=1.1,
- total_price=1.1,
- tokenizer_id="string",
- tokenizer_config={"key": "value"},
+ model_name="modelName",
+ match_pattern="matchPattern",
),
)
"""
@@ -146,10 +135,7 @@ def list(
password="YOUR_PASSWORD",
base_url="https://yourhost.com/path/to/api",
)
- client.models.list(
- page=1,
- limit=1,
- )
+ client.models.list()
"""
_response = self._client_wrapper.httpx_client.request(
"api/public/models",
@@ -213,7 +199,7 @@ def get(
base_url="https://yourhost.com/path/to/api",
)
client.models.get(
- id="string",
+ id="id",
)
"""
_response = self._client_wrapper.httpx_client.request(
@@ -277,7 +263,7 @@ def delete(
base_url="https://yourhost.com/path/to/api",
)
client.models.delete(
- id="string",
+ id="id",
)
"""
_response = self._client_wrapper.httpx_client.request(
@@ -339,9 +325,8 @@ async def create(
Examples
--------
import asyncio
- import datetime
- from langfuse import CreateModelRequest, ModelUsageUnit
+ from langfuse import CreateModelRequest
from langfuse.client import AsyncFernLangfuse
client = AsyncFernLangfuse(
@@ -357,17 +342,8 @@ async def create(
async def main() -> None:
await client.models.create(
request=CreateModelRequest(
- model_name="string",
- match_pattern="string",
- start_date=datetime.datetime.fromisoformat(
- "2024-01-15 09:30:00+00:00",
- ),
- unit=ModelUsageUnit.CHARACTERS,
- input_price=1.1,
- output_price=1.1,
- total_price=1.1,
- tokenizer_id="string",
- tokenizer_config={"key": "value"},
+ model_name="modelName",
+ match_pattern="matchPattern",
),
)
@@ -449,10 +425,7 @@ async def list(
async def main() -> None:
- await client.models.list(
- page=1,
- limit=1,
- )
+ await client.models.list()
asyncio.run(main())
@@ -524,7 +497,7 @@ async def get(
async def main() -> None:
await client.models.get(
- id="string",
+ id="id",
)
@@ -596,7 +569,7 @@ async def delete(
async def main() -> None:
await client.models.delete(
- id="string",
+ id="id",
)
diff --git a/langfuse/api/resources/observations/client.py b/langfuse/api/resources/observations/client.py
index d937841b9..180a48949 100644
--- a/langfuse/api/resources/observations/client.py
+++ b/langfuse/api/resources/observations/client.py
@@ -57,7 +57,7 @@ def get(
base_url="https://yourhost.com/path/to/api",
)
client.observations.get(
- observation_id="string",
+ observation_id="observationId",
)
"""
_response = self._client_wrapper.httpx_client.request(
@@ -101,6 +101,7 @@ def get_many(
type: typing.Optional[str] = None,
trace_id: typing.Optional[str] = None,
parent_observation_id: typing.Optional[str] = None,
+ environment: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None,
from_start_time: typing.Optional[dt.datetime] = None,
to_start_time: typing.Optional[dt.datetime] = None,
version: typing.Optional[str] = None,
@@ -127,6 +128,9 @@ def get_many(
parent_observation_id : typing.Optional[str]
+ environment : typing.Optional[typing.Union[str, typing.Sequence[str]]]
+ Optional filter for observations where the environment is one of the provided values.
+
from_start_time : typing.Optional[dt.datetime]
Retrieve only observations with a start_time or or after this datetime (ISO 8601).
@@ -145,8 +149,6 @@ def get_many(
Examples
--------
- import datetime
-
from langfuse.client import FernLangfuse
client = FernLangfuse(
@@ -157,22 +159,7 @@ def get_many(
password="YOUR_PASSWORD",
base_url="https://yourhost.com/path/to/api",
)
- client.observations.get_many(
- page=1,
- limit=1,
- name="string",
- user_id="string",
- type="string",
- trace_id="string",
- parent_observation_id="string",
- from_start_time=datetime.datetime.fromisoformat(
- "2024-01-15 09:30:00+00:00",
- ),
- to_start_time=datetime.datetime.fromisoformat(
- "2024-01-15 09:30:00+00:00",
- ),
- version="string",
- )
+ client.observations.get_many()
"""
_response = self._client_wrapper.httpx_client.request(
"api/public/observations",
@@ -185,6 +172,7 @@ def get_many(
"type": type,
"traceId": trace_id,
"parentObservationId": parent_observation_id,
+ "environment": environment,
"fromStartTime": serialize_datetime(from_start_time)
if from_start_time is not None
else None,
@@ -265,7 +253,7 @@ async def get(
async def main() -> None:
await client.observations.get(
- observation_id="string",
+ observation_id="observationId",
)
@@ -312,6 +300,7 @@ async def get_many(
type: typing.Optional[str] = None,
trace_id: typing.Optional[str] = None,
parent_observation_id: typing.Optional[str] = None,
+ environment: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None,
from_start_time: typing.Optional[dt.datetime] = None,
to_start_time: typing.Optional[dt.datetime] = None,
version: typing.Optional[str] = None,
@@ -338,6 +327,9 @@ async def get_many(
parent_observation_id : typing.Optional[str]
+ environment : typing.Optional[typing.Union[str, typing.Sequence[str]]]
+ Optional filter for observations where the environment is one of the provided values.
+
from_start_time : typing.Optional[dt.datetime]
Retrieve only observations with a start_time or or after this datetime (ISO 8601).
@@ -357,7 +349,6 @@ async def get_many(
Examples
--------
import asyncio
- import datetime
from langfuse.client import AsyncFernLangfuse
@@ -372,22 +363,7 @@ async def get_many(
async def main() -> None:
- await client.observations.get_many(
- page=1,
- limit=1,
- name="string",
- user_id="string",
- type="string",
- trace_id="string",
- parent_observation_id="string",
- from_start_time=datetime.datetime.fromisoformat(
- "2024-01-15 09:30:00+00:00",
- ),
- to_start_time=datetime.datetime.fromisoformat(
- "2024-01-15 09:30:00+00:00",
- ),
- version="string",
- )
+ await client.observations.get_many()
asyncio.run(main())
@@ -403,6 +379,7 @@ async def main() -> None:
"type": type,
"traceId": trace_id,
"parentObservationId": parent_observation_id,
+ "environment": environment,
"fromStartTime": serialize_datetime(from_start_time)
if from_start_time is not None
else None,
diff --git a/langfuse/api/resources/prompt_version/client.py b/langfuse/api/resources/prompt_version/client.py
index 638871082..89140941d 100644
--- a/langfuse/api/resources/prompt_version/client.py
+++ b/langfuse/api/resources/prompt_version/client.py
@@ -65,9 +65,9 @@ def update(
base_url="https://yourhost.com/path/to/api",
)
client.prompt_version.update(
- name="string",
+ name="name",
version=1,
- new_labels=["string"],
+ new_labels=["newLabels", "newLabels"],
)
"""
_response = self._client_wrapper.httpx_client.request(
@@ -155,9 +155,9 @@ async def update(
async def main() -> None:
await client.prompt_version.update(
- name="string",
+ name="name",
version=1,
- new_labels=["string"],
+ new_labels=["newLabels", "newLabels"],
)
diff --git a/langfuse/api/resources/prompts/client.py b/langfuse/api/resources/prompts/client.py
index 5ca4c4aa5..b41ab5642 100644
--- a/langfuse/api/resources/prompts/client.py
+++ b/langfuse/api/resources/prompts/client.py
@@ -69,9 +69,7 @@ def get(
base_url="https://yourhost.com/path/to/api",
)
client.prompts.get(
- prompt_name="string",
- version=1,
- label="string",
+ prompt_name="promptName",
)
"""
_response = self._client_wrapper.httpx_client.request(
@@ -150,8 +148,6 @@ def list(
Examples
--------
- import datetime
-
from langfuse.client import FernLangfuse
client = FernLangfuse(
@@ -162,19 +158,7 @@ def list(
password="YOUR_PASSWORD",
base_url="https://yourhost.com/path/to/api",
)
- client.prompts.list(
- name="string",
- label="string",
- tag="string",
- page=1,
- limit=1,
- from_updated_at=datetime.datetime.fromisoformat(
- "2024-01-15 09:30:00+00:00",
- ),
- to_updated_at=datetime.datetime.fromisoformat(
- "2024-01-15 09:30:00+00:00",
- ),
- )
+ client.prompts.list()
"""
_response = self._client_wrapper.httpx_client.request(
"api/public/v2/prompts",
@@ -257,17 +241,17 @@ def create(
)
client.prompts.create(
request=CreatePromptRequest_Chat(
- name="string",
+ name="name",
prompt=[
ChatMessage(
- role="string",
- content="string",
- )
+ role="role",
+ content="content",
+ ),
+ ChatMessage(
+ role="role",
+ content="content",
+ ),
],
- config={"key": "value"},
- labels=["string"],
- tags=["string"],
- commit_message="string",
),
)
"""
@@ -356,9 +340,7 @@ async def get(
async def main() -> None:
await client.prompts.get(
- prompt_name="string",
- version=1,
- label="string",
+ prompt_name="promptName",
)
@@ -441,7 +423,6 @@ async def list(
Examples
--------
import asyncio
- import datetime
from langfuse.client import AsyncFernLangfuse
@@ -456,19 +437,7 @@ async def list(
async def main() -> None:
- await client.prompts.list(
- name="string",
- label="string",
- tag="string",
- page=1,
- limit=1,
- from_updated_at=datetime.datetime.fromisoformat(
- "2024-01-15 09:30:00+00:00",
- ),
- to_updated_at=datetime.datetime.fromisoformat(
- "2024-01-15 09:30:00+00:00",
- ),
- )
+ await client.prompts.list()
asyncio.run(main())
@@ -559,17 +528,17 @@ async def create(
async def main() -> None:
await client.prompts.create(
request=CreatePromptRequest_Chat(
- name="string",
+ name="name",
prompt=[
ChatMessage(
- role="string",
- content="string",
- )
+ role="role",
+ content="content",
+ ),
+ ChatMessage(
+ role="role",
+ content="content",
+ ),
],
- config={"key": "value"},
- labels=["string"],
- tags=["string"],
- commit_message="string",
),
)
diff --git a/langfuse/api/resources/prompts/types/base_prompt.py b/langfuse/api/resources/prompts/types/base_prompt.py
index 576110b75..eff295cc5 100644
--- a/langfuse/api/resources/prompts/types/base_prompt.py
+++ b/langfuse/api/resources/prompts/types/base_prompt.py
@@ -28,6 +28,13 @@ class BasePrompt(pydantic_v1.BaseModel):
Commit message for this prompt version.
"""
+ resolution_graph: typing.Optional[typing.Dict[str, typing.Any]] = pydantic_v1.Field(
+ alias="resolutionGraph", default=None
+ )
+ """
+ The dependency resolution graph for the current prompt. Null if prompt has no dependencies.
+ """
+
def json(self, **kwargs: typing.Any) -> str:
kwargs_with_defaults: typing.Any = {
"by_alias": True,
diff --git a/langfuse/api/resources/prompts/types/prompt.py b/langfuse/api/resources/prompts/types/prompt.py
index 9c91b85d8..2fee54b70 100644
--- a/langfuse/api/resources/prompts/types/prompt.py
+++ b/langfuse/api/resources/prompts/types/prompt.py
@@ -20,6 +20,9 @@ class Prompt_Chat(pydantic_v1.BaseModel):
commit_message: typing.Optional[str] = pydantic_v1.Field(
alias="commitMessage", default=None
)
+ resolution_graph: typing.Optional[typing.Dict[str, typing.Any]] = pydantic_v1.Field(
+ alias="resolutionGraph", default=None
+ )
type: typing.Literal["chat"] = "chat"
def json(self, **kwargs: typing.Any) -> str:
@@ -66,6 +69,9 @@ class Prompt_Text(pydantic_v1.BaseModel):
commit_message: typing.Optional[str] = pydantic_v1.Field(
alias="commitMessage", default=None
)
+ resolution_graph: typing.Optional[typing.Dict[str, typing.Any]] = pydantic_v1.Field(
+ alias="resolutionGraph", default=None
+ )
type: typing.Literal["text"] = "text"
def json(self, **kwargs: typing.Any) -> str:
diff --git a/langfuse/api/resources/score/client.py b/langfuse/api/resources/score/client.py
index 9c40a48f7..774f4f218 100644
--- a/langfuse/api/resources/score/client.py
+++ b/langfuse/api/resources/score/client.py
@@ -65,9 +65,9 @@ def create(
)
client.score.create(
request=CreateScoreRequest(
- name="novelty",
- value=0.9,
- trace_id="cdef-1234-5678-90ab",
+ trace_id="traceId",
+ name="name",
+ value=1.1,
),
)
"""
@@ -113,6 +113,7 @@ def get(
name: typing.Optional[str] = None,
from_timestamp: typing.Optional[dt.datetime] = None,
to_timestamp: typing.Optional[dt.datetime] = None,
+ environment: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None,
source: typing.Optional[ScoreSource] = None,
operator: typing.Optional[str] = None,
value: typing.Optional[float] = None,
@@ -146,6 +147,9 @@ def get(
to_timestamp : typing.Optional[dt.datetime]
Optional filter to only include scores created before a certain datetime (ISO 8601)
+ environment : typing.Optional[typing.Union[str, typing.Sequence[str]]]
+ Optional filter for scores where the environment is one of the provided values.
+
source : typing.Optional[ScoreSource]
Retrieve only scores from a specific source.
@@ -179,9 +183,6 @@ def get(
Examples
--------
- import datetime
-
- from langfuse import ScoreDataType, ScoreSource
from langfuse.client import FernLangfuse
client = FernLangfuse(
@@ -192,26 +193,7 @@ def get(
password="YOUR_PASSWORD",
base_url="https://yourhost.com/path/to/api",
)
- client.score.get(
- page=1,
- limit=1,
- user_id="string",
- name="string",
- from_timestamp=datetime.datetime.fromisoformat(
- "2024-01-15 09:30:00+00:00",
- ),
- to_timestamp=datetime.datetime.fromisoformat(
- "2024-01-15 09:30:00+00:00",
- ),
- source=ScoreSource.ANNOTATION,
- operator="string",
- value=1.1,
- score_ids="string",
- config_id="string",
- queue_id="string",
- data_type=ScoreDataType.NUMERIC,
- trace_tags="string",
- )
+ client.score.get()
"""
_response = self._client_wrapper.httpx_client.request(
"api/public/scores",
@@ -227,6 +209,7 @@ def get(
"toTimestamp": serialize_datetime(to_timestamp)
if to_timestamp is not None
else None,
+ "environment": environment,
"source": source,
"operator": operator,
"value": value,
@@ -295,7 +278,7 @@ def get_by_id(
base_url="https://yourhost.com/path/to/api",
)
client.score.get_by_id(
- score_id="string",
+ score_id="scoreId",
)
"""
_response = self._client_wrapper.httpx_client.request(
@@ -360,7 +343,7 @@ def delete(
base_url="https://yourhost.com/path/to/api",
)
client.score.delete(
- score_id="string",
+ score_id="scoreId",
)
"""
_response = self._client_wrapper.httpx_client.request(
@@ -439,9 +422,9 @@ async def create(
async def main() -> None:
await client.score.create(
request=CreateScoreRequest(
- name="novelty",
- value=0.9,
- trace_id="cdef-1234-5678-90ab",
+ trace_id="traceId",
+ name="name",
+ value=1.1,
),
)
@@ -490,6 +473,7 @@ async def get(
name: typing.Optional[str] = None,
from_timestamp: typing.Optional[dt.datetime] = None,
to_timestamp: typing.Optional[dt.datetime] = None,
+ environment: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None,
source: typing.Optional[ScoreSource] = None,
operator: typing.Optional[str] = None,
value: typing.Optional[float] = None,
@@ -523,6 +507,9 @@ async def get(
to_timestamp : typing.Optional[dt.datetime]
Optional filter to only include scores created before a certain datetime (ISO 8601)
+ environment : typing.Optional[typing.Union[str, typing.Sequence[str]]]
+ Optional filter for scores where the environment is one of the provided values.
+
source : typing.Optional[ScoreSource]
Retrieve only scores from a specific source.
@@ -557,9 +544,7 @@ async def get(
Examples
--------
import asyncio
- import datetime
- from langfuse import ScoreDataType, ScoreSource
from langfuse.client import AsyncFernLangfuse
client = AsyncFernLangfuse(
@@ -573,26 +558,7 @@ async def get(
async def main() -> None:
- await client.score.get(
- page=1,
- limit=1,
- user_id="string",
- name="string",
- from_timestamp=datetime.datetime.fromisoformat(
- "2024-01-15 09:30:00+00:00",
- ),
- to_timestamp=datetime.datetime.fromisoformat(
- "2024-01-15 09:30:00+00:00",
- ),
- source=ScoreSource.ANNOTATION,
- operator="string",
- value=1.1,
- score_ids="string",
- config_id="string",
- queue_id="string",
- data_type=ScoreDataType.NUMERIC,
- trace_tags="string",
- )
+ await client.score.get()
asyncio.run(main())
@@ -611,6 +577,7 @@ async def main() -> None:
"toTimestamp": serialize_datetime(to_timestamp)
if to_timestamp is not None
else None,
+ "environment": environment,
"source": source,
"operator": operator,
"value": value,
@@ -684,7 +651,7 @@ async def get_by_id(
async def main() -> None:
await client.score.get_by_id(
- score_id="string",
+ score_id="scoreId",
)
@@ -757,7 +724,7 @@ async def delete(
async def main() -> None:
await client.score.delete(
- score_id="string",
+ score_id="scoreId",
)
diff --git a/langfuse/api/resources/score/types/create_score_request.py b/langfuse/api/resources/score/types/create_score_request.py
index 8a76f464e..c11030f4f 100644
--- a/langfuse/api/resources/score/types/create_score_request.py
+++ b/langfuse/api/resources/score/types/create_score_request.py
@@ -34,6 +34,11 @@ class CreateScoreRequest(pydantic_v1.BaseModel):
alias="observationId", default=None
)
comment: typing.Optional[str] = None
+ environment: typing.Optional[str] = pydantic_v1.Field(default=None)
+ """
+ The environment of the score. Can be any lowercase alphanumeric string with hyphens and underscores that does not start with 'langfuse'.
+ """
+
data_type: typing.Optional[ScoreDataType] = pydantic_v1.Field(
alias="dataType", default=None
)
diff --git a/langfuse/api/resources/score/types/get_scores_response_trace_data.py b/langfuse/api/resources/score/types/get_scores_response_trace_data.py
index efbafadf4..6e5539e35 100644
--- a/langfuse/api/resources/score/types/get_scores_response_trace_data.py
+++ b/langfuse/api/resources/score/types/get_scores_response_trace_data.py
@@ -18,6 +18,11 @@ class GetScoresResponseTraceData(pydantic_v1.BaseModel):
A list of tags associated with the trace referenced by score
"""
+ environment: typing.Optional[str] = pydantic_v1.Field(default=None)
+ """
+ The environment of the trace referenced by score
+ """
+
def json(self, **kwargs: typing.Any) -> str:
kwargs_with_defaults: typing.Any = {
"by_alias": True,
diff --git a/langfuse/api/resources/score_configs/client.py b/langfuse/api/resources/score_configs/client.py
index 5f8463612..7bd2a72df 100644
--- a/langfuse/api/resources/score_configs/client.py
+++ b/langfuse/api/resources/score_configs/client.py
@@ -47,7 +47,7 @@ def create(
Examples
--------
- from langfuse import ConfigCategory, CreateScoreConfigRequest, ScoreDataType
+ from langfuse import CreateScoreConfigRequest, ScoreDataType
from langfuse.client import FernLangfuse
client = FernLangfuse(
@@ -60,17 +60,8 @@ def create(
)
client.score_configs.create(
request=CreateScoreConfigRequest(
- name="string",
+ name="name",
data_type=ScoreDataType.NUMERIC,
- categories=[
- ConfigCategory(
- value=1.1,
- label="string",
- )
- ],
- min_value=1.1,
- max_value=1.1,
- description="string",
),
)
"""
@@ -144,10 +135,7 @@ def get(
password="YOUR_PASSWORD",
base_url="https://yourhost.com/path/to/api",
)
- client.score_configs.get(
- page=1,
- limit=1,
- )
+ client.score_configs.get()
"""
_response = self._client_wrapper.httpx_client.request(
"api/public/score-configs",
@@ -212,7 +200,7 @@ def get_by_id(
base_url="https://yourhost.com/path/to/api",
)
client.score_configs.get_by_id(
- config_id="string",
+ config_id="configId",
)
"""
_response = self._client_wrapper.httpx_client.request(
@@ -275,7 +263,7 @@ async def create(
--------
import asyncio
- from langfuse import ConfigCategory, CreateScoreConfigRequest, ScoreDataType
+ from langfuse import CreateScoreConfigRequest, ScoreDataType
from langfuse.client import AsyncFernLangfuse
client = AsyncFernLangfuse(
@@ -291,17 +279,8 @@ async def create(
async def main() -> None:
await client.score_configs.create(
request=CreateScoreConfigRequest(
- name="string",
+ name="name",
data_type=ScoreDataType.NUMERIC,
- categories=[
- ConfigCategory(
- value=1.1,
- label="string",
- )
- ],
- min_value=1.1,
- max_value=1.1,
- description="string",
),
)
@@ -383,10 +362,7 @@ async def get(
async def main() -> None:
- await client.score_configs.get(
- page=1,
- limit=1,
- )
+ await client.score_configs.get()
asyncio.run(main())
@@ -459,7 +435,7 @@ async def get_by_id(
async def main() -> None:
await client.score_configs.get_by_id(
- config_id="string",
+ config_id="configId",
)
diff --git a/langfuse/api/resources/sessions/client.py b/langfuse/api/resources/sessions/client.py
index 98c56e0fc..d5ae779c3 100644
--- a/langfuse/api/resources/sessions/client.py
+++ b/langfuse/api/resources/sessions/client.py
@@ -30,6 +30,7 @@ def list(
limit: typing.Optional[int] = None,
from_timestamp: typing.Optional[dt.datetime] = None,
to_timestamp: typing.Optional[dt.datetime] = None,
+ environment: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None,
request_options: typing.Optional[RequestOptions] = None,
) -> PaginatedSessions:
"""
@@ -49,6 +50,9 @@ def list(
to_timestamp : typing.Optional[dt.datetime]
Optional filter to only include sessions created before a certain datetime (ISO 8601)
+ environment : typing.Optional[typing.Union[str, typing.Sequence[str]]]
+ Optional filter for sessions where the environment is one of the provided values.
+
request_options : typing.Optional[RequestOptions]
Request-specific configuration.
@@ -58,8 +62,6 @@ def list(
Examples
--------
- import datetime
-
from langfuse.client import FernLangfuse
client = FernLangfuse(
@@ -70,16 +72,7 @@ def list(
password="YOUR_PASSWORD",
base_url="https://yourhost.com/path/to/api",
)
- client.sessions.list(
- page=1,
- limit=1,
- from_timestamp=datetime.datetime.fromisoformat(
- "2024-01-15 09:30:00+00:00",
- ),
- to_timestamp=datetime.datetime.fromisoformat(
- "2024-01-15 09:30:00+00:00",
- ),
- )
+ client.sessions.list()
"""
_response = self._client_wrapper.httpx_client.request(
"api/public/sessions",
@@ -93,6 +86,7 @@ def list(
"toTimestamp": serialize_datetime(to_timestamp)
if to_timestamp is not None
else None,
+ "environment": environment,
},
request_options=request_options,
)
@@ -156,7 +150,7 @@ def get(
base_url="https://yourhost.com/path/to/api",
)
client.sessions.get(
- session_id="string",
+ session_id="sessionId",
)
"""
_response = self._client_wrapper.httpx_client.request(
@@ -202,6 +196,7 @@ async def list(
limit: typing.Optional[int] = None,
from_timestamp: typing.Optional[dt.datetime] = None,
to_timestamp: typing.Optional[dt.datetime] = None,
+ environment: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None,
request_options: typing.Optional[RequestOptions] = None,
) -> PaginatedSessions:
"""
@@ -221,6 +216,9 @@ async def list(
to_timestamp : typing.Optional[dt.datetime]
Optional filter to only include sessions created before a certain datetime (ISO 8601)
+ environment : typing.Optional[typing.Union[str, typing.Sequence[str]]]
+ Optional filter for sessions where the environment is one of the provided values.
+
request_options : typing.Optional[RequestOptions]
Request-specific configuration.
@@ -231,7 +229,6 @@ async def list(
Examples
--------
import asyncio
- import datetime
from langfuse.client import AsyncFernLangfuse
@@ -246,16 +243,7 @@ async def list(
async def main() -> None:
- await client.sessions.list(
- page=1,
- limit=1,
- from_timestamp=datetime.datetime.fromisoformat(
- "2024-01-15 09:30:00+00:00",
- ),
- to_timestamp=datetime.datetime.fromisoformat(
- "2024-01-15 09:30:00+00:00",
- ),
- )
+ await client.sessions.list()
asyncio.run(main())
@@ -272,6 +260,7 @@ async def main() -> None:
"toTimestamp": serialize_datetime(to_timestamp)
if to_timestamp is not None
else None,
+ "environment": environment,
},
request_options=request_options,
)
@@ -340,7 +329,7 @@ async def get(
async def main() -> None:
await client.sessions.get(
- session_id="string",
+ session_id="sessionId",
)
diff --git a/langfuse/api/resources/trace/__init__.py b/langfuse/api/resources/trace/__init__.py
index a2135eb9e..17855e971 100644
--- a/langfuse/api/resources/trace/__init__.py
+++ b/langfuse/api/resources/trace/__init__.py
@@ -1,5 +1,5 @@
# This file was auto-generated by Fern from our API Definition.
-from .types import Sort, Traces
+from .types import DeleteTraceResponse, Sort, Traces
-__all__ = ["Sort", "Traces"]
+__all__ = ["DeleteTraceResponse", "Sort", "Traces"]
diff --git a/langfuse/api/resources/trace/client.py b/langfuse/api/resources/trace/client.py
index 0c33e90d5..ece75f3a6 100644
--- a/langfuse/api/resources/trace/client.py
+++ b/langfuse/api/resources/trace/client.py
@@ -16,8 +16,12 @@
from ..commons.errors.not_found_error import NotFoundError
from ..commons.errors.unauthorized_error import UnauthorizedError
from ..commons.types.trace_with_full_details import TraceWithFullDetails
+from .types.delete_trace_response import DeleteTraceResponse
from .types.traces import Traces
+# this is used as the default value for optional parameters
+OMIT = typing.cast(typing.Any, ...)
+
class TraceClient:
def __init__(self, *, client_wrapper: SyncClientWrapper):
@@ -54,7 +58,7 @@ def get(
base_url="https://yourhost.com/path/to/api",
)
client.trace.get(
- trace_id="string",
+ trace_id="traceId",
)
"""
_response = self._client_wrapper.httpx_client.request(
@@ -88,6 +92,71 @@ def get(
raise ApiError(status_code=_response.status_code, body=_response.text)
raise ApiError(status_code=_response.status_code, body=_response_json)
+ def delete(
+ self, trace_id: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> DeleteTraceResponse:
+ """
+ Delete a specific trace
+
+ Parameters
+ ----------
+ trace_id : str
+ The unique langfuse identifier of the trace to delete
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ DeleteTraceResponse
+
+ Examples
+ --------
+ 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.trace.delete(
+ trace_id="traceId",
+ )
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"api/public/traces/{jsonable_encoder(trace_id)}",
+ method="DELETE",
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ return pydantic_v1.parse_obj_as(DeleteTraceResponse, _response.json()) # type: ignore
+ if _response.status_code == 400:
+ raise Error(pydantic_v1.parse_obj_as(typing.Any, _response.json())) # type: ignore
+ if _response.status_code == 401:
+ raise UnauthorizedError(
+ pydantic_v1.parse_obj_as(typing.Any, _response.json())
+ ) # type: ignore
+ if _response.status_code == 403:
+ raise AccessDeniedError(
+ pydantic_v1.parse_obj_as(typing.Any, _response.json())
+ ) # type: ignore
+ if _response.status_code == 405:
+ raise MethodNotAllowedError(
+ pydantic_v1.parse_obj_as(typing.Any, _response.json())
+ ) # type: ignore
+ if _response.status_code == 404:
+ raise NotFoundError(
+ pydantic_v1.parse_obj_as(typing.Any, _response.json())
+ ) # type: ignore
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, body=_response.text)
+ raise ApiError(status_code=_response.status_code, body=_response_json)
+
def list(
self,
*,
@@ -102,6 +171,7 @@ def list(
tags: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None,
version: typing.Optional[str] = None,
release: typing.Optional[str] = None,
+ environment: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None,
request_options: typing.Optional[RequestOptions] = None,
) -> Traces:
"""
@@ -139,6 +209,9 @@ def list(
release : typing.Optional[str]
Optional filter to only include traces with a certain release.
+ environment : typing.Optional[typing.Union[str, typing.Sequence[str]]]
+ Optional filter for traces where the environment is one of the provided values.
+
request_options : typing.Optional[RequestOptions]
Request-specific configuration.
@@ -148,8 +221,6 @@ def list(
Examples
--------
- import datetime
-
from langfuse.client import FernLangfuse
client = FernLangfuse(
@@ -160,23 +231,7 @@ def list(
password="YOUR_PASSWORD",
base_url="https://yourhost.com/path/to/api",
)
- client.trace.list(
- page=1,
- limit=1,
- user_id="string",
- name="string",
- session_id="string",
- from_timestamp=datetime.datetime.fromisoformat(
- "2024-01-15 09:30:00+00:00",
- ),
- to_timestamp=datetime.datetime.fromisoformat(
- "2024-01-15 09:30:00+00:00",
- ),
- order_by="string",
- tags="string",
- version="string",
- release="string",
- )
+ client.trace.list()
"""
_response = self._client_wrapper.httpx_client.request(
"api/public/traces",
@@ -197,6 +252,7 @@ def list(
"tags": tags,
"version": version,
"release": release,
+ "environment": environment,
},
request_options=request_options,
)
@@ -226,6 +282,76 @@ def list(
raise ApiError(status_code=_response.status_code, body=_response.text)
raise ApiError(status_code=_response.status_code, body=_response_json)
+ def delete_multiple(
+ self,
+ *,
+ trace_ids: typing.Sequence[str],
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> DeleteTraceResponse:
+ """
+ Delete multiple traces
+
+ Parameters
+ ----------
+ trace_ids : typing.Sequence[str]
+ List of trace IDs to delete
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ DeleteTraceResponse
+
+ Examples
+ --------
+ 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.trace.delete_multiple(
+ trace_ids=["traceIds", "traceIds"],
+ )
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ "api/public/traces",
+ method="DELETE",
+ json={"traceIds": trace_ids},
+ request_options=request_options,
+ omit=OMIT,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ return pydantic_v1.parse_obj_as(DeleteTraceResponse, _response.json()) # type: ignore
+ if _response.status_code == 400:
+ raise Error(pydantic_v1.parse_obj_as(typing.Any, _response.json())) # type: ignore
+ if _response.status_code == 401:
+ raise UnauthorizedError(
+ pydantic_v1.parse_obj_as(typing.Any, _response.json())
+ ) # type: ignore
+ if _response.status_code == 403:
+ raise AccessDeniedError(
+ pydantic_v1.parse_obj_as(typing.Any, _response.json())
+ ) # type: ignore
+ if _response.status_code == 405:
+ raise MethodNotAllowedError(
+ pydantic_v1.parse_obj_as(typing.Any, _response.json())
+ ) # type: ignore
+ if _response.status_code == 404:
+ raise NotFoundError(
+ pydantic_v1.parse_obj_as(typing.Any, _response.json())
+ ) # type: ignore
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, body=_response.text)
+ raise ApiError(status_code=_response.status_code, body=_response_json)
+
class AsyncTraceClient:
def __init__(self, *, client_wrapper: AsyncClientWrapper):
@@ -267,7 +393,7 @@ async def get(
async def main() -> None:
await client.trace.get(
- trace_id="string",
+ trace_id="traceId",
)
@@ -304,6 +430,79 @@ async def main() -> None:
raise ApiError(status_code=_response.status_code, body=_response.text)
raise ApiError(status_code=_response.status_code, body=_response_json)
+ async def delete(
+ self, trace_id: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> DeleteTraceResponse:
+ """
+ Delete a specific trace
+
+ Parameters
+ ----------
+ trace_id : str
+ The unique langfuse identifier of the trace to delete
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ DeleteTraceResponse
+
+ Examples
+ --------
+ import asyncio
+
+ from langfuse.client import AsyncFernLangfuse
+
+ client = AsyncFernLangfuse(
+ 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",
+ )
+
+
+ async def main() -> None:
+ await client.trace.delete(
+ trace_id="traceId",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"api/public/traces/{jsonable_encoder(trace_id)}",
+ method="DELETE",
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ return pydantic_v1.parse_obj_as(DeleteTraceResponse, _response.json()) # type: ignore
+ if _response.status_code == 400:
+ raise Error(pydantic_v1.parse_obj_as(typing.Any, _response.json())) # type: ignore
+ if _response.status_code == 401:
+ raise UnauthorizedError(
+ pydantic_v1.parse_obj_as(typing.Any, _response.json())
+ ) # type: ignore
+ if _response.status_code == 403:
+ raise AccessDeniedError(
+ pydantic_v1.parse_obj_as(typing.Any, _response.json())
+ ) # type: ignore
+ if _response.status_code == 405:
+ raise MethodNotAllowedError(
+ pydantic_v1.parse_obj_as(typing.Any, _response.json())
+ ) # type: ignore
+ if _response.status_code == 404:
+ raise NotFoundError(
+ pydantic_v1.parse_obj_as(typing.Any, _response.json())
+ ) # type: ignore
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, body=_response.text)
+ raise ApiError(status_code=_response.status_code, body=_response_json)
+
async def list(
self,
*,
@@ -318,6 +517,7 @@ async def list(
tags: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None,
version: typing.Optional[str] = None,
release: typing.Optional[str] = None,
+ environment: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None,
request_options: typing.Optional[RequestOptions] = None,
) -> Traces:
"""
@@ -355,6 +555,9 @@ async def list(
release : typing.Optional[str]
Optional filter to only include traces with a certain release.
+ environment : typing.Optional[typing.Union[str, typing.Sequence[str]]]
+ Optional filter for traces where the environment is one of the provided values.
+
request_options : typing.Optional[RequestOptions]
Request-specific configuration.
@@ -365,7 +568,6 @@ async def list(
Examples
--------
import asyncio
- import datetime
from langfuse.client import AsyncFernLangfuse
@@ -380,23 +582,7 @@ async def list(
async def main() -> None:
- await client.trace.list(
- page=1,
- limit=1,
- user_id="string",
- name="string",
- session_id="string",
- from_timestamp=datetime.datetime.fromisoformat(
- "2024-01-15 09:30:00+00:00",
- ),
- to_timestamp=datetime.datetime.fromisoformat(
- "2024-01-15 09:30:00+00:00",
- ),
- order_by="string",
- tags="string",
- version="string",
- release="string",
- )
+ await client.trace.list()
asyncio.run(main())
@@ -420,6 +606,7 @@ async def main() -> None:
"tags": tags,
"version": version,
"release": release,
+ "environment": environment,
},
request_options=request_options,
)
@@ -448,3 +635,81 @@ async def main() -> None:
except JSONDecodeError:
raise ApiError(status_code=_response.status_code, body=_response.text)
raise ApiError(status_code=_response.status_code, body=_response_json)
+
+ async def delete_multiple(
+ self,
+ *,
+ trace_ids: typing.Sequence[str],
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> DeleteTraceResponse:
+ """
+ Delete multiple traces
+
+ Parameters
+ ----------
+ trace_ids : typing.Sequence[str]
+ List of trace IDs to delete
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ DeleteTraceResponse
+
+ Examples
+ --------
+ import asyncio
+
+ from langfuse.client import AsyncFernLangfuse
+
+ client = AsyncFernLangfuse(
+ 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",
+ )
+
+
+ async def main() -> None:
+ await client.trace.delete_multiple(
+ trace_ids=["traceIds", "traceIds"],
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ "api/public/traces",
+ method="DELETE",
+ json={"traceIds": trace_ids},
+ request_options=request_options,
+ omit=OMIT,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ return pydantic_v1.parse_obj_as(DeleteTraceResponse, _response.json()) # type: ignore
+ if _response.status_code == 400:
+ raise Error(pydantic_v1.parse_obj_as(typing.Any, _response.json())) # type: ignore
+ if _response.status_code == 401:
+ raise UnauthorizedError(
+ pydantic_v1.parse_obj_as(typing.Any, _response.json())
+ ) # type: ignore
+ if _response.status_code == 403:
+ raise AccessDeniedError(
+ pydantic_v1.parse_obj_as(typing.Any, _response.json())
+ ) # type: ignore
+ if _response.status_code == 405:
+ raise MethodNotAllowedError(
+ pydantic_v1.parse_obj_as(typing.Any, _response.json())
+ ) # type: ignore
+ if _response.status_code == 404:
+ raise NotFoundError(
+ pydantic_v1.parse_obj_as(typing.Any, _response.json())
+ ) # type: ignore
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, body=_response.text)
+ raise ApiError(status_code=_response.status_code, body=_response_json)
diff --git a/langfuse/api/resources/trace/types/__init__.py b/langfuse/api/resources/trace/types/__init__.py
index 7907a8b54..929a1e047 100644
--- a/langfuse/api/resources/trace/types/__init__.py
+++ b/langfuse/api/resources/trace/types/__init__.py
@@ -1,6 +1,7 @@
# This file was auto-generated by Fern from our API Definition.
+from .delete_trace_response import DeleteTraceResponse
from .sort import Sort
from .traces import Traces
-__all__ = ["Sort", "Traces"]
+__all__ = ["DeleteTraceResponse", "Sort", "Traces"]
diff --git a/langfuse/api/resources/trace/types/delete_trace_response.py b/langfuse/api/resources/trace/types/delete_trace_response.py
new file mode 100644
index 000000000..450c894e2
--- /dev/null
+++ b/langfuse/api/resources/trace/types/delete_trace_response.py
@@ -0,0 +1,42 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import datetime as dt
+import typing
+
+from ....core.datetime_utils import serialize_datetime
+from ....core.pydantic_utilities import deep_union_pydantic_dicts, pydantic_v1
+
+
+class DeleteTraceResponse(pydantic_v1.BaseModel):
+ message: str
+
+ def json(self, **kwargs: typing.Any) -> str:
+ kwargs_with_defaults: typing.Any = {
+ "by_alias": True,
+ "exclude_unset": True,
+ **kwargs,
+ }
+ return super().json(**kwargs_with_defaults)
+
+ def dict(self, **kwargs: typing.Any) -> typing.Dict[str, typing.Any]:
+ kwargs_with_defaults_exclude_unset: typing.Any = {
+ "by_alias": True,
+ "exclude_unset": True,
+ **kwargs,
+ }
+ kwargs_with_defaults_exclude_none: typing.Any = {
+ "by_alias": True,
+ "exclude_none": True,
+ **kwargs,
+ }
+
+ return deep_union_pydantic_dicts(
+ super().dict(**kwargs_with_defaults_exclude_unset),
+ super().dict(**kwargs_with_defaults_exclude_none),
+ )
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic_v1.Extra.allow
+ json_encoders = {dt.datetime: serialize_datetime}
diff --git a/langfuse/openai.py b/langfuse/openai.py
index 03d2585cd..37e3d1e07 100644
--- a/langfuse/openai.py
+++ b/langfuse/openai.py
@@ -128,6 +128,22 @@ class OpenAiDefinition:
sync=False,
min_version="1.50.0",
),
+ OpenAiDefinition(
+ module="openai.resources.responses",
+ object="Responses",
+ method="create",
+ type="chat",
+ sync=True,
+ min_version="1.66.0",
+ ),
+ OpenAiDefinition(
+ module="openai.resources.responses",
+ object="AsyncResponses",
+ method="create",
+ type="chat",
+ sync=False,
+ min_version="1.66.0",
+ ),
]
@@ -350,6 +366,10 @@ def _get_langfuse_data_from_kwargs(
if resource.type == "completion":
prompt = kwargs.get("prompt", None)
+
+ elif resource.object == "Responses":
+ prompt = kwargs.get("input", None)
+
elif resource.type == "chat":
prompt = _extract_chat_prompt(kwargs)
@@ -443,6 +463,7 @@ def _create_langfuse_update(
completion_start_time,
model=None,
usage=None,
+ metadata=None,
):
update = {
"end_time": _get_timestamp(),
@@ -452,6 +473,9 @@ def _create_langfuse_update(
if model is not None:
update["model"] = model
+ if metadata is not None:
+ update["metadata"] = metadata
+
if usage is not None:
update["usage"] = _parse_usage(usage)
@@ -464,7 +488,12 @@ def _parse_usage(usage=None):
usage_dict = usage.copy() if isinstance(usage, dict) else usage.__dict__.copy()
- for tokens_details in ["prompt_tokens_details", "completion_tokens_details"]:
+ for tokens_details in [
+ "prompt_tokens_details",
+ "completion_tokens_details",
+ "input_token_details",
+ "output_token_details",
+ ]:
if tokens_details in usage_dict and usage_dict[tokens_details] is not None:
tokens_details_dict = (
usage_dict[tokens_details]
@@ -478,6 +507,33 @@ def _parse_usage(usage=None):
return usage_dict
+def _extract_streamed_response_api_response(chunks):
+ completion, model, usage = None, None, None
+ metadata = {}
+
+ for raw_chunk in chunks:
+ chunk = raw_chunk.__dict__
+ if raw_response := chunk.get("response", None):
+ usage = chunk.get("usage", None)
+ response = raw_response.__dict__
+ model = response.get("model")
+
+ for key, val in response.items():
+ if key not in ["created_at", "model", "output", "usage", "text"]:
+ metadata[key] = val
+
+ if key == "output":
+ output = val
+ if not isinstance(output, list):
+ completion = output
+ elif len(output) > 1:
+ completion = output
+ elif len(output) == 1:
+ completion = output[0]
+
+ return (model, completion, usage, metadata)
+
+
def _extract_streamed_openai_response(resource, chunks):
completion = defaultdict(str) if resource.type == "chat" else ""
model, usage = None, None
@@ -587,6 +643,7 @@ def get_response_for_chat():
model,
get_response_for_chat() if resource.type == "chat" else completion,
usage,
+ None,
)
@@ -597,12 +654,24 @@ def _get_langfuse_data_from_default_response(resource: OpenAiDefinition, respons
model = response.get("model", None) or None
completion = None
+
if resource.type == "completion":
choices = response.get("choices", [])
if len(choices) > 0:
choice = choices[-1]
completion = choice.text if _is_openai_v1() else choice.get("text", None)
+
+ elif resource.object == "Responses":
+ output = response.get("output", {})
+
+ if not isinstance(output, list):
+ completion = output
+ elif len(output) > 1:
+ completion = output
+ elif len(output) == 1:
+ completion = output[0]
+
elif resource.type == "chat":
choices = response.get("choices", [])
if len(choices) > 0:
@@ -890,8 +959,10 @@ def __exit__(self, exc_type, exc_value, traceback):
pass
def _finalize(self):
- model, completion, usage = _extract_streamed_openai_response(
- self.resource, self.items
+ model, completion, usage, metadata = (
+ _extract_streamed_response_api_response(self.items)
+ if self.resource.object == "Responses"
+ else _extract_streamed_openai_response(self.resource, self.items)
)
# Avoiding the trace-update if trace-id is provided by user.
@@ -904,6 +975,7 @@ def _finalize(self):
self.completion_start_time,
model=model,
usage=usage,
+ metadata=metadata,
)
@@ -960,8 +1032,10 @@ async def __aexit__(self, exc_type, exc_value, traceback):
pass
async def _finalize(self):
- model, completion, usage = _extract_streamed_openai_response(
- self.resource, self.items
+ model, completion, usage, metadata = (
+ _extract_streamed_response_api_response(self.items)
+ if self.resource.object == "Responses"
+ else _extract_streamed_openai_response(self.resource, self.items)
)
# Avoiding the trace-update if trace-id is provided by user.
@@ -974,6 +1048,7 @@ async def _finalize(self):
self.completion_start_time,
model=model,
usage=usage,
+ metadata=metadata,
)
async def close(self) -> None:
diff --git a/poetry.lock b/poetry.lock
index ea86959f7..52744668f 100644
--- a/poetry.lock
+++ b/poetry.lock
@@ -3235,13 +3235,13 @@ sympy = "*"
[[package]]
name = "openai"
-version = "1.54.3"
+version = "1.66.3"
description = "The official Python library for the openai API"
optional = false
python-versions = ">=3.8"
files = [
- {file = "openai-1.54.3-py3-none-any.whl", hash = "sha256:f18dbaf09c50d70c4185b892a2a553f80681d1d866323a2da7f7be2f688615d5"},
- {file = "openai-1.54.3.tar.gz", hash = "sha256:7511b74eeb894ac0b0253dc71f087a15d2e4d71d22d0088767205143d880cca6"},
+ {file = "openai-1.66.3-py3-none-any.whl", hash = "sha256:a427c920f727711877ab17c11b95f1230b27767ba7a01e5b66102945141ceca9"},
+ {file = "openai-1.66.3.tar.gz", hash = "sha256:8dde3aebe2d081258d4159c4cb27bdc13b5bb3f7ea2201d9bd940b9a89faf0c9"},
]
[package.dependencies]
@@ -3256,6 +3256,7 @@ typing-extensions = ">=4.11,<5"
[package.extras]
datalib = ["numpy (>=1)", "pandas (>=1.2.3)", "pandas-stubs (>=1.1.0.11)"]
+realtime = ["websockets (>=13,<15)"]
[[package]]
name = "opentelemetry-api"
diff --git a/tests/test_openai.py b/tests/test_openai.py
index 31176bfae..ddaec0447 100644
--- a/tests/test_openai.py
+++ b/tests/test_openai.py
@@ -60,6 +60,7 @@ def test_openai_chat_completion():
assert len(completion.choices) != 0
assert generation.data[0].input == [
{
+ "annotations": None,
"content": "You are an expert mathematician",
"audio": None,
"function_call": None,
@@ -90,6 +91,7 @@ def test_openai_chat_completion():
trace = get_api().trace.get(generation.data[0].trace_id)
assert trace.input == [
{
+ "annotations": None,
"content": "You are an expert mathematician",
"audio": None,
"function_call": None,
@@ -1612,3 +1614,234 @@ def test_audio_input_and_output():
"@@@langfuseMedia:type=audio/wav|id="
in generation.data[0].output["audio"]["data"]
)
+
+
+def test_response_api_text_input():
+ client = openai.OpenAI()
+ generation_name = "test_response_api_text_input" + create_uuid()[:8]
+
+ client.responses.create(
+ name=generation_name,
+ model="gpt-4o",
+ input="Tell me a three sentence bedtime story about a unicorn.",
+ )
+
+ openai.flush_langfuse()
+ generation = get_api().observations.get_many(
+ name=generation_name, type="GENERATION"
+ )
+
+ assert len(generation.data) != 0
+ generationData = generation.data[0]
+ assert generationData.name == generation_name
+ assert (
+ generation.data[0].input
+ == "Tell me a three sentence bedtime story about a unicorn."
+ )
+ assert generationData.type == "GENERATION"
+ assert "gpt-4o" in generationData.model
+ assert generationData.start_time is not None
+ assert generationData.end_time is not None
+ assert generationData.start_time < generationData.end_time
+ assert generationData.usage.input is not None
+ assert generationData.usage.output is not None
+ assert generationData.usage.total is not None
+ assert generationData.output is not None
+
+
+def test_response_api_image_input():
+ client = openai.OpenAI()
+ generation_name = "test_response_api_image_input" + create_uuid()[:8]
+
+ client.responses.create(
+ name=generation_name,
+ model="gpt-4o",
+ input=[
+ {
+ "role": "user",
+ "content": [
+ {"type": "input_text", "text": "what is in this image?"},
+ {
+ "type": "input_image",
+ "image_url": "https://upload.wikimedia.org/wikipedia/commons/thumb/d/dd/Gfp-wisconsin-madison-the-nature-boardwalk.jpg/2560px-Gfp-wisconsin-madison-the-nature-boardwalk.jpg",
+ },
+ ],
+ }
+ ],
+ )
+
+ openai.flush_langfuse()
+
+ generation = get_api().observations.get_many(
+ name=generation_name, type="GENERATION"
+ )
+
+ assert len(generation.data) != 0
+ generationData = generation.data[0]
+ assert generationData.name == generation_name
+ assert generation.data[0].input[0]["content"][0]["text"] == "what is in this image?"
+ assert generationData.type == "GENERATION"
+ assert "gpt-4o" in generationData.model
+ assert generationData.start_time is not None
+ assert generationData.end_time is not None
+ assert generationData.start_time < generationData.end_time
+ assert generationData.usage.input is not None
+ assert generationData.usage.output is not None
+ assert generationData.usage.total is not None
+ assert generationData.output is not None
+
+
+def test_response_api_web_search():
+ client = openai.OpenAI()
+ generation_name = "test_response_api_web_search" + create_uuid()[:8]
+
+ client.responses.create(
+ name=generation_name,
+ model="gpt-4o",
+ tools=[{"type": "web_search_preview"}],
+ input="What was a positive news story from today?",
+ )
+
+ openai.flush_langfuse()
+
+ generation = get_api().observations.get_many(
+ name=generation_name, type="GENERATION"
+ )
+
+ assert len(generation.data) != 0
+ generationData = generation.data[0]
+ assert generationData.name == generation_name
+ assert generationData.input == "What was a positive news story from today?"
+ assert generationData.type == "GENERATION"
+ assert "gpt-4o" in generationData.model
+ assert generationData.start_time is not None
+ assert generationData.end_time is not None
+ assert generationData.start_time < generationData.end_time
+ assert generationData.usage.input is not None
+ assert generationData.usage.output is not None
+ assert generationData.usage.total is not None
+ assert generationData.output is not None
+ assert generationData.metadata is not None
+
+
+def test_response_api_streaming():
+ client = openai.OpenAI()
+ generation_name = "test_response_api_streaming" + create_uuid()[:8]
+
+ response = client.responses.create(
+ name=generation_name,
+ model="gpt-4o",
+ instructions="You are a helpful assistant.",
+ input="Hello!",
+ stream=True,
+ )
+
+ for _ in response:
+ continue
+
+ openai.flush_langfuse()
+
+ generation = get_api().observations.get_many(
+ name=generation_name, type="GENERATION"
+ )
+
+ assert len(generation.data) != 0
+ generationData = generation.data[0]
+ assert generationData.name == generation_name
+ assert generation.data[0].input == "Hello!"
+ assert generationData.type == "GENERATION"
+ assert "gpt-4o" in generationData.model
+ assert generationData.start_time is not None
+ assert generationData.end_time is not None
+ assert generationData.start_time < generationData.end_time
+ assert generationData.usage.input is not None
+ assert generationData.usage.output is not None
+ assert generationData.usage.total is not None
+ assert generationData.output is not None
+ assert generationData.metadata is not None
+ assert generationData.metadata["instructions"] == "You are a helpful assistant."
+
+
+def test_response_api_functions():
+ client = openai.OpenAI()
+ generation_name = "test_response_api_functions" + create_uuid()[:8]
+
+ tools = [
+ {
+ "type": "function",
+ "name": "get_current_weather",
+ "description": "Get the current weather in a given location",
+ "parameters": {
+ "type": "object",
+ "properties": {
+ "location": {
+ "type": "string",
+ "description": "The city and state, e.g. San Francisco, CA",
+ },
+ "unit": {"type": "string", "enum": ["celsius", "fahrenheit"]},
+ },
+ "required": ["location", "unit"],
+ },
+ }
+ ]
+
+ client.responses.create(
+ name=generation_name,
+ model="gpt-4o",
+ tools=tools,
+ input="What is the weather like in Boston today?",
+ tool_choice="auto",
+ )
+
+ openai.flush_langfuse()
+
+ generation = get_api().observations.get_many(
+ name=generation_name, type="GENERATION"
+ )
+
+ assert len(generation.data) != 0
+ generationData = generation.data[0]
+ assert generationData.name == generation_name
+ assert generation.data[0].input == "What is the weather like in Boston today?"
+ assert generationData.type == "GENERATION"
+ assert "gpt-4o" in generationData.model
+ assert generationData.start_time is not None
+ assert generationData.end_time is not None
+ assert generationData.start_time < generationData.end_time
+ assert generationData.usage.input is not None
+ assert generationData.usage.output is not None
+ assert generationData.usage.total is not None
+ assert generationData.output is not None
+ assert generationData.metadata is not None
+
+
+def test_response_api_reasoning():
+ client = openai.OpenAI()
+ generation_name = "test_response_api_reasoning" + create_uuid()[:8]
+
+ client.responses.create(
+ name=generation_name,
+ model="o3-mini",
+ input="How much wood would a woodchuck chuck?",
+ reasoning={"effort": "high"},
+ )
+ openai.flush_langfuse()
+
+ generation = get_api().observations.get_many(
+ name=generation_name, type="GENERATION"
+ )
+
+ assert len(generation.data) != 0
+ generationData = generation.data[0]
+ assert generationData.name == generation_name
+ assert generation.data[0].input == "How much wood would a woodchuck chuck?"
+ assert generationData.type == "GENERATION"
+ assert "o3-mini" in generationData.model
+ assert generationData.start_time is not None
+ assert generationData.end_time is not None
+ assert generationData.start_time < generationData.end_time
+ assert generationData.usage.input is not None
+ assert generationData.usage.output is not None
+ assert generationData.usage.total is not None
+ assert generationData.output is not None
+ assert generationData.metadata is not None