Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
1 change: 1 addition & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ jobs:
- "3.11"
- "3.12"
- "3.13"
- "3.14"

name: Test on Python version ${{ matrix.python-version }}
steps:
Expand Down
3 changes: 2 additions & 1 deletion langfuse/_client/attributes.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,9 @@
ObservationTypeSpanLike,
)
from langfuse._utils.serializer import EventSerializer
from langfuse.api import MapValue
from langfuse.model import PromptClient
from langfuse.types import MapValue, SpanLevel
from langfuse.types import SpanLevel


class LangfuseOtelSpanAttributes:
Expand Down
149 changes: 43 additions & 106 deletions langfuse/_client/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
ObservationTypeSpanLike,
get_observation_types_list,
)
from langfuse._client.datasets import DatasetClient, DatasetItemClient
from langfuse._client.datasets import DatasetClient
from langfuse._client.environment_variables import (
LANGFUSE_BASE_URL,
LANGFUSE_DEBUG,
Expand Down Expand Up @@ -78,14 +78,19 @@
from langfuse._utils import _get_timestamp
from langfuse._utils.parse_error import handle_fern_exception
from langfuse._utils.prompt_cache import PromptCache
from langfuse.api.resources.commons.errors.error import Error
from langfuse.api.resources.commons.errors.not_found_error import NotFoundError
from langfuse.api.resources.ingestion.types.score_body import ScoreBody
from langfuse.api.resources.prompts.types import (
CreatePromptRequest_Chat,
CreatePromptRequest_Text,
from langfuse.api import (
CreateChatPromptRequest,
CreateChatPromptType,
CreateTextPromptRequest,
Dataset,
DatasetItem,
DatasetStatus,
Error,
MapValue,
NotFoundError,
Prompt_Chat,
Prompt_Text,
ScoreBody,
)
from langfuse.batch_evaluation import (
BatchEvaluationResult,
Expand All @@ -112,13 +117,6 @@
ChatMessageDict,
ChatMessageWithPlaceholdersDict,
ChatPromptClient,
CreateDatasetItemRequest,
CreateDatasetRequest,
CreateDatasetRunItemRequest,
Dataset,
DatasetItem,
DatasetStatus,
MapValue,
PromptClient,
TextPromptClient,
)
Expand Down Expand Up @@ -1635,67 +1633,6 @@ def update_current_span(
status_message=status_message,
)

def update_current_trace(
self,
*,
name: Optional[str] = None,
user_id: Optional[str] = None,
session_id: Optional[str] = None,
version: Optional[str] = None,
input: Optional[Any] = None,
output: Optional[Any] = None,
metadata: Optional[Any] = None,
tags: Optional[List[str]] = None,
public: Optional[bool] = None,
) -> None:
"""Update the current trace with additional information.

Args:
name: Updated name for the Langfuse trace
user_id: ID of the user who initiated the Langfuse trace
session_id: Session identifier for grouping related Langfuse traces
version: Version identifier for the application or service
input: Input data for the overall Langfuse trace
output: Output data from the overall Langfuse trace
metadata: Additional metadata to associate with the Langfuse trace
tags: List of tags to categorize the Langfuse trace
public: Whether the Langfuse trace should be publicly accessible

See Also:
:func:`langfuse.propagate_attributes`: Recommended replacement
"""
if not self._tracing_enabled:
langfuse_logger.debug(
"Operation skipped: update_current_trace - Tracing is disabled or client is in no-op mode."
)
return

current_otel_span = self._get_current_otel_span()

if current_otel_span is not None and current_otel_span.is_recording():
existing_observation_type = current_otel_span.attributes.get( # type: ignore[attr-defined]
LangfuseOtelSpanAttributes.OBSERVATION_TYPE, "span"
)
# We need to preserve the class to keep the correct observation type
span_class = self._get_span_class(existing_observation_type)
span = span_class(
otel_span=current_otel_span,
langfuse_client=self,
environment=self._environment,
)

span.update_trace(
name=name,
user_id=user_id,
session_id=session_id,
version=version,
input=input,
output=output,
metadata=metadata,
tags=tags,
public=public,
)

def create_event(
self,
*,
Expand Down Expand Up @@ -2057,7 +1994,7 @@ def create_score(
try:
new_body = ScoreBody(
id=score_id,
sessionId=session_id,
session_id=session_id,
datasetRunId=dataset_run_id,
traceId=trace_id,
observationId=observation_id,
Expand Down Expand Up @@ -2453,9 +2390,9 @@ def get_dataset(

page += 1

items = [DatasetItemClient(i, langfuse=self) for i in dataset_items]

return DatasetClient(dataset, items=items)
return DatasetClient(
dataset=dataset, items=dataset_items, langfuse_client=self
)

except Error as e:
handle_fern_exception(e)
Expand Down Expand Up @@ -2818,14 +2755,12 @@ async def _process_experiment_item(
# creates multiple event loops across different threads
dataset_run_item = await asyncio.to_thread(
self.api.dataset_run_items.create,
request=CreateDatasetRunItemRequest(
runName=experiment_run_name,
runDescription=experiment_description,
metadata=experiment_metadata,
datasetItemId=item.id, # type: ignore
traceId=trace_id,
observationId=span.id,
),
run_name=experiment_run_name,
run_description=experiment_description,
metadata=experiment_metadata,
dataset_item_id=item.id, # type: ignore
trace_id=trace_id,
observation_id=span.id,
)

dataset_run_id = dataset_run_item.dataset_run_id
Expand Down Expand Up @@ -3271,16 +3206,17 @@ def create_dataset(
Dataset: The created dataset as returned by the Langfuse API.
"""
try:
body = CreateDatasetRequest(
langfuse_logger.debug(f"Creating datasets {name}")

result = self.api.datasets.create(
name=name,
description=description,
metadata=metadata,
inputSchema=input_schema,
expectedOutputSchema=expected_output_schema,
input_schema=input_schema,
expected_output_schema=expected_output_schema,
)
langfuse_logger.debug(f"Creating datasets {body}")

return self.api.datasets.create(request=body)
return cast(Dataset, result)

except Error as e:
handle_fern_exception(e)
Expand Down Expand Up @@ -3331,18 +3267,20 @@ def create_dataset_item(
```
"""
try:
body = CreateDatasetItemRequest(
datasetName=dataset_name,
langfuse_logger.debug(f"Creating dataset item for dataset {dataset_name}")

result = self.api.dataset_items.create(
dataset_name=dataset_name,
input=input,
expectedOutput=expected_output,
expected_output=expected_output,
metadata=metadata,
sourceTraceId=source_trace_id,
sourceObservationId=source_observation_id,
source_trace_id=source_trace_id,
source_observation_id=source_observation_id,
status=status,
id=id,
)
langfuse_logger.debug(f"Creating dataset item {body}")
return self.api.dataset_items.create(request=body)

return cast(DatasetItem, result)
except Error as e:
handle_fern_exception(e)
raise e
Expand Down Expand Up @@ -3704,15 +3642,15 @@ def create_prompt(
raise ValueError(
"For 'chat' type, 'prompt' must be a list of chat messages with role and content attributes."
)
request: Union[CreatePromptRequest_Chat, CreatePromptRequest_Text] = (
CreatePromptRequest_Chat(
request: Union[CreateChatPromptRequest, CreateTextPromptRequest] = (
CreateChatPromptRequest(
name=name,
prompt=cast(Any, prompt),
labels=labels,
tags=tags,
config=config or {},
commitMessage=commit_message,
type="chat",
commit_message=commit_message,
type=CreateChatPromptType.CHAT,
)
)
server_prompt = self.api.prompts.create(request=request)
Expand All @@ -3725,14 +3663,13 @@ def create_prompt(
if not isinstance(prompt, str):
raise ValueError("For 'text' type, 'prompt' must be a string.")

request = CreatePromptRequest_Text(
request = CreateTextPromptRequest(
name=name,
prompt=prompt,
labels=labels,
tags=tags,
config=config or {},
commitMessage=commit_message,
type="text",
commit_message=commit_message,
)

server_prompt = self.api.prompts.create(request=request)
Expand Down
Loading
Loading