Skip to content

Commit 0d1b070

Browse files
committed
feat!: migrate api client to latest fern (#1480)
1 parent 0fd6338 commit 0d1b070

602 files changed

Lines changed: 44680 additions & 34893 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/ci.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ jobs:
7373
- "3.11"
7474
- "3.12"
7575
- "3.13"
76+
- "3.14"
7677

7778
name: Test on Python version ${{ matrix.python-version }}
7879
steps:

langfuse/_client/attributes.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,9 @@
1919
ObservationTypeSpanLike,
2020
)
2121
from langfuse._utils.serializer import EventSerializer
22+
from langfuse.api import MapValue
2223
from langfuse.model import PromptClient
23-
from langfuse.types import MapValue, SpanLevel
24+
from langfuse.types import SpanLevel
2425

2526

2627
class LangfuseOtelSpanAttributes:

langfuse/_client/client.py

Lines changed: 39 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -78,19 +78,19 @@
7878
from langfuse._utils import _get_timestamp
7979
from langfuse._utils.parse_error import handle_fern_exception
8080
from langfuse._utils.prompt_cache import PromptCache
81-
from langfuse.api.resources.commons.errors.error import Error
82-
from langfuse.api.resources.commons.errors.not_found_error import NotFoundError
83-
from langfuse.api.resources.commons.types import DatasetRunWithItems
84-
from langfuse.api.resources.datasets.types import (
85-
DeleteDatasetRunResponse,
86-
PaginatedDatasetRuns,
87-
)
88-
from langfuse.api.resources.ingestion.types.score_body import ScoreBody
89-
from langfuse.api.resources.prompts.types import (
90-
CreatePromptRequest_Chat,
91-
CreatePromptRequest_Text,
81+
from langfuse.api import (
82+
CreateChatPromptRequest,
83+
CreateChatPromptType,
84+
CreateTextPromptRequest,
85+
Dataset,
86+
DatasetItem,
87+
DatasetStatus,
88+
Error,
89+
MapValue,
90+
NotFoundError,
9291
Prompt_Chat,
9392
Prompt_Text,
93+
ScoreBody,
9494
)
9595
from langfuse.batch_evaluation import (
9696
BatchEvaluationResult,
@@ -117,13 +117,6 @@
117117
ChatMessageDict,
118118
ChatMessageWithPlaceholdersDict,
119119
ChatPromptClient,
120-
CreateDatasetItemRequest,
121-
CreateDatasetRequest,
122-
CreateDatasetRunItemRequest,
123-
Dataset,
124-
DatasetItem,
125-
DatasetStatus,
126-
MapValue,
127120
PromptClient,
128121
TextPromptClient,
129122
)
@@ -2062,7 +2055,7 @@ def create_score(
20622055
try:
20632056
new_body = ScoreBody(
20642057
id=score_id,
2065-
sessionId=session_id,
2058+
session_id=session_id,
20662059
datasetRunId=dataset_run_id,
20672060
traceId=trace_id,
20682061
observationId=observation_id,
@@ -2910,14 +2903,12 @@ async def _process_experiment_item(
29102903
# creates multiple event loops across different threads
29112904
dataset_run_item = await asyncio.to_thread(
29122905
self.api.dataset_run_items.create,
2913-
request=CreateDatasetRunItemRequest(
2914-
runName=experiment_run_name,
2915-
runDescription=experiment_description,
2916-
metadata=experiment_metadata,
2917-
datasetItemId=item.id, # type: ignore
2918-
traceId=trace_id,
2919-
observationId=span.id,
2920-
),
2906+
run_name=experiment_run_name,
2907+
run_description=experiment_description,
2908+
metadata=experiment_metadata,
2909+
dataset_item_id=item.id, # type: ignore
2910+
trace_id=trace_id,
2911+
observation_id=span.id,
29212912
)
29222913

29232914
dataset_run_id = dataset_run_item.dataset_run_id
@@ -3372,16 +3363,17 @@ def create_dataset(
33723363
Dataset: The created dataset as returned by the Langfuse API.
33733364
"""
33743365
try:
3375-
body = CreateDatasetRequest(
3366+
langfuse_logger.debug(f"Creating datasets {name}")
3367+
3368+
result = self.api.datasets.create(
33763369
name=name,
33773370
description=description,
33783371
metadata=metadata,
3379-
inputSchema=input_schema,
3380-
expectedOutputSchema=expected_output_schema,
3372+
input_schema=input_schema,
3373+
expected_output_schema=expected_output_schema,
33813374
)
3382-
langfuse_logger.debug(f"Creating datasets {body}")
33833375

3384-
return self.api.datasets.create(request=body)
3376+
return cast(Dataset, result)
33853377

33863378
except Error as e:
33873379
handle_fern_exception(e)
@@ -3432,18 +3424,20 @@ def create_dataset_item(
34323424
```
34333425
"""
34343426
try:
3435-
body = CreateDatasetItemRequest(
3436-
datasetName=dataset_name,
3427+
langfuse_logger.debug(f"Creating dataset item for dataset {dataset_name}")
3428+
3429+
result = self.api.dataset_items.create(
3430+
dataset_name=dataset_name,
34373431
input=input,
3438-
expectedOutput=expected_output,
3432+
expected_output=expected_output,
34393433
metadata=metadata,
3440-
sourceTraceId=source_trace_id,
3441-
sourceObservationId=source_observation_id,
3434+
source_trace_id=source_trace_id,
3435+
source_observation_id=source_observation_id,
34423436
status=status,
34433437
id=id,
34443438
)
3445-
langfuse_logger.debug(f"Creating dataset item {body}")
3446-
return self.api.dataset_items.create(request=body)
3439+
3440+
return cast(DatasetItem, result)
34473441
except Error as e:
34483442
handle_fern_exception(e)
34493443
raise e
@@ -3805,15 +3799,15 @@ def create_prompt(
38053799
raise ValueError(
38063800
"For 'chat' type, 'prompt' must be a list of chat messages with role and content attributes."
38073801
)
3808-
request: Union[CreatePromptRequest_Chat, CreatePromptRequest_Text] = (
3809-
CreatePromptRequest_Chat(
3802+
request: Union[CreateChatPromptRequest, CreateTextPromptRequest] = (
3803+
CreateChatPromptRequest(
38103804
name=name,
38113805
prompt=cast(Any, prompt),
38123806
labels=labels,
38133807
tags=tags,
38143808
config=config or {},
3815-
commitMessage=commit_message,
3816-
type="chat",
3809+
commit_message=commit_message,
3810+
type=CreateChatPromptType.CHAT,
38173811
)
38183812
)
38193813
server_prompt = self.api.prompts.create(request=request)
@@ -3826,14 +3820,13 @@ def create_prompt(
38263820
if not isinstance(prompt, str):
38273821
raise ValueError("For 'text' type, 'prompt' must be a string.")
38283822

3829-
request = CreatePromptRequest_Text(
3823+
request = CreateTextPromptRequest(
38303824
name=name,
38313825
prompt=prompt,
38323826
labels=labels,
38333827
tags=tags,
38343828
config=config or {},
3835-
commitMessage=commit_message,
3836-
type="text",
3829+
commit_message=commit_message,
38373830
)
38383831

38393832
server_prompt = self.api.prompts.create(request=request)

langfuse/_client/datasets.py

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,18 @@
44

55
from opentelemetry.util._decorator import _agnosticcontextmanager
66

7+
from langfuse.api import (
8+
Dataset,
9+
DatasetItem,
10+
DatasetStatus,
11+
)
712
from langfuse.batch_evaluation import CompositeEvaluatorFunction
813
from langfuse.experiment import (
914
EvaluatorFunction,
1015
ExperimentResult,
1116
RunEvaluatorFunction,
1217
TaskFunction,
1318
)
14-
from langfuse.model import (
15-
CreateDatasetRunItemRequest,
16-
Dataset,
17-
DatasetItem,
18-
DatasetStatus,
19-
)
2019

2120
from .span import LangfuseSpan
2221

@@ -131,13 +130,11 @@ def run(
131130
)
132131

133132
self.langfuse.api.dataset_run_items.create(
134-
request=CreateDatasetRunItemRequest(
135-
runName=run_name,
136-
datasetItemId=self.id,
137-
traceId=span.trace_id,
138-
metadata=run_metadata,
139-
runDescription=run_description,
140-
)
133+
run_name=run_name,
134+
dataset_item_id=self.id,
135+
trace_id=span.trace_id,
136+
metadata=run_metadata,
137+
run_description=run_description,
141138
)
142139

143140
yield span

langfuse/_client/resource_manager.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@
4242
from langfuse._utils.environment import get_common_release_envs
4343
from langfuse._utils.prompt_cache import PromptCache
4444
from langfuse._utils.request import LangfuseClient
45-
from langfuse.api.client import AsyncFernLangfuse, FernLangfuse
45+
from langfuse.api import AsyncLangfuseAPI, LangfuseAPI
4646
from langfuse.logger import langfuse_logger
4747
from langfuse.types import MaskFunction
4848

@@ -213,7 +213,7 @@ def _initialize_instance(
213213
client_headers = additional_headers if additional_headers else {}
214214
self.httpx_client = httpx.Client(timeout=timeout, headers=client_headers)
215215

216-
self.api = FernLangfuse(
216+
self.api = LangfuseAPI(
217217
base_url=base_url,
218218
username=self.public_key,
219219
password=secret_key,
@@ -223,7 +223,7 @@ def _initialize_instance(
223223
httpx_client=self.httpx_client,
224224
timeout=timeout,
225225
)
226-
self.async_api = AsyncFernLangfuse(
226+
self.async_api = AsyncLangfuseAPI(
227227
base_url=base_url,
228228
username=self.public_key,
229229
password=secret_key,

langfuse/_client/span.py

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,9 @@
5151
ObservationTypeSpanLike,
5252
get_observation_types_list,
5353
)
54+
from langfuse.api import MapValue, ScoreDataType
5455
from langfuse.logger import langfuse_logger
55-
from langfuse.types import MapValue, ScoreDataType, SpanLevel
56+
from langfuse.types import SpanLevel
5657

5758
# Factory mapping for observation classes
5859
# Note: "event" is handled separately due to special instantiation logic
@@ -273,7 +274,9 @@ def score(
273274
name: str,
274275
value: float,
275276
score_id: Optional[str] = None,
276-
data_type: Optional[Literal["NUMERIC", "BOOLEAN"]] = None,
277+
data_type: Optional[
278+
Literal[ScoreDataType.NUMERIC, ScoreDataType.BOOLEAN]
279+
] = None,
277280
comment: Optional[str] = None,
278281
config_id: Optional[str] = None,
279282
timestamp: Optional[datetime] = None,
@@ -287,7 +290,9 @@ def score(
287290
name: str,
288291
value: str,
289292
score_id: Optional[str] = None,
290-
data_type: Optional[Literal["CATEGORICAL"]] = "CATEGORICAL",
293+
data_type: Optional[
294+
Literal[ScoreDataType.CATEGORICAL]
295+
] = ScoreDataType.CATEGORICAL,
291296
comment: Optional[str] = None,
292297
config_id: Optional[str] = None,
293298
timestamp: Optional[datetime] = None,
@@ -356,7 +361,9 @@ def score_trace(
356361
name: str,
357362
value: float,
358363
score_id: Optional[str] = None,
359-
data_type: Optional[Literal["NUMERIC", "BOOLEAN"]] = None,
364+
data_type: Optional[
365+
Literal[ScoreDataType.NUMERIC, ScoreDataType.BOOLEAN]
366+
] = None,
360367
comment: Optional[str] = None,
361368
config_id: Optional[str] = None,
362369
timestamp: Optional[datetime] = None,
@@ -370,7 +377,9 @@ def score_trace(
370377
name: str,
371378
value: str,
372379
score_id: Optional[str] = None,
373-
data_type: Optional[Literal["CATEGORICAL"]] = "CATEGORICAL",
380+
data_type: Optional[
381+
Literal[ScoreDataType.CATEGORICAL]
382+
] = ScoreDataType.CATEGORICAL,
374383
comment: Optional[str] = None,
375384
config_id: Optional[str] = None,
376385
timestamp: Optional[datetime] = None,

langfuse/_task_manager/media_manager.py

Lines changed: 12 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,8 @@
1010

1111
from langfuse._client.environment_variables import LANGFUSE_MEDIA_UPLOAD_ENABLED
1212
from langfuse._utils import _get_timestamp
13-
from langfuse.api import GetMediaUploadUrlRequest, PatchMediaBody
14-
from langfuse.api.client import FernLangfuse
13+
from langfuse.api import LangfuseAPI, MediaContentType
1514
from langfuse.api.core import ApiError
16-
from langfuse.api.resources.media.types.media_content_type import MediaContentType
1715
from langfuse.media import LangfuseMedia
1816

1917
from .media_upload_queue import UploadMediaJob
@@ -28,7 +26,7 @@ class MediaManager:
2826
def __init__(
2927
self,
3028
*,
31-
api_client: FernLangfuse,
29+
api_client: LangfuseAPI,
3230
media_upload_queue: Queue,
3331
max_retries: Optional[int] = 3,
3432
):
@@ -219,14 +217,12 @@ def _process_upload_media_job(
219217
) -> None:
220218
upload_url_response = self._request_with_backoff(
221219
self._api_client.media.get_upload_url,
222-
request=GetMediaUploadUrlRequest(
223-
contentLength=data["content_length"],
224-
contentType=cast(MediaContentType, data["content_type"]),
225-
sha256Hash=data["content_sha256_hash"],
226-
field=data["field"],
227-
traceId=data["trace_id"],
228-
observationId=data["observation_id"],
229-
),
220+
content_length=data["content_length"],
221+
content_type=cast(MediaContentType, data["content_type"]),
222+
sha256hash=data["content_sha256_hash"],
223+
field=data["field"],
224+
trace_id=data["trace_id"],
225+
observation_id=data["observation_id"],
230226
)
231227

232228
upload_url = upload_url_response.upload_url
@@ -266,12 +262,10 @@ def _process_upload_media_job(
266262
self._request_with_backoff(
267263
self._api_client.media.patch,
268264
media_id=data["media_id"],
269-
request=PatchMediaBody(
270-
uploadedAt=_get_timestamp(),
271-
uploadHttpStatus=upload_response.status_code,
272-
uploadHttpError=upload_response.text,
273-
uploadTimeMs=upload_time_ms,
274-
),
265+
uploaded_at=_get_timestamp(),
266+
upload_http_status=upload_response.status_code,
267+
upload_http_error=upload_response.text,
268+
upload_time_ms=upload_time_ms,
275269
)
276270

277271
self._log.debug(

0 commit comments

Comments
 (0)