From 743e0c5f1587a84fb9997dcfb4961435bd26f118 Mon Sep 17 00:00:00 2001 From: langfuse-bot Date: Wed, 10 Jun 2026 12:58:54 +0000 Subject: [PATCH] feat(api): update API spec from langfuse/langfuse e5c1a45 --- langfuse/api/__init__.py | 130 ++-- langfuse/api/client.py | 19 - langfuse/api/legacy/__init__.py | 45 +- langfuse/api/legacy/client.py | 19 + langfuse/api/legacy/scores_v2/__init__.py | 82 +++ langfuse/api/legacy/scores_v2/client.py | 432 +++++++++++ langfuse/api/legacy/scores_v2/raw_client.py | 668 ++++++++++++++++++ .../api/legacy/scores_v2/types/__init__.py | 82 +++ .../scores_v2/types/get_scores_response.py | 17 + .../types/get_scores_response_data.py | 6 +- .../types/get_scores_response_data_boolean.py | 2 +- .../get_scores_response_data_categorical.py | 2 +- .../get_scores_response_data_correction.py | 2 +- .../types/get_scores_response_data_numeric.py | 2 +- .../types/get_scores_response_data_text.py | 2 +- .../types/get_scores_response_trace_data.py | 4 +- langfuse/api/scores/__init__.py | 102 ++- langfuse/api/scores/client.py | 409 +++++------ langfuse/api/scores/raw_client.py | 538 +++++--------- langfuse/api/scores/types/__init__.py | 106 ++- .../types/base_score_v3.py | 4 +- .../types/boolean_score_v3.py | 0 .../types/categorical_score_v3.py | 0 .../types/correction_score_v3.py | 0 .../types/get_scores_meta.py} | 2 +- .../api/scores/types/get_scores_response.py | 8 +- .../types/numeric_score_v3.py | 0 .../types/score_subject.py} | 18 +- .../types/score_subject_experiment.py} | 2 +- .../types/score_subject_observation.py} | 2 +- .../types/score_subject_session.py} | 2 +- .../types/score_subject_trace.py} | 2 +- .../{scores_v3 => scores}/types/score_v3.py | 12 +- .../types/text_score_v3.py | 0 langfuse/api/scores_v3/__init__.py | 112 --- langfuse/api/scores_v3/client.py | 341 --------- langfuse/api/scores_v3/raw_client.py | 460 ------------ langfuse/api/scores_v3/types/__init__.py | 114 --- .../scores_v3/types/get_scores_v3response.py | 17 - 39 files changed, 1908 insertions(+), 1857 deletions(-) create mode 100644 langfuse/api/legacy/scores_v2/__init__.py create mode 100644 langfuse/api/legacy/scores_v2/client.py create mode 100644 langfuse/api/legacy/scores_v2/raw_client.py create mode 100644 langfuse/api/legacy/scores_v2/types/__init__.py create mode 100644 langfuse/api/legacy/scores_v2/types/get_scores_response.py rename langfuse/api/{scores => legacy/scores_v2}/types/get_scores_response_data.py (98%) rename langfuse/api/{scores => legacy/scores_v2}/types/get_scores_response_data_boolean.py (87%) rename langfuse/api/{scores => legacy/scores_v2}/types/get_scores_response_data_categorical.py (86%) rename langfuse/api/{scores => legacy/scores_v2}/types/get_scores_response_data_correction.py (86%) rename langfuse/api/{scores => legacy/scores_v2}/types/get_scores_response_data_numeric.py (87%) rename langfuse/api/{scores => legacy/scores_v2}/types/get_scores_response_data_text.py (88%) rename langfuse/api/{scores => legacy/scores_v2}/types/get_scores_response_trace_data.py (90%) rename langfuse/api/{scores_v3 => scores}/types/base_score_v3.py (95%) rename langfuse/api/{scores_v3 => scores}/types/boolean_score_v3.py (100%) rename langfuse/api/{scores_v3 => scores}/types/categorical_score_v3.py (100%) rename langfuse/api/{scores_v3 => scores}/types/correction_score_v3.py (100%) rename langfuse/api/{scores_v3/types/get_scores_v3meta.py => scores/types/get_scores_meta.py} (91%) rename langfuse/api/{scores_v3 => scores}/types/numeric_score_v3.py (100%) rename langfuse/api/{scores_v3/types/score_subject_v3.py => scores/types/score_subject.py} (82%) rename langfuse/api/{scores_v3/types/score_subject_experiment_v3.py => scores/types/score_subject_experiment.py} (87%) rename langfuse/api/{scores_v3/types/score_subject_observation_v3.py => scores/types/score_subject_observation.py} (92%) rename langfuse/api/{scores_v3/types/score_subject_session_v3.py => scores/types/score_subject_session.py} (87%) rename langfuse/api/{scores_v3/types/score_subject_trace_v3.py => scores/types/score_subject_trace.py} (87%) rename langfuse/api/{scores_v3 => scores}/types/score_v3.py (95%) rename langfuse/api/{scores_v3 => scores}/types/text_score_v3.py (100%) delete mode 100644 langfuse/api/scores_v3/__init__.py delete mode 100644 langfuse/api/scores_v3/client.py delete mode 100644 langfuse/api/scores_v3/raw_client.py delete mode 100644 langfuse/api/scores_v3/types/__init__.py delete mode 100644 langfuse/api/scores_v3/types/get_scores_v3response.py diff --git a/langfuse/api/__init__.py b/langfuse/api/__init__.py index 46985c0b9..290b4abb7 100644 --- a/langfuse/api/__init__.py +++ b/langfuse/api/__init__.py @@ -30,7 +30,6 @@ scim, score_configs, scores, - scores_v3, sessions, trace, unstable, @@ -284,37 +283,22 @@ UpdateScoreConfigRequest, ) from .scores import ( - GetScoresResponse, - GetScoresResponseData, - GetScoresResponseDataBoolean, - GetScoresResponseDataCategorical, - GetScoresResponseDataCorrection, - GetScoresResponseDataNumeric, - GetScoresResponseDataText, - GetScoresResponseData_Boolean, - GetScoresResponseData_Categorical, - GetScoresResponseData_Correction, - GetScoresResponseData_Numeric, - GetScoresResponseData_Text, - GetScoresResponseTraceData, - ) - from .scores_v3 import ( BaseScoreV3, BooleanScoreV3, CategoricalScoreV3, CorrectionScoreV3, - GetScoresV3Meta, - GetScoresV3Response, + GetScoresMeta, + GetScoresResponse, NumericScoreV3, - ScoreSubjectExperimentV3, - ScoreSubjectObservationV3, - ScoreSubjectSessionV3, - ScoreSubjectTraceV3, - ScoreSubjectV3, - ScoreSubjectV3_Experiment, - ScoreSubjectV3_Observation, - ScoreSubjectV3_Session, - ScoreSubjectV3_Trace, + ScoreSubject, + ScoreSubjectExperiment, + ScoreSubjectObservation, + ScoreSubjectSession, + ScoreSubjectTrace, + ScoreSubject_Experiment, + ScoreSubject_Observation, + ScoreSubject_Session, + ScoreSubject_Trace, ScoreV3, ScoreV3_Boolean, ScoreV3_Categorical, @@ -342,7 +326,7 @@ "BasePrompt": ".prompts", "BaseScore": ".commons", "BaseScoreV1": ".commons", - "BaseScoreV3": ".scores_v3", + "BaseScoreV3": ".scores", "BlobStorageExportFieldGroup": ".blob_storage_integrations", "BlobStorageExportFrequency": ".blob_storage_integrations", "BlobStorageExportMode": ".blob_storage_integrations", @@ -356,11 +340,11 @@ "BlobStorageSyncStatus": ".blob_storage_integrations", "BooleanScore": ".commons", "BooleanScoreV1": ".commons", - "BooleanScoreV3": ".scores_v3", + "BooleanScoreV3": ".scores", "BulkConfig": ".scim", "CategoricalScore": ".commons", "CategoricalScoreV1": ".commons", - "CategoricalScoreV3": ".scores_v3", + "CategoricalScoreV3": ".scores", "ChatMessage": ".prompts", "ChatMessageType": ".prompts", "ChatMessageWithPlaceholders": ".prompts", @@ -369,7 +353,7 @@ "CommentObjectType": ".commons", "ConfigCategory": ".commons", "CorrectionScore": ".commons", - "CorrectionScoreV3": ".scores_v3", + "CorrectionScoreV3": ".scores", "CreateAnnotationQueueAssignmentResponse": ".annotation_queues", "CreateAnnotationQueueItemRequest": ".annotation_queues", "CreateAnnotationQueueRequest": ".annotation_queues", @@ -414,21 +398,8 @@ "GetMediaResponse": ".media", "GetMediaUploadUrlRequest": ".media", "GetMediaUploadUrlResponse": ".media", + "GetScoresMeta": ".scores", "GetScoresResponse": ".scores", - "GetScoresResponseData": ".scores", - "GetScoresResponseDataBoolean": ".scores", - "GetScoresResponseDataCategorical": ".scores", - "GetScoresResponseDataCorrection": ".scores", - "GetScoresResponseDataNumeric": ".scores", - "GetScoresResponseDataText": ".scores", - "GetScoresResponseData_Boolean": ".scores", - "GetScoresResponseData_Categorical": ".scores", - "GetScoresResponseData_Correction": ".scores", - "GetScoresResponseData_Numeric": ".scores", - "GetScoresResponseData_Text": ".scores", - "GetScoresResponseTraceData": ".scores", - "GetScoresV3Meta": ".scores_v3", - "GetScoresV3Response": ".scores_v3", "HealthResponse": ".health", "IngestionError": ".ingestion", "IngestionEvent": ".ingestion", @@ -463,7 +434,7 @@ "NotFoundError": ".commons", "NumericScore": ".commons", "NumericScoreV1": ".commons", - "NumericScoreV3": ".scores_v3", + "NumericScoreV3": ".scores", "Observation": ".commons", "ObservationBody": ".ingestion", "ObservationLevel": ".commons", @@ -533,26 +504,26 @@ "ScoreDataType": ".commons", "ScoreEvent": ".ingestion", "ScoreSource": ".commons", - "ScoreSubjectExperimentV3": ".scores_v3", - "ScoreSubjectObservationV3": ".scores_v3", - "ScoreSubjectSessionV3": ".scores_v3", - "ScoreSubjectTraceV3": ".scores_v3", - "ScoreSubjectV3": ".scores_v3", - "ScoreSubjectV3_Experiment": ".scores_v3", - "ScoreSubjectV3_Observation": ".scores_v3", - "ScoreSubjectV3_Session": ".scores_v3", - "ScoreSubjectV3_Trace": ".scores_v3", + "ScoreSubject": ".scores", + "ScoreSubjectExperiment": ".scores", + "ScoreSubjectObservation": ".scores", + "ScoreSubjectSession": ".scores", + "ScoreSubjectTrace": ".scores", + "ScoreSubject_Experiment": ".scores", + "ScoreSubject_Observation": ".scores", + "ScoreSubject_Session": ".scores", + "ScoreSubject_Trace": ".scores", "ScoreV1": ".commons", "ScoreV1_Boolean": ".commons", "ScoreV1_Categorical": ".commons", "ScoreV1_Numeric": ".commons", "ScoreV1_Text": ".commons", - "ScoreV3": ".scores_v3", - "ScoreV3_Boolean": ".scores_v3", - "ScoreV3_Categorical": ".scores_v3", - "ScoreV3_Correction": ".scores_v3", - "ScoreV3_Numeric": ".scores_v3", - "ScoreV3_Text": ".scores_v3", + "ScoreV3": ".scores", + "ScoreV3_Boolean": ".scores", + "ScoreV3_Categorical": ".scores", + "ScoreV3_Correction": ".scores", + "ScoreV3_Numeric": ".scores", + "ScoreV3_Text": ".scores", "Score_Boolean": ".commons", "Score_Categorical": ".commons", "Score_Correction": ".commons", @@ -568,7 +539,7 @@ "TextPrompt": ".prompts", "TextScore": ".commons", "TextScoreV1": ".commons", - "TextScoreV3": ".scores_v3", + "TextScoreV3": ".scores", "Trace": ".commons", "TraceBody": ".ingestion", "TraceEvent": ".ingestion", @@ -611,7 +582,6 @@ "scim": ".scim", "score_configs": ".score_configs", "scores": ".scores", - "scores_v3": ".scores_v3", "sessions": ".sessions", "trace": ".trace", "unstable": ".unstable", @@ -735,21 +705,8 @@ def __dir__(): "GetMediaResponse", "GetMediaUploadUrlRequest", "GetMediaUploadUrlResponse", + "GetScoresMeta", "GetScoresResponse", - "GetScoresResponseData", - "GetScoresResponseDataBoolean", - "GetScoresResponseDataCategorical", - "GetScoresResponseDataCorrection", - "GetScoresResponseDataNumeric", - "GetScoresResponseDataText", - "GetScoresResponseData_Boolean", - "GetScoresResponseData_Categorical", - "GetScoresResponseData_Correction", - "GetScoresResponseData_Numeric", - "GetScoresResponseData_Text", - "GetScoresResponseTraceData", - "GetScoresV3Meta", - "GetScoresV3Response", "HealthResponse", "IngestionError", "IngestionEvent", @@ -854,15 +811,15 @@ def __dir__(): "ScoreDataType", "ScoreEvent", "ScoreSource", - "ScoreSubjectExperimentV3", - "ScoreSubjectObservationV3", - "ScoreSubjectSessionV3", - "ScoreSubjectTraceV3", - "ScoreSubjectV3", - "ScoreSubjectV3_Experiment", - "ScoreSubjectV3_Observation", - "ScoreSubjectV3_Session", - "ScoreSubjectV3_Trace", + "ScoreSubject", + "ScoreSubjectExperiment", + "ScoreSubjectObservation", + "ScoreSubjectSession", + "ScoreSubjectTrace", + "ScoreSubject_Experiment", + "ScoreSubject_Observation", + "ScoreSubject_Session", + "ScoreSubject_Trace", "ScoreV1", "ScoreV1_Boolean", "ScoreV1_Categorical", @@ -932,7 +889,6 @@ def __dir__(): "scim", "score_configs", "scores", - "scores_v3", "sessions", "trace", "unstable", diff --git a/langfuse/api/client.py b/langfuse/api/client.py index a72aede85..c0413704b 100644 --- a/langfuse/api/client.py +++ b/langfuse/api/client.py @@ -39,7 +39,6 @@ from .scim.client import AsyncScimClient, ScimClient from .score_configs.client import AsyncScoreConfigsClient, ScoreConfigsClient from .scores.client import AsyncScoresClient, ScoresClient - from .scores_v3.client import AsyncScoresV3Client, ScoresV3Client from .sessions.client import AsyncSessionsClient, SessionsClient from .trace.client import AsyncTraceClient, TraceClient from .unstable.client import AsyncUnstableClient, UnstableClient @@ -146,7 +145,6 @@ def __init__( self._prompts: typing.Optional[PromptsClient] = None self._scim: typing.Optional[ScimClient] = None self._score_configs: typing.Optional[ScoreConfigsClient] = None - self._scores_v3: typing.Optional[ScoresV3Client] = None self._scores: typing.Optional[ScoresClient] = None self._sessions: typing.Optional[SessionsClient] = None self._trace: typing.Optional[TraceClient] = None @@ -338,14 +336,6 @@ def score_configs(self): ) return self._score_configs - @property - def scores_v3(self): - if self._scores_v3 is None: - from .scores_v3.client import ScoresV3Client # noqa: E402 - - self._scores_v3 = ScoresV3Client(client_wrapper=self._client_wrapper) - return self._scores_v3 - @property def scores(self): if self._scores is None: @@ -480,7 +470,6 @@ def __init__( self._prompts: typing.Optional[AsyncPromptsClient] = None self._scim: typing.Optional[AsyncScimClient] = None self._score_configs: typing.Optional[AsyncScoreConfigsClient] = None - self._scores_v3: typing.Optional[AsyncScoresV3Client] = None self._scores: typing.Optional[AsyncScoresClient] = None self._sessions: typing.Optional[AsyncSessionsClient] = None self._trace: typing.Optional[AsyncTraceClient] = None @@ -676,14 +665,6 @@ def score_configs(self): ) return self._score_configs - @property - def scores_v3(self): - if self._scores_v3 is None: - from .scores_v3.client import AsyncScoresV3Client # noqa: E402 - - self._scores_v3 = AsyncScoresV3Client(client_wrapper=self._client_wrapper) - return self._scores_v3 - @property def scores(self): if self._scores is None: diff --git a/langfuse/api/legacy/__init__.py b/langfuse/api/legacy/__init__.py index 0a67d1c0c..493135b00 100644 --- a/langfuse/api/legacy/__init__.py +++ b/langfuse/api/legacy/__init__.py @@ -6,20 +6,49 @@ from importlib import import_module if typing.TYPE_CHECKING: - from . import metrics_v1, observations_v1, score_v1 + from . import metrics_v1, observations_v1, score_v1, scores_v2 from .metrics_v1 import MetricsResponse from .observations_v1 import Observations, ObservationsViews from .score_v1 import CreateScoreRequest, CreateScoreResponse, CreateScoreSource + from .scores_v2 import ( + GetScoresResponse, + GetScoresResponseData, + GetScoresResponseDataBoolean, + GetScoresResponseDataCategorical, + GetScoresResponseDataCorrection, + GetScoresResponseDataNumeric, + GetScoresResponseDataText, + GetScoresResponseData_Boolean, + GetScoresResponseData_Categorical, + GetScoresResponseData_Correction, + GetScoresResponseData_Numeric, + GetScoresResponseData_Text, + GetScoresResponseTraceData, + ) _dynamic_imports: typing.Dict[str, str] = { "CreateScoreRequest": ".score_v1", "CreateScoreResponse": ".score_v1", "CreateScoreSource": ".score_v1", + "GetScoresResponse": ".scores_v2", + "GetScoresResponseData": ".scores_v2", + "GetScoresResponseDataBoolean": ".scores_v2", + "GetScoresResponseDataCategorical": ".scores_v2", + "GetScoresResponseDataCorrection": ".scores_v2", + "GetScoresResponseDataNumeric": ".scores_v2", + "GetScoresResponseDataText": ".scores_v2", + "GetScoresResponseData_Boolean": ".scores_v2", + "GetScoresResponseData_Categorical": ".scores_v2", + "GetScoresResponseData_Correction": ".scores_v2", + "GetScoresResponseData_Numeric": ".scores_v2", + "GetScoresResponseData_Text": ".scores_v2", + "GetScoresResponseTraceData": ".scores_v2", "MetricsResponse": ".metrics_v1", "Observations": ".observations_v1", "ObservationsViews": ".observations_v1", "metrics_v1": ".metrics_v1", "observations_v1": ".observations_v1", "score_v1": ".score_v1", + "scores_v2": ".scores_v2", } @@ -54,10 +83,24 @@ def __dir__(): "CreateScoreRequest", "CreateScoreResponse", "CreateScoreSource", + "GetScoresResponse", + "GetScoresResponseData", + "GetScoresResponseDataBoolean", + "GetScoresResponseDataCategorical", + "GetScoresResponseDataCorrection", + "GetScoresResponseDataNumeric", + "GetScoresResponseDataText", + "GetScoresResponseData_Boolean", + "GetScoresResponseData_Categorical", + "GetScoresResponseData_Correction", + "GetScoresResponseData_Numeric", + "GetScoresResponseData_Text", + "GetScoresResponseTraceData", "MetricsResponse", "Observations", "ObservationsViews", "metrics_v1", "observations_v1", "score_v1", + "scores_v2", ] diff --git a/langfuse/api/legacy/client.py b/langfuse/api/legacy/client.py index 3886b9eac..cd92d954f 100644 --- a/langfuse/api/legacy/client.py +++ b/langfuse/api/legacy/client.py @@ -11,6 +11,7 @@ from .metrics_v1.client import AsyncMetricsV1Client, MetricsV1Client from .observations_v1.client import AsyncObservationsV1Client, ObservationsV1Client from .score_v1.client import AsyncScoreV1Client, ScoreV1Client + from .scores_v2.client import AsyncScoresV2Client, ScoresV2Client class LegacyClient: @@ -20,6 +21,7 @@ def __init__(self, *, client_wrapper: SyncClientWrapper): self._metrics_v1: typing.Optional[MetricsV1Client] = None self._observations_v1: typing.Optional[ObservationsV1Client] = None self._score_v1: typing.Optional[ScoreV1Client] = None + self._scores_v2: typing.Optional[ScoresV2Client] = None @property def with_raw_response(self) -> RawLegacyClient: @@ -58,6 +60,14 @@ def score_v1(self): self._score_v1 = ScoreV1Client(client_wrapper=self._client_wrapper) return self._score_v1 + @property + def scores_v2(self): + if self._scores_v2 is None: + from .scores_v2.client import ScoresV2Client # noqa: E402 + + self._scores_v2 = ScoresV2Client(client_wrapper=self._client_wrapper) + return self._scores_v2 + class AsyncLegacyClient: def __init__(self, *, client_wrapper: AsyncClientWrapper): @@ -66,6 +76,7 @@ def __init__(self, *, client_wrapper: AsyncClientWrapper): self._metrics_v1: typing.Optional[AsyncMetricsV1Client] = None self._observations_v1: typing.Optional[AsyncObservationsV1Client] = None self._score_v1: typing.Optional[AsyncScoreV1Client] = None + self._scores_v2: typing.Optional[AsyncScoresV2Client] = None @property def with_raw_response(self) -> AsyncRawLegacyClient: @@ -103,3 +114,11 @@ def score_v1(self): self._score_v1 = AsyncScoreV1Client(client_wrapper=self._client_wrapper) return self._score_v1 + + @property + def scores_v2(self): + if self._scores_v2 is None: + from .scores_v2.client import AsyncScoresV2Client # noqa: E402 + + self._scores_v2 = AsyncScoresV2Client(client_wrapper=self._client_wrapper) + return self._scores_v2 diff --git a/langfuse/api/legacy/scores_v2/__init__.py b/langfuse/api/legacy/scores_v2/__init__.py new file mode 100644 index 000000000..d57fb5371 --- /dev/null +++ b/langfuse/api/legacy/scores_v2/__init__.py @@ -0,0 +1,82 @@ +# This file was auto-generated by Fern from our API Definition. + +# isort: skip_file + +import typing +from importlib import import_module + +if typing.TYPE_CHECKING: + from .types import ( + GetScoresResponse, + GetScoresResponseData, + GetScoresResponseDataBoolean, + GetScoresResponseDataCategorical, + GetScoresResponseDataCorrection, + GetScoresResponseDataNumeric, + GetScoresResponseDataText, + GetScoresResponseData_Boolean, + GetScoresResponseData_Categorical, + GetScoresResponseData_Correction, + GetScoresResponseData_Numeric, + GetScoresResponseData_Text, + GetScoresResponseTraceData, + ) +_dynamic_imports: typing.Dict[str, str] = { + "GetScoresResponse": ".types", + "GetScoresResponseData": ".types", + "GetScoresResponseDataBoolean": ".types", + "GetScoresResponseDataCategorical": ".types", + "GetScoresResponseDataCorrection": ".types", + "GetScoresResponseDataNumeric": ".types", + "GetScoresResponseDataText": ".types", + "GetScoresResponseData_Boolean": ".types", + "GetScoresResponseData_Categorical": ".types", + "GetScoresResponseData_Correction": ".types", + "GetScoresResponseData_Numeric": ".types", + "GetScoresResponseData_Text": ".types", + "GetScoresResponseTraceData": ".types", +} + + +def __getattr__(attr_name: str) -> typing.Any: + module_name = _dynamic_imports.get(attr_name) + if module_name is None: + raise AttributeError( + f"No {attr_name} found in _dynamic_imports for module name -> {__name__}" + ) + try: + module = import_module(module_name, __package__) + if module_name == f".{attr_name}": + return module + else: + return getattr(module, attr_name) + except ImportError as e: + raise ImportError( + f"Failed to import {attr_name} from {module_name}: {e}" + ) from e + except AttributeError as e: + raise AttributeError( + f"Failed to get {attr_name} from {module_name}: {e}" + ) from e + + +def __dir__(): + lazy_attrs = list(_dynamic_imports.keys()) + return sorted(lazy_attrs) + + +__all__ = [ + "GetScoresResponse", + "GetScoresResponseData", + "GetScoresResponseDataBoolean", + "GetScoresResponseDataCategorical", + "GetScoresResponseDataCorrection", + "GetScoresResponseDataNumeric", + "GetScoresResponseDataText", + "GetScoresResponseData_Boolean", + "GetScoresResponseData_Categorical", + "GetScoresResponseData_Correction", + "GetScoresResponseData_Numeric", + "GetScoresResponseData_Text", + "GetScoresResponseTraceData", +] diff --git a/langfuse/api/legacy/scores_v2/client.py b/langfuse/api/legacy/scores_v2/client.py new file mode 100644 index 000000000..2ce6cba97 --- /dev/null +++ b/langfuse/api/legacy/scores_v2/client.py @@ -0,0 +1,432 @@ +# This file was auto-generated by Fern from our API Definition. + +import datetime as dt +import typing + +from ...commons.types.score import Score +from ...commons.types.score_data_type import ScoreDataType +from ...commons.types.score_source import ScoreSource +from ...core.client_wrapper import AsyncClientWrapper, SyncClientWrapper +from ...core.request_options import RequestOptions +from .raw_client import AsyncRawScoresV2Client, RawScoresV2Client +from .types.get_scores_response import GetScoresResponse + + +class ScoresV2Client: + def __init__(self, *, client_wrapper: SyncClientWrapper): + self._raw_client = RawScoresV2Client(client_wrapper=client_wrapper) + + @property + def with_raw_response(self) -> RawScoresV2Client: + """ + Retrieves a raw implementation of this client that returns raw responses. + + Returns + ------- + RawScoresV2Client + """ + return self._raw_client + + def get_many( + self, + *, + page: typing.Optional[int] = None, + limit: typing.Optional[int] = None, + user_id: typing.Optional[str] = None, + 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, + score_ids: typing.Optional[str] = None, + config_id: typing.Optional[str] = None, + session_id: typing.Optional[str] = None, + dataset_run_id: typing.Optional[str] = None, + trace_id: typing.Optional[str] = None, + observation_id: typing.Optional[str] = None, + queue_id: typing.Optional[str] = None, + data_type: typing.Optional[ScoreDataType] = None, + trace_tags: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None, + fields: typing.Optional[str] = None, + filter: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> GetScoresResponse: + """ + **Deprecated.** Use `GET /api/public/v3/scores` instead. This endpoint + is no longer available on Langfuse v4 and later. + + Get a list of scores (supports both trace and session scores) + + Parameters + ---------- + page : typing.Optional[int] + Page number, starts at 1. + + limit : typing.Optional[int] + Limit of items per page. Maximum 100. Defaults to 50. Requests with a limit greater than 100 return HTTP 400. If you encounter api issues due to too large page sizes, try to reduce the limit. + + user_id : typing.Optional[str] + Retrieve only scores with this userId associated to the trace. + + name : typing.Optional[str] + Retrieve only scores with this name. + + from_timestamp : typing.Optional[dt.datetime] + Optional filter to only include scores created on or after a certain datetime (ISO 8601) + + 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. + + operator : typing.Optional[str] + Retrieve only scores with value. + + value : typing.Optional[float] + Retrieve only scores with value. + + score_ids : typing.Optional[str] + Comma-separated list of score IDs to limit the results to. + + config_id : typing.Optional[str] + Retrieve only scores with a specific configId. + + session_id : typing.Optional[str] + Retrieve only scores with a specific sessionId. + + dataset_run_id : typing.Optional[str] + Retrieve only scores with a specific datasetRunId. + + trace_id : typing.Optional[str] + Retrieve only scores with a specific traceId. + + observation_id : typing.Optional[str] + Comma-separated list of observation IDs to filter scores by. + + queue_id : typing.Optional[str] + Retrieve only scores with a specific annotation queueId. + + data_type : typing.Optional[ScoreDataType] + Retrieve only scores with a specific dataType. + + trace_tags : typing.Optional[typing.Union[str, typing.Sequence[str]]] + Only scores linked to traces that include all of these tags will be returned. + + fields : typing.Optional[str] + Comma-separated list of field groups to include in the response. Available field groups: 'score' (core score fields), 'trace' (trace properties: userId, tags, environment, sessionId). If not specified, both 'score' and 'trace' are returned by default. Example: 'score' to exclude trace data, 'score,trace' to include both. Note: When filtering by trace properties (using userId or traceTags parameters), the 'trace' field group must be included, otherwise a 400 error will be returned. + + filter : typing.Optional[str] + A JSON stringified array of filter objects. Each object requires type, column, operator, and value. Supports filtering by score metadata using the stringObject type. Example: [{"type":"stringObject","column":"metadata","key":"user_id","operator":"=","value":"abc123"}]. Supported types: stringObject (metadata key-value filtering), string, number, datetime, stringOptions, arrayOptions. Supported operators for stringObject: =, contains, does not contain, starts with, ends with. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + GetScoresResponse + + Examples + -------- + from langfuse import LangfuseAPI + + client = LangfuseAPI( + 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.legacy.scores_v2.get_many() + """ + _response = self._raw_client.get_many( + page=page, + limit=limit, + user_id=user_id, + name=name, + from_timestamp=from_timestamp, + to_timestamp=to_timestamp, + environment=environment, + source=source, + operator=operator, + value=value, + score_ids=score_ids, + config_id=config_id, + session_id=session_id, + dataset_run_id=dataset_run_id, + trace_id=trace_id, + observation_id=observation_id, + queue_id=queue_id, + data_type=data_type, + trace_tags=trace_tags, + fields=fields, + filter=filter, + request_options=request_options, + ) + return _response.data + + def get_by_id( + self, score_id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> Score: + """ + **Deprecated.** Use `GET /api/public/v3/scores` with the `id` filter + instead. This endpoint is no longer available on Langfuse v4 and later. + + Get a score (supports both trace and session scores) + + Parameters + ---------- + score_id : str + The unique langfuse identifier of a score + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + Score + + Examples + -------- + from langfuse import LangfuseAPI + + client = LangfuseAPI( + 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.legacy.scores_v2.get_by_id( + score_id="scoreId", + ) + """ + _response = self._raw_client.get_by_id( + score_id, request_options=request_options + ) + return _response.data + + +class AsyncScoresV2Client: + def __init__(self, *, client_wrapper: AsyncClientWrapper): + self._raw_client = AsyncRawScoresV2Client(client_wrapper=client_wrapper) + + @property + def with_raw_response(self) -> AsyncRawScoresV2Client: + """ + Retrieves a raw implementation of this client that returns raw responses. + + Returns + ------- + AsyncRawScoresV2Client + """ + return self._raw_client + + async def get_many( + self, + *, + page: typing.Optional[int] = None, + limit: typing.Optional[int] = None, + user_id: typing.Optional[str] = None, + 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, + score_ids: typing.Optional[str] = None, + config_id: typing.Optional[str] = None, + session_id: typing.Optional[str] = None, + dataset_run_id: typing.Optional[str] = None, + trace_id: typing.Optional[str] = None, + observation_id: typing.Optional[str] = None, + queue_id: typing.Optional[str] = None, + data_type: typing.Optional[ScoreDataType] = None, + trace_tags: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None, + fields: typing.Optional[str] = None, + filter: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> GetScoresResponse: + """ + **Deprecated.** Use `GET /api/public/v3/scores` instead. This endpoint + is no longer available on Langfuse v4 and later. + + Get a list of scores (supports both trace and session scores) + + Parameters + ---------- + page : typing.Optional[int] + Page number, starts at 1. + + limit : typing.Optional[int] + Limit of items per page. Maximum 100. Defaults to 50. Requests with a limit greater than 100 return HTTP 400. If you encounter api issues due to too large page sizes, try to reduce the limit. + + user_id : typing.Optional[str] + Retrieve only scores with this userId associated to the trace. + + name : typing.Optional[str] + Retrieve only scores with this name. + + from_timestamp : typing.Optional[dt.datetime] + Optional filter to only include scores created on or after a certain datetime (ISO 8601) + + 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. + + operator : typing.Optional[str] + Retrieve only scores with value. + + value : typing.Optional[float] + Retrieve only scores with value. + + score_ids : typing.Optional[str] + Comma-separated list of score IDs to limit the results to. + + config_id : typing.Optional[str] + Retrieve only scores with a specific configId. + + session_id : typing.Optional[str] + Retrieve only scores with a specific sessionId. + + dataset_run_id : typing.Optional[str] + Retrieve only scores with a specific datasetRunId. + + trace_id : typing.Optional[str] + Retrieve only scores with a specific traceId. + + observation_id : typing.Optional[str] + Comma-separated list of observation IDs to filter scores by. + + queue_id : typing.Optional[str] + Retrieve only scores with a specific annotation queueId. + + data_type : typing.Optional[ScoreDataType] + Retrieve only scores with a specific dataType. + + trace_tags : typing.Optional[typing.Union[str, typing.Sequence[str]]] + Only scores linked to traces that include all of these tags will be returned. + + fields : typing.Optional[str] + Comma-separated list of field groups to include in the response. Available field groups: 'score' (core score fields), 'trace' (trace properties: userId, tags, environment, sessionId). If not specified, both 'score' and 'trace' are returned by default. Example: 'score' to exclude trace data, 'score,trace' to include both. Note: When filtering by trace properties (using userId or traceTags parameters), the 'trace' field group must be included, otherwise a 400 error will be returned. + + filter : typing.Optional[str] + A JSON stringified array of filter objects. Each object requires type, column, operator, and value. Supports filtering by score metadata using the stringObject type. Example: [{"type":"stringObject","column":"metadata","key":"user_id","operator":"=","value":"abc123"}]. Supported types: stringObject (metadata key-value filtering), string, number, datetime, stringOptions, arrayOptions. Supported operators for stringObject: =, contains, does not contain, starts with, ends with. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + GetScoresResponse + + Examples + -------- + import asyncio + + from langfuse import AsyncLangfuseAPI + + client = AsyncLangfuseAPI( + 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.legacy.scores_v2.get_many() + + + asyncio.run(main()) + """ + _response = await self._raw_client.get_many( + page=page, + limit=limit, + user_id=user_id, + name=name, + from_timestamp=from_timestamp, + to_timestamp=to_timestamp, + environment=environment, + source=source, + operator=operator, + value=value, + score_ids=score_ids, + config_id=config_id, + session_id=session_id, + dataset_run_id=dataset_run_id, + trace_id=trace_id, + observation_id=observation_id, + queue_id=queue_id, + data_type=data_type, + trace_tags=trace_tags, + fields=fields, + filter=filter, + request_options=request_options, + ) + return _response.data + + async def get_by_id( + self, score_id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> Score: + """ + **Deprecated.** Use `GET /api/public/v3/scores` with the `id` filter + instead. This endpoint is no longer available on Langfuse v4 and later. + + Get a score (supports both trace and session scores) + + Parameters + ---------- + score_id : str + The unique langfuse identifier of a score + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + Score + + Examples + -------- + import asyncio + + from langfuse import AsyncLangfuseAPI + + client = AsyncLangfuseAPI( + 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.legacy.scores_v2.get_by_id( + score_id="scoreId", + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.get_by_id( + score_id, request_options=request_options + ) + return _response.data diff --git a/langfuse/api/legacy/scores_v2/raw_client.py b/langfuse/api/legacy/scores_v2/raw_client.py new file mode 100644 index 000000000..1a203c795 --- /dev/null +++ b/langfuse/api/legacy/scores_v2/raw_client.py @@ -0,0 +1,668 @@ +# This file was auto-generated by Fern from our API Definition. + +import datetime as dt +import typing +from json.decoder import JSONDecodeError + +from ...commons.errors.access_denied_error import AccessDeniedError +from ...commons.errors.error import Error +from ...commons.errors.method_not_allowed_error import MethodNotAllowedError +from ...commons.errors.not_found_error import NotFoundError +from ...commons.errors.unauthorized_error import UnauthorizedError +from ...commons.types.score import Score +from ...commons.types.score_data_type import ScoreDataType +from ...commons.types.score_source import ScoreSource +from ...core.api_error import ApiError +from ...core.client_wrapper import AsyncClientWrapper, SyncClientWrapper +from ...core.datetime_utils import serialize_datetime +from ...core.http_response import AsyncHttpResponse, HttpResponse +from ...core.jsonable_encoder import jsonable_encoder +from ...core.pydantic_utilities import parse_obj_as +from ...core.request_options import RequestOptions +from .types.get_scores_response import GetScoresResponse + + +class RawScoresV2Client: + def __init__(self, *, client_wrapper: SyncClientWrapper): + self._client_wrapper = client_wrapper + + def get_many( + self, + *, + page: typing.Optional[int] = None, + limit: typing.Optional[int] = None, + user_id: typing.Optional[str] = None, + 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, + score_ids: typing.Optional[str] = None, + config_id: typing.Optional[str] = None, + session_id: typing.Optional[str] = None, + dataset_run_id: typing.Optional[str] = None, + trace_id: typing.Optional[str] = None, + observation_id: typing.Optional[str] = None, + queue_id: typing.Optional[str] = None, + data_type: typing.Optional[ScoreDataType] = None, + trace_tags: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None, + fields: typing.Optional[str] = None, + filter: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> HttpResponse[GetScoresResponse]: + """ + **Deprecated.** Use `GET /api/public/v3/scores` instead. This endpoint + is no longer available on Langfuse v4 and later. + + Get a list of scores (supports both trace and session scores) + + Parameters + ---------- + page : typing.Optional[int] + Page number, starts at 1. + + limit : typing.Optional[int] + Limit of items per page. Maximum 100. Defaults to 50. Requests with a limit greater than 100 return HTTP 400. If you encounter api issues due to too large page sizes, try to reduce the limit. + + user_id : typing.Optional[str] + Retrieve only scores with this userId associated to the trace. + + name : typing.Optional[str] + Retrieve only scores with this name. + + from_timestamp : typing.Optional[dt.datetime] + Optional filter to only include scores created on or after a certain datetime (ISO 8601) + + 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. + + operator : typing.Optional[str] + Retrieve only scores with value. + + value : typing.Optional[float] + Retrieve only scores with value. + + score_ids : typing.Optional[str] + Comma-separated list of score IDs to limit the results to. + + config_id : typing.Optional[str] + Retrieve only scores with a specific configId. + + session_id : typing.Optional[str] + Retrieve only scores with a specific sessionId. + + dataset_run_id : typing.Optional[str] + Retrieve only scores with a specific datasetRunId. + + trace_id : typing.Optional[str] + Retrieve only scores with a specific traceId. + + observation_id : typing.Optional[str] + Comma-separated list of observation IDs to filter scores by. + + queue_id : typing.Optional[str] + Retrieve only scores with a specific annotation queueId. + + data_type : typing.Optional[ScoreDataType] + Retrieve only scores with a specific dataType. + + trace_tags : typing.Optional[typing.Union[str, typing.Sequence[str]]] + Only scores linked to traces that include all of these tags will be returned. + + fields : typing.Optional[str] + Comma-separated list of field groups to include in the response. Available field groups: 'score' (core score fields), 'trace' (trace properties: userId, tags, environment, sessionId). If not specified, both 'score' and 'trace' are returned by default. Example: 'score' to exclude trace data, 'score,trace' to include both. Note: When filtering by trace properties (using userId or traceTags parameters), the 'trace' field group must be included, otherwise a 400 error will be returned. + + filter : typing.Optional[str] + A JSON stringified array of filter objects. Each object requires type, column, operator, and value. Supports filtering by score metadata using the stringObject type. Example: [{"type":"stringObject","column":"metadata","key":"user_id","operator":"=","value":"abc123"}]. Supported types: stringObject (metadata key-value filtering), string, number, datetime, stringOptions, arrayOptions. Supported operators for stringObject: =, contains, does not contain, starts with, ends with. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[GetScoresResponse] + """ + _response = self._client_wrapper.httpx_client.request( + "api/public/v2/scores", + method="GET", + params={ + "page": page, + "limit": limit, + "userId": user_id, + "name": name, + "fromTimestamp": serialize_datetime(from_timestamp) + if from_timestamp is not None + else None, + "toTimestamp": serialize_datetime(to_timestamp) + if to_timestamp is not None + else None, + "environment": environment, + "source": source, + "operator": operator, + "value": value, + "scoreIds": score_ids, + "configId": config_id, + "sessionId": session_id, + "datasetRunId": dataset_run_id, + "traceId": trace_id, + "observationId": observation_id, + "queueId": queue_id, + "dataType": data_type, + "traceTags": trace_tags, + "fields": fields, + "filter": filter, + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + GetScoresResponse, + parse_obj_as( + type_=GetScoresResponse, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise Error( + headers=dict(_response.headers), + body=typing.cast( + typing.Any, + parse_obj_as( + type_=typing.Any, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + typing.Any, + parse_obj_as( + type_=typing.Any, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise AccessDeniedError( + headers=dict(_response.headers), + body=typing.cast( + typing.Any, + parse_obj_as( + type_=typing.Any, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 405: + raise MethodNotAllowedError( + headers=dict(_response.headers), + body=typing.cast( + typing.Any, + parse_obj_as( + type_=typing.Any, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + typing.Any, + parse_obj_as( + type_=typing.Any, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError( + status_code=_response.status_code, + headers=dict(_response.headers), + body=_response.text, + ) + raise ApiError( + status_code=_response.status_code, + headers=dict(_response.headers), + body=_response_json, + ) + + def get_by_id( + self, score_id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> HttpResponse[Score]: + """ + **Deprecated.** Use `GET /api/public/v3/scores` with the `id` filter + instead. This endpoint is no longer available on Langfuse v4 and later. + + Get a score (supports both trace and session scores) + + Parameters + ---------- + score_id : str + The unique langfuse identifier of a score + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[Score] + """ + _response = self._client_wrapper.httpx_client.request( + f"api/public/v2/scores/{jsonable_encoder(score_id)}", + method="GET", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + Score, + parse_obj_as( + type_=Score, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise Error( + headers=dict(_response.headers), + body=typing.cast( + typing.Any, + parse_obj_as( + type_=typing.Any, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + typing.Any, + parse_obj_as( + type_=typing.Any, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise AccessDeniedError( + headers=dict(_response.headers), + body=typing.cast( + typing.Any, + parse_obj_as( + type_=typing.Any, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 405: + raise MethodNotAllowedError( + headers=dict(_response.headers), + body=typing.cast( + typing.Any, + parse_obj_as( + type_=typing.Any, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + typing.Any, + parse_obj_as( + type_=typing.Any, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError( + status_code=_response.status_code, + headers=dict(_response.headers), + body=_response.text, + ) + raise ApiError( + status_code=_response.status_code, + headers=dict(_response.headers), + body=_response_json, + ) + + +class AsyncRawScoresV2Client: + def __init__(self, *, client_wrapper: AsyncClientWrapper): + self._client_wrapper = client_wrapper + + async def get_many( + self, + *, + page: typing.Optional[int] = None, + limit: typing.Optional[int] = None, + user_id: typing.Optional[str] = None, + 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, + score_ids: typing.Optional[str] = None, + config_id: typing.Optional[str] = None, + session_id: typing.Optional[str] = None, + dataset_run_id: typing.Optional[str] = None, + trace_id: typing.Optional[str] = None, + observation_id: typing.Optional[str] = None, + queue_id: typing.Optional[str] = None, + data_type: typing.Optional[ScoreDataType] = None, + trace_tags: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None, + fields: typing.Optional[str] = None, + filter: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncHttpResponse[GetScoresResponse]: + """ + **Deprecated.** Use `GET /api/public/v3/scores` instead. This endpoint + is no longer available on Langfuse v4 and later. + + Get a list of scores (supports both trace and session scores) + + Parameters + ---------- + page : typing.Optional[int] + Page number, starts at 1. + + limit : typing.Optional[int] + Limit of items per page. Maximum 100. Defaults to 50. Requests with a limit greater than 100 return HTTP 400. If you encounter api issues due to too large page sizes, try to reduce the limit. + + user_id : typing.Optional[str] + Retrieve only scores with this userId associated to the trace. + + name : typing.Optional[str] + Retrieve only scores with this name. + + from_timestamp : typing.Optional[dt.datetime] + Optional filter to only include scores created on or after a certain datetime (ISO 8601) + + 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. + + operator : typing.Optional[str] + Retrieve only scores with value. + + value : typing.Optional[float] + Retrieve only scores with value. + + score_ids : typing.Optional[str] + Comma-separated list of score IDs to limit the results to. + + config_id : typing.Optional[str] + Retrieve only scores with a specific configId. + + session_id : typing.Optional[str] + Retrieve only scores with a specific sessionId. + + dataset_run_id : typing.Optional[str] + Retrieve only scores with a specific datasetRunId. + + trace_id : typing.Optional[str] + Retrieve only scores with a specific traceId. + + observation_id : typing.Optional[str] + Comma-separated list of observation IDs to filter scores by. + + queue_id : typing.Optional[str] + Retrieve only scores with a specific annotation queueId. + + data_type : typing.Optional[ScoreDataType] + Retrieve only scores with a specific dataType. + + trace_tags : typing.Optional[typing.Union[str, typing.Sequence[str]]] + Only scores linked to traces that include all of these tags will be returned. + + fields : typing.Optional[str] + Comma-separated list of field groups to include in the response. Available field groups: 'score' (core score fields), 'trace' (trace properties: userId, tags, environment, sessionId). If not specified, both 'score' and 'trace' are returned by default. Example: 'score' to exclude trace data, 'score,trace' to include both. Note: When filtering by trace properties (using userId or traceTags parameters), the 'trace' field group must be included, otherwise a 400 error will be returned. + + filter : typing.Optional[str] + A JSON stringified array of filter objects. Each object requires type, column, operator, and value. Supports filtering by score metadata using the stringObject type. Example: [{"type":"stringObject","column":"metadata","key":"user_id","operator":"=","value":"abc123"}]. Supported types: stringObject (metadata key-value filtering), string, number, datetime, stringOptions, arrayOptions. Supported operators for stringObject: =, contains, does not contain, starts with, ends with. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[GetScoresResponse] + """ + _response = await self._client_wrapper.httpx_client.request( + "api/public/v2/scores", + method="GET", + params={ + "page": page, + "limit": limit, + "userId": user_id, + "name": name, + "fromTimestamp": serialize_datetime(from_timestamp) + if from_timestamp is not None + else None, + "toTimestamp": serialize_datetime(to_timestamp) + if to_timestamp is not None + else None, + "environment": environment, + "source": source, + "operator": operator, + "value": value, + "scoreIds": score_ids, + "configId": config_id, + "sessionId": session_id, + "datasetRunId": dataset_run_id, + "traceId": trace_id, + "observationId": observation_id, + "queueId": queue_id, + "dataType": data_type, + "traceTags": trace_tags, + "fields": fields, + "filter": filter, + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + GetScoresResponse, + parse_obj_as( + type_=GetScoresResponse, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise Error( + headers=dict(_response.headers), + body=typing.cast( + typing.Any, + parse_obj_as( + type_=typing.Any, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + typing.Any, + parse_obj_as( + type_=typing.Any, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise AccessDeniedError( + headers=dict(_response.headers), + body=typing.cast( + typing.Any, + parse_obj_as( + type_=typing.Any, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 405: + raise MethodNotAllowedError( + headers=dict(_response.headers), + body=typing.cast( + typing.Any, + parse_obj_as( + type_=typing.Any, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + typing.Any, + parse_obj_as( + type_=typing.Any, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError( + status_code=_response.status_code, + headers=dict(_response.headers), + body=_response.text, + ) + raise ApiError( + status_code=_response.status_code, + headers=dict(_response.headers), + body=_response_json, + ) + + async def get_by_id( + self, score_id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> AsyncHttpResponse[Score]: + """ + **Deprecated.** Use `GET /api/public/v3/scores` with the `id` filter + instead. This endpoint is no longer available on Langfuse v4 and later. + + Get a score (supports both trace and session scores) + + Parameters + ---------- + score_id : str + The unique langfuse identifier of a score + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[Score] + """ + _response = await self._client_wrapper.httpx_client.request( + f"api/public/v2/scores/{jsonable_encoder(score_id)}", + method="GET", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + Score, + parse_obj_as( + type_=Score, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise Error( + headers=dict(_response.headers), + body=typing.cast( + typing.Any, + parse_obj_as( + type_=typing.Any, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + typing.Any, + parse_obj_as( + type_=typing.Any, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise AccessDeniedError( + headers=dict(_response.headers), + body=typing.cast( + typing.Any, + parse_obj_as( + type_=typing.Any, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 405: + raise MethodNotAllowedError( + headers=dict(_response.headers), + body=typing.cast( + typing.Any, + parse_obj_as( + type_=typing.Any, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + typing.Any, + parse_obj_as( + type_=typing.Any, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError( + status_code=_response.status_code, + headers=dict(_response.headers), + body=_response.text, + ) + raise ApiError( + status_code=_response.status_code, + headers=dict(_response.headers), + body=_response_json, + ) diff --git a/langfuse/api/legacy/scores_v2/types/__init__.py b/langfuse/api/legacy/scores_v2/types/__init__.py new file mode 100644 index 000000000..5b82ed448 --- /dev/null +++ b/langfuse/api/legacy/scores_v2/types/__init__.py @@ -0,0 +1,82 @@ +# This file was auto-generated by Fern from our API Definition. + +# isort: skip_file + +import typing +from importlib import import_module + +if typing.TYPE_CHECKING: + from .get_scores_response import GetScoresResponse + from .get_scores_response_data import ( + GetScoresResponseData, + GetScoresResponseData_Boolean, + GetScoresResponseData_Categorical, + GetScoresResponseData_Correction, + GetScoresResponseData_Numeric, + GetScoresResponseData_Text, + ) + from .get_scores_response_data_boolean import GetScoresResponseDataBoolean + from .get_scores_response_data_categorical import GetScoresResponseDataCategorical + from .get_scores_response_data_correction import GetScoresResponseDataCorrection + from .get_scores_response_data_numeric import GetScoresResponseDataNumeric + from .get_scores_response_data_text import GetScoresResponseDataText + from .get_scores_response_trace_data import GetScoresResponseTraceData +_dynamic_imports: typing.Dict[str, str] = { + "GetScoresResponse": ".get_scores_response", + "GetScoresResponseData": ".get_scores_response_data", + "GetScoresResponseDataBoolean": ".get_scores_response_data_boolean", + "GetScoresResponseDataCategorical": ".get_scores_response_data_categorical", + "GetScoresResponseDataCorrection": ".get_scores_response_data_correction", + "GetScoresResponseDataNumeric": ".get_scores_response_data_numeric", + "GetScoresResponseDataText": ".get_scores_response_data_text", + "GetScoresResponseData_Boolean": ".get_scores_response_data", + "GetScoresResponseData_Categorical": ".get_scores_response_data", + "GetScoresResponseData_Correction": ".get_scores_response_data", + "GetScoresResponseData_Numeric": ".get_scores_response_data", + "GetScoresResponseData_Text": ".get_scores_response_data", + "GetScoresResponseTraceData": ".get_scores_response_trace_data", +} + + +def __getattr__(attr_name: str) -> typing.Any: + module_name = _dynamic_imports.get(attr_name) + if module_name is None: + raise AttributeError( + f"No {attr_name} found in _dynamic_imports for module name -> {__name__}" + ) + try: + module = import_module(module_name, __package__) + if module_name == f".{attr_name}": + return module + else: + return getattr(module, attr_name) + except ImportError as e: + raise ImportError( + f"Failed to import {attr_name} from {module_name}: {e}" + ) from e + except AttributeError as e: + raise AttributeError( + f"Failed to get {attr_name} from {module_name}: {e}" + ) from e + + +def __dir__(): + lazy_attrs = list(_dynamic_imports.keys()) + return sorted(lazy_attrs) + + +__all__ = [ + "GetScoresResponse", + "GetScoresResponseData", + "GetScoresResponseDataBoolean", + "GetScoresResponseDataCategorical", + "GetScoresResponseDataCorrection", + "GetScoresResponseDataNumeric", + "GetScoresResponseDataText", + "GetScoresResponseData_Boolean", + "GetScoresResponseData_Categorical", + "GetScoresResponseData_Correction", + "GetScoresResponseData_Numeric", + "GetScoresResponseData_Text", + "GetScoresResponseTraceData", +] diff --git a/langfuse/api/legacy/scores_v2/types/get_scores_response.py b/langfuse/api/legacy/scores_v2/types/get_scores_response.py new file mode 100644 index 000000000..84f6acd55 --- /dev/null +++ b/langfuse/api/legacy/scores_v2/types/get_scores_response.py @@ -0,0 +1,17 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ....core.pydantic_utilities import UniversalBaseModel +from ....utils.pagination.types.meta_response import MetaResponse +from .get_scores_response_data import GetScoresResponseData + + +class GetScoresResponse(UniversalBaseModel): + data: typing.List[GetScoresResponseData] + meta: MetaResponse + + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict( + extra="allow", frozen=True + ) diff --git a/langfuse/api/scores/types/get_scores_response_data.py b/langfuse/api/legacy/scores_v2/types/get_scores_response_data.py similarity index 98% rename from langfuse/api/scores/types/get_scores_response_data.py rename to langfuse/api/legacy/scores_v2/types/get_scores_response_data.py index f85cd471c..b7f517255 100644 --- a/langfuse/api/scores/types/get_scores_response_data.py +++ b/langfuse/api/legacy/scores_v2/types/get_scores_response_data.py @@ -7,9 +7,9 @@ import pydantic import typing_extensions -from ...commons.types.score_source import ScoreSource -from ...core.pydantic_utilities import UniversalBaseModel -from ...core.serialization import FieldMetadata +from ....commons.types.score_source import ScoreSource +from ....core.pydantic_utilities import UniversalBaseModel +from ....core.serialization import FieldMetadata from .get_scores_response_trace_data import GetScoresResponseTraceData diff --git a/langfuse/api/scores/types/get_scores_response_data_boolean.py b/langfuse/api/legacy/scores_v2/types/get_scores_response_data_boolean.py similarity index 87% rename from langfuse/api/scores/types/get_scores_response_data_boolean.py rename to langfuse/api/legacy/scores_v2/types/get_scores_response_data_boolean.py index eee645cd3..b5078706b 100644 --- a/langfuse/api/scores/types/get_scores_response_data_boolean.py +++ b/langfuse/api/legacy/scores_v2/types/get_scores_response_data_boolean.py @@ -3,7 +3,7 @@ import typing import pydantic -from ...commons.types.boolean_score import BooleanScore +from ....commons.types.boolean_score import BooleanScore from .get_scores_response_trace_data import GetScoresResponseTraceData diff --git a/langfuse/api/scores/types/get_scores_response_data_categorical.py b/langfuse/api/legacy/scores_v2/types/get_scores_response_data_categorical.py similarity index 86% rename from langfuse/api/scores/types/get_scores_response_data_categorical.py rename to langfuse/api/legacy/scores_v2/types/get_scores_response_data_categorical.py index edd4e46fa..fc7013aae 100644 --- a/langfuse/api/scores/types/get_scores_response_data_categorical.py +++ b/langfuse/api/legacy/scores_v2/types/get_scores_response_data_categorical.py @@ -3,7 +3,7 @@ import typing import pydantic -from ...commons.types.categorical_score import CategoricalScore +from ....commons.types.categorical_score import CategoricalScore from .get_scores_response_trace_data import GetScoresResponseTraceData diff --git a/langfuse/api/scores/types/get_scores_response_data_correction.py b/langfuse/api/legacy/scores_v2/types/get_scores_response_data_correction.py similarity index 86% rename from langfuse/api/scores/types/get_scores_response_data_correction.py rename to langfuse/api/legacy/scores_v2/types/get_scores_response_data_correction.py index df39c65ed..3985e7ae7 100644 --- a/langfuse/api/scores/types/get_scores_response_data_correction.py +++ b/langfuse/api/legacy/scores_v2/types/get_scores_response_data_correction.py @@ -3,7 +3,7 @@ import typing import pydantic -from ...commons.types.correction_score import CorrectionScore +from ....commons.types.correction_score import CorrectionScore from .get_scores_response_trace_data import GetScoresResponseTraceData diff --git a/langfuse/api/scores/types/get_scores_response_data_numeric.py b/langfuse/api/legacy/scores_v2/types/get_scores_response_data_numeric.py similarity index 87% rename from langfuse/api/scores/types/get_scores_response_data_numeric.py rename to langfuse/api/legacy/scores_v2/types/get_scores_response_data_numeric.py index 350be0e0c..078ceea87 100644 --- a/langfuse/api/scores/types/get_scores_response_data_numeric.py +++ b/langfuse/api/legacy/scores_v2/types/get_scores_response_data_numeric.py @@ -3,7 +3,7 @@ import typing import pydantic -from ...commons.types.numeric_score import NumericScore +from ....commons.types.numeric_score import NumericScore from .get_scores_response_trace_data import GetScoresResponseTraceData diff --git a/langfuse/api/scores/types/get_scores_response_data_text.py b/langfuse/api/legacy/scores_v2/types/get_scores_response_data_text.py similarity index 88% rename from langfuse/api/scores/types/get_scores_response_data_text.py rename to langfuse/api/legacy/scores_v2/types/get_scores_response_data_text.py index 4949afe74..6dc9c553e 100644 --- a/langfuse/api/scores/types/get_scores_response_data_text.py +++ b/langfuse/api/legacy/scores_v2/types/get_scores_response_data_text.py @@ -3,7 +3,7 @@ import typing import pydantic -from ...commons.types.text_score import TextScore +from ....commons.types.text_score import TextScore from .get_scores_response_trace_data import GetScoresResponseTraceData diff --git a/langfuse/api/scores/types/get_scores_response_trace_data.py b/langfuse/api/legacy/scores_v2/types/get_scores_response_trace_data.py similarity index 90% rename from langfuse/api/scores/types/get_scores_response_trace_data.py rename to langfuse/api/legacy/scores_v2/types/get_scores_response_trace_data.py index 306aaaf78..fa65391ac 100644 --- a/langfuse/api/scores/types/get_scores_response_trace_data.py +++ b/langfuse/api/legacy/scores_v2/types/get_scores_response_trace_data.py @@ -4,8 +4,8 @@ import pydantic import typing_extensions -from ...core.pydantic_utilities import UniversalBaseModel -from ...core.serialization import FieldMetadata +from ....core.pydantic_utilities import UniversalBaseModel +from ....core.serialization import FieldMetadata class GetScoresResponseTraceData(UniversalBaseModel): diff --git a/langfuse/api/scores/__init__.py b/langfuse/api/scores/__init__.py index d57fb5371..4c8af1309 100644 --- a/langfuse/api/scores/__init__.py +++ b/langfuse/api/scores/__init__.py @@ -7,34 +7,54 @@ if typing.TYPE_CHECKING: from .types import ( + BaseScoreV3, + BooleanScoreV3, + CategoricalScoreV3, + CorrectionScoreV3, + GetScoresMeta, GetScoresResponse, - GetScoresResponseData, - GetScoresResponseDataBoolean, - GetScoresResponseDataCategorical, - GetScoresResponseDataCorrection, - GetScoresResponseDataNumeric, - GetScoresResponseDataText, - GetScoresResponseData_Boolean, - GetScoresResponseData_Categorical, - GetScoresResponseData_Correction, - GetScoresResponseData_Numeric, - GetScoresResponseData_Text, - GetScoresResponseTraceData, + NumericScoreV3, + ScoreSubject, + ScoreSubjectExperiment, + ScoreSubjectObservation, + ScoreSubjectSession, + ScoreSubjectTrace, + ScoreSubject_Experiment, + ScoreSubject_Observation, + ScoreSubject_Session, + ScoreSubject_Trace, + ScoreV3, + ScoreV3_Boolean, + ScoreV3_Categorical, + ScoreV3_Correction, + ScoreV3_Numeric, + ScoreV3_Text, + TextScoreV3, ) _dynamic_imports: typing.Dict[str, str] = { + "BaseScoreV3": ".types", + "BooleanScoreV3": ".types", + "CategoricalScoreV3": ".types", + "CorrectionScoreV3": ".types", + "GetScoresMeta": ".types", "GetScoresResponse": ".types", - "GetScoresResponseData": ".types", - "GetScoresResponseDataBoolean": ".types", - "GetScoresResponseDataCategorical": ".types", - "GetScoresResponseDataCorrection": ".types", - "GetScoresResponseDataNumeric": ".types", - "GetScoresResponseDataText": ".types", - "GetScoresResponseData_Boolean": ".types", - "GetScoresResponseData_Categorical": ".types", - "GetScoresResponseData_Correction": ".types", - "GetScoresResponseData_Numeric": ".types", - "GetScoresResponseData_Text": ".types", - "GetScoresResponseTraceData": ".types", + "NumericScoreV3": ".types", + "ScoreSubject": ".types", + "ScoreSubjectExperiment": ".types", + "ScoreSubjectObservation": ".types", + "ScoreSubjectSession": ".types", + "ScoreSubjectTrace": ".types", + "ScoreSubject_Experiment": ".types", + "ScoreSubject_Observation": ".types", + "ScoreSubject_Session": ".types", + "ScoreSubject_Trace": ".types", + "ScoreV3": ".types", + "ScoreV3_Boolean": ".types", + "ScoreV3_Categorical": ".types", + "ScoreV3_Correction": ".types", + "ScoreV3_Numeric": ".types", + "ScoreV3_Text": ".types", + "TextScoreV3": ".types", } @@ -66,17 +86,27 @@ def __dir__(): __all__ = [ + "BaseScoreV3", + "BooleanScoreV3", + "CategoricalScoreV3", + "CorrectionScoreV3", + "GetScoresMeta", "GetScoresResponse", - "GetScoresResponseData", - "GetScoresResponseDataBoolean", - "GetScoresResponseDataCategorical", - "GetScoresResponseDataCorrection", - "GetScoresResponseDataNumeric", - "GetScoresResponseDataText", - "GetScoresResponseData_Boolean", - "GetScoresResponseData_Categorical", - "GetScoresResponseData_Correction", - "GetScoresResponseData_Numeric", - "GetScoresResponseData_Text", - "GetScoresResponseTraceData", + "NumericScoreV3", + "ScoreSubject", + "ScoreSubjectExperiment", + "ScoreSubjectObservation", + "ScoreSubjectSession", + "ScoreSubjectTrace", + "ScoreSubject_Experiment", + "ScoreSubject_Observation", + "ScoreSubject_Session", + "ScoreSubject_Trace", + "ScoreV3", + "ScoreV3_Boolean", + "ScoreV3_Categorical", + "ScoreV3_Correction", + "ScoreV3_Numeric", + "ScoreV3_Text", + "TextScoreV3", ] diff --git a/langfuse/api/scores/client.py b/langfuse/api/scores/client.py index 566530e21..4fca34a5b 100644 --- a/langfuse/api/scores/client.py +++ b/langfuse/api/scores/client.py @@ -3,9 +3,6 @@ import datetime as dt import typing -from ..commons.types.score import Score -from ..commons.types.score_data_type import ScoreDataType -from ..commons.types.score_source import ScoreSource from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper from ..core.request_options import RequestOptions from .raw_client import AsyncRawScoresClient, RawScoresClient @@ -30,96 +27,109 @@ def with_raw_response(self) -> RawScoresClient: def get_many( self, *, - page: typing.Optional[int] = None, limit: typing.Optional[int] = None, - user_id: typing.Optional[str] = None, + cursor: typing.Optional[str] = None, + fields: typing.Optional[str] = None, + id: typing.Optional[str] = None, 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, - score_ids: typing.Optional[str] = None, + source: typing.Optional[str] = None, + data_type: typing.Optional[str] = None, + environment: typing.Optional[str] = None, config_id: typing.Optional[str] = None, - session_id: typing.Optional[str] = None, - dataset_run_id: typing.Optional[str] = None, + queue_id: typing.Optional[str] = None, + author_user_id: typing.Optional[str] = None, + value: typing.Optional[str] = None, + value_min: typing.Optional[float] = None, + value_max: typing.Optional[float] = None, trace_id: typing.Optional[str] = None, + session_id: typing.Optional[str] = None, observation_id: typing.Optional[str] = None, - queue_id: typing.Optional[str] = None, - data_type: typing.Optional[ScoreDataType] = None, - trace_tags: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None, - fields: typing.Optional[str] = None, - filter: typing.Optional[str] = None, + experiment_id: typing.Optional[str] = None, + from_timestamp: typing.Optional[dt.datetime] = None, + to_timestamp: typing.Optional[dt.datetime] = None, request_options: typing.Optional[RequestOptions] = None, ) -> GetScoresResponse: """ - Get a list of scores (supports both trace and session scores) + Get a list of scores with a polymorphic `value` field (v3). + + The `value` field type depends on `dataType`: + - `NUMERIC` → number + - `BOOLEAN` → boolean + - `CATEGORICAL`, `TEXT`, `CORRECTION` → string + + The response always includes the core fields: id, projectId, name, + value, dataType, source, timestamp, environment, createdAt, updatedAt. + + Additional field groups can be requested via the `fields` parameter: + - `details` — adds comment, configId, metadata + - `subject` — adds the subject object describing the entity the score + is attached to: kind (trace, observation, session, or experiment), + id, and traceId for observation-level scores + - `annotation` — adds authorUserId, queueId + + Unknown group names return HTTP 400. Parameters ---------- - page : typing.Optional[int] - Page number, starts at 1. - limit : typing.Optional[int] - Limit of items per page. Maximum 100. Defaults to 50. Requests with a limit greater than 100 return HTTP 400. If you encounter api issues due to too large page sizes, try to reduce the limit. + Number of items per page. Maximum 100, default 50. Requests with a limit greater than 100 return HTTP 400. - user_id : typing.Optional[str] - Retrieve only scores with this userId associated to the trace. + cursor : typing.Optional[str] + URL-safe base64 (base64url) cursor for pagination. Use the cursor from the previous response to get the next page. Absent on the final page. - name : typing.Optional[str] - Retrieve only scores with this name. + fields : typing.Optional[str] + Comma-separated field groups to include in addition to the always-returned core fields. Allowed: details, subject, annotation — see the endpoint description for the fields each group adds. Unknown names return HTTP 400. - from_timestamp : typing.Optional[dt.datetime] - Optional filter to only include scores created on or after a certain datetime (ISO 8601) + id : typing.Optional[str] + Comma-separated list of score IDs to filter by (OR within, AND across filters). - to_timestamp : typing.Optional[dt.datetime] - Optional filter to only include scores created before a certain datetime (ISO 8601) + name : typing.Optional[str] + Comma-separated list of score names to filter by. - 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[str] + Comma-separated list of score sources to filter by (e.g. API, ANNOTATION, EVAL). Case-insensitive — `api` and `API` are equivalent. - source : typing.Optional[ScoreSource] - Retrieve only scores from a specific source. + data_type : typing.Optional[str] + Comma-separated list of data types to filter by (NUMERIC, BOOLEAN, CATEGORICAL, TEXT, CORRECTION). Case-insensitive — `numeric` and `NUMERIC` are equivalent. Must be a single value when used with value, valueMin, or valueMax; otherwise the request returns HTTP 400. Must be NUMERIC when used with valueMin or valueMax. - operator : typing.Optional[str] - Retrieve only scores with value. + environment : typing.Optional[str] + Comma-separated list of environments to filter by. - value : typing.Optional[float] - Retrieve only scores with value. + config_id : typing.Optional[str] + Comma-separated list of score config IDs to filter by. - score_ids : typing.Optional[str] - Comma-separated list of score IDs to limit the results to. + queue_id : typing.Optional[str] + Comma-separated list of annotation queue IDs to filter by. - config_id : typing.Optional[str] - Retrieve only scores with a specific configId. + author_user_id : typing.Optional[str] + Comma-separated list of author user IDs to filter by. - session_id : typing.Optional[str] - Retrieve only scores with a specific sessionId. + value : typing.Optional[str] + Comma-separated list of exact values to filter by. Requires a single dataType from NUMERIC, BOOLEAN, or CATEGORICAL; any other dataType, multiple dataTypes, or omitting dataType returns HTTP 400. For BOOLEAN, each value must be "true" or "false"; for NUMERIC, each value must be a finite number. Otherwise the request returns HTTP 400. - dataset_run_id : typing.Optional[str] - Retrieve only scores with a specific datasetRunId. + value_min : typing.Optional[float] + Inclusive lower bound on the numeric value. Requires dataType=NUMERIC as a single value; otherwise the request returns HTTP 400. - trace_id : typing.Optional[str] - Retrieve only scores with a specific traceId. + value_max : typing.Optional[float] + Inclusive upper bound on the numeric value. Requires dataType=NUMERIC as a single value; otherwise the request returns HTTP 400. - observation_id : typing.Optional[str] - Comma-separated list of observation IDs to filter scores by. + trace_id : typing.Optional[str] + Comma-separated list of trace IDs to filter by. Mutually exclusive with sessionId, experimentId. May be combined with observationId to scope the observation lookup to a specific trace. - queue_id : typing.Optional[str] - Retrieve only scores with a specific annotation queueId. + session_id : typing.Optional[str] + Comma-separated list of session IDs to filter by. Mutually exclusive with traceId, observationId, experimentId. - data_type : typing.Optional[ScoreDataType] - Retrieve only scores with a specific dataType. + observation_id : typing.Optional[str] + Comma-separated list of observation IDs to filter by. Requires traceId to be specified, because observation IDs are scoped to a trace. Mutually exclusive with sessionId, experimentId. Returns HTTP 400 when used without traceId. - trace_tags : typing.Optional[typing.Union[str, typing.Sequence[str]]] - Only scores linked to traces that include all of these tags will be returned. + experiment_id : typing.Optional[str] + Comma-separated list of dataset run IDs (experiment IDs) to filter by. Mutually exclusive with traceId, sessionId, observationId. - fields : typing.Optional[str] - Comma-separated list of field groups to include in the response. Available field groups: 'score' (core score fields), 'trace' (trace properties: userId, tags, environment, sessionId). If not specified, both 'score' and 'trace' are returned by default. Example: 'score' to exclude trace data, 'score,trace' to include both. Note: When filtering by trace properties (using userId or traceTags parameters), the 'trace' field group must be included, otherwise a 400 error will be returned. + from_timestamp : typing.Optional[dt.datetime] + Inclusive lower bound on the score timestamp. - filter : typing.Optional[str] - A JSON stringified array of filter objects. Each object requires type, column, operator, and value. Supports filtering by score metadata using the stringObject type. Example: [{"type":"stringObject","column":"metadata","key":"user_id","operator":"=","value":"abc123"}]. Supported types: stringObject (metadata key-value filtering), string, number, datetime, stringOptions, arrayOptions. Supported operators for stringObject: =, contains, does not contain, starts with, ends with. + to_timestamp : typing.Optional[dt.datetime] + Exclusive upper bound on the score timestamp. request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -143,70 +153,30 @@ def get_many( client.scores.get_many() """ _response = self._raw_client.get_many( - page=page, limit=limit, - user_id=user_id, + cursor=cursor, + fields=fields, + id=id, name=name, - from_timestamp=from_timestamp, - to_timestamp=to_timestamp, - environment=environment, source=source, - operator=operator, - value=value, - score_ids=score_ids, + data_type=data_type, + environment=environment, config_id=config_id, - session_id=session_id, - dataset_run_id=dataset_run_id, + queue_id=queue_id, + author_user_id=author_user_id, + value=value, + value_min=value_min, + value_max=value_max, trace_id=trace_id, + session_id=session_id, observation_id=observation_id, - queue_id=queue_id, - data_type=data_type, - trace_tags=trace_tags, - fields=fields, - filter=filter, + experiment_id=experiment_id, + from_timestamp=from_timestamp, + to_timestamp=to_timestamp, request_options=request_options, ) return _response.data - def get_by_id( - self, score_id: str, *, request_options: typing.Optional[RequestOptions] = None - ) -> Score: - """ - Get a score (supports both trace and session scores) - - Parameters - ---------- - score_id : str - The unique langfuse identifier of a score - - request_options : typing.Optional[RequestOptions] - Request-specific configuration. - - Returns - ------- - Score - - Examples - -------- - from langfuse import LangfuseAPI - - client = LangfuseAPI( - 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.scores.get_by_id( - score_id="scoreId", - ) - """ - _response = self._raw_client.get_by_id( - score_id, request_options=request_options - ) - return _response.data - class AsyncScoresClient: def __init__(self, *, client_wrapper: AsyncClientWrapper): @@ -226,96 +196,109 @@ def with_raw_response(self) -> AsyncRawScoresClient: async def get_many( self, *, - page: typing.Optional[int] = None, limit: typing.Optional[int] = None, - user_id: typing.Optional[str] = None, + cursor: typing.Optional[str] = None, + fields: typing.Optional[str] = None, + id: typing.Optional[str] = None, 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, - score_ids: typing.Optional[str] = None, + source: typing.Optional[str] = None, + data_type: typing.Optional[str] = None, + environment: typing.Optional[str] = None, config_id: typing.Optional[str] = None, - session_id: typing.Optional[str] = None, - dataset_run_id: typing.Optional[str] = None, + queue_id: typing.Optional[str] = None, + author_user_id: typing.Optional[str] = None, + value: typing.Optional[str] = None, + value_min: typing.Optional[float] = None, + value_max: typing.Optional[float] = None, trace_id: typing.Optional[str] = None, + session_id: typing.Optional[str] = None, observation_id: typing.Optional[str] = None, - queue_id: typing.Optional[str] = None, - data_type: typing.Optional[ScoreDataType] = None, - trace_tags: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None, - fields: typing.Optional[str] = None, - filter: typing.Optional[str] = None, + experiment_id: typing.Optional[str] = None, + from_timestamp: typing.Optional[dt.datetime] = None, + to_timestamp: typing.Optional[dt.datetime] = None, request_options: typing.Optional[RequestOptions] = None, ) -> GetScoresResponse: """ - Get a list of scores (supports both trace and session scores) + Get a list of scores with a polymorphic `value` field (v3). + + The `value` field type depends on `dataType`: + - `NUMERIC` → number + - `BOOLEAN` → boolean + - `CATEGORICAL`, `TEXT`, `CORRECTION` → string + + The response always includes the core fields: id, projectId, name, + value, dataType, source, timestamp, environment, createdAt, updatedAt. + + Additional field groups can be requested via the `fields` parameter: + - `details` — adds comment, configId, metadata + - `subject` — adds the subject object describing the entity the score + is attached to: kind (trace, observation, session, or experiment), + id, and traceId for observation-level scores + - `annotation` — adds authorUserId, queueId + + Unknown group names return HTTP 400. Parameters ---------- - page : typing.Optional[int] - Page number, starts at 1. - limit : typing.Optional[int] - Limit of items per page. Maximum 100. Defaults to 50. Requests with a limit greater than 100 return HTTP 400. If you encounter api issues due to too large page sizes, try to reduce the limit. + Number of items per page. Maximum 100, default 50. Requests with a limit greater than 100 return HTTP 400. - user_id : typing.Optional[str] - Retrieve only scores with this userId associated to the trace. + cursor : typing.Optional[str] + URL-safe base64 (base64url) cursor for pagination. Use the cursor from the previous response to get the next page. Absent on the final page. - name : typing.Optional[str] - Retrieve only scores with this name. + fields : typing.Optional[str] + Comma-separated field groups to include in addition to the always-returned core fields. Allowed: details, subject, annotation — see the endpoint description for the fields each group adds. Unknown names return HTTP 400. - from_timestamp : typing.Optional[dt.datetime] - Optional filter to only include scores created on or after a certain datetime (ISO 8601) + id : typing.Optional[str] + Comma-separated list of score IDs to filter by (OR within, AND across filters). - to_timestamp : typing.Optional[dt.datetime] - Optional filter to only include scores created before a certain datetime (ISO 8601) + name : typing.Optional[str] + Comma-separated list of score names to filter by. - 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[str] + Comma-separated list of score sources to filter by (e.g. API, ANNOTATION, EVAL). Case-insensitive — `api` and `API` are equivalent. - source : typing.Optional[ScoreSource] - Retrieve only scores from a specific source. + data_type : typing.Optional[str] + Comma-separated list of data types to filter by (NUMERIC, BOOLEAN, CATEGORICAL, TEXT, CORRECTION). Case-insensitive — `numeric` and `NUMERIC` are equivalent. Must be a single value when used with value, valueMin, or valueMax; otherwise the request returns HTTP 400. Must be NUMERIC when used with valueMin or valueMax. - operator : typing.Optional[str] - Retrieve only scores with value. + environment : typing.Optional[str] + Comma-separated list of environments to filter by. - value : typing.Optional[float] - Retrieve only scores with value. + config_id : typing.Optional[str] + Comma-separated list of score config IDs to filter by. - score_ids : typing.Optional[str] - Comma-separated list of score IDs to limit the results to. + queue_id : typing.Optional[str] + Comma-separated list of annotation queue IDs to filter by. - config_id : typing.Optional[str] - Retrieve only scores with a specific configId. + author_user_id : typing.Optional[str] + Comma-separated list of author user IDs to filter by. - session_id : typing.Optional[str] - Retrieve only scores with a specific sessionId. + value : typing.Optional[str] + Comma-separated list of exact values to filter by. Requires a single dataType from NUMERIC, BOOLEAN, or CATEGORICAL; any other dataType, multiple dataTypes, or omitting dataType returns HTTP 400. For BOOLEAN, each value must be "true" or "false"; for NUMERIC, each value must be a finite number. Otherwise the request returns HTTP 400. - dataset_run_id : typing.Optional[str] - Retrieve only scores with a specific datasetRunId. + value_min : typing.Optional[float] + Inclusive lower bound on the numeric value. Requires dataType=NUMERIC as a single value; otherwise the request returns HTTP 400. - trace_id : typing.Optional[str] - Retrieve only scores with a specific traceId. + value_max : typing.Optional[float] + Inclusive upper bound on the numeric value. Requires dataType=NUMERIC as a single value; otherwise the request returns HTTP 400. - observation_id : typing.Optional[str] - Comma-separated list of observation IDs to filter scores by. + trace_id : typing.Optional[str] + Comma-separated list of trace IDs to filter by. Mutually exclusive with sessionId, experimentId. May be combined with observationId to scope the observation lookup to a specific trace. - queue_id : typing.Optional[str] - Retrieve only scores with a specific annotation queueId. + session_id : typing.Optional[str] + Comma-separated list of session IDs to filter by. Mutually exclusive with traceId, observationId, experimentId. - data_type : typing.Optional[ScoreDataType] - Retrieve only scores with a specific dataType. + observation_id : typing.Optional[str] + Comma-separated list of observation IDs to filter by. Requires traceId to be specified, because observation IDs are scoped to a trace. Mutually exclusive with sessionId, experimentId. Returns HTTP 400 when used without traceId. - trace_tags : typing.Optional[typing.Union[str, typing.Sequence[str]]] - Only scores linked to traces that include all of these tags will be returned. + experiment_id : typing.Optional[str] + Comma-separated list of dataset run IDs (experiment IDs) to filter by. Mutually exclusive with traceId, sessionId, observationId. - fields : typing.Optional[str] - Comma-separated list of field groups to include in the response. Available field groups: 'score' (core score fields), 'trace' (trace properties: userId, tags, environment, sessionId). If not specified, both 'score' and 'trace' are returned by default. Example: 'score' to exclude trace data, 'score,trace' to include both. Note: When filtering by trace properties (using userId or traceTags parameters), the 'trace' field group must be included, otherwise a 400 error will be returned. + from_timestamp : typing.Optional[dt.datetime] + Inclusive lower bound on the score timestamp. - filter : typing.Optional[str] - A JSON stringified array of filter objects. Each object requires type, column, operator, and value. Supports filtering by score metadata using the stringObject type. Example: [{"type":"stringObject","column":"metadata","key":"user_id","operator":"=","value":"abc123"}]. Supported types: stringObject (metadata key-value filtering), string, number, datetime, stringOptions, arrayOptions. Supported operators for stringObject: =, contains, does not contain, starts with, ends with. + to_timestamp : typing.Optional[dt.datetime] + Exclusive upper bound on the score timestamp. request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -347,74 +330,26 @@ async def main() -> None: asyncio.run(main()) """ _response = await self._raw_client.get_many( - page=page, limit=limit, - user_id=user_id, + cursor=cursor, + fields=fields, + id=id, name=name, - from_timestamp=from_timestamp, - to_timestamp=to_timestamp, - environment=environment, source=source, - operator=operator, - value=value, - score_ids=score_ids, + data_type=data_type, + environment=environment, config_id=config_id, - session_id=session_id, - dataset_run_id=dataset_run_id, + queue_id=queue_id, + author_user_id=author_user_id, + value=value, + value_min=value_min, + value_max=value_max, trace_id=trace_id, + session_id=session_id, observation_id=observation_id, - queue_id=queue_id, - data_type=data_type, - trace_tags=trace_tags, - fields=fields, - filter=filter, + experiment_id=experiment_id, + from_timestamp=from_timestamp, + to_timestamp=to_timestamp, request_options=request_options, ) return _response.data - - async def get_by_id( - self, score_id: str, *, request_options: typing.Optional[RequestOptions] = None - ) -> Score: - """ - Get a score (supports both trace and session scores) - - Parameters - ---------- - score_id : str - The unique langfuse identifier of a score - - request_options : typing.Optional[RequestOptions] - Request-specific configuration. - - Returns - ------- - Score - - Examples - -------- - import asyncio - - from langfuse import AsyncLangfuseAPI - - client = AsyncLangfuseAPI( - 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.scores.get_by_id( - score_id="scoreId", - ) - - - asyncio.run(main()) - """ - _response = await self._raw_client.get_by_id( - score_id, request_options=request_options - ) - return _response.data diff --git a/langfuse/api/scores/raw_client.py b/langfuse/api/scores/raw_client.py index d1508545c..b30439bd5 100644 --- a/langfuse/api/scores/raw_client.py +++ b/langfuse/api/scores/raw_client.py @@ -9,14 +9,10 @@ from ..commons.errors.method_not_allowed_error import MethodNotAllowedError from ..commons.errors.not_found_error import NotFoundError from ..commons.errors.unauthorized_error import UnauthorizedError -from ..commons.types.score import Score -from ..commons.types.score_data_type import ScoreDataType -from ..commons.types.score_source import ScoreSource from ..core.api_error import ApiError from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper from ..core.datetime_utils import serialize_datetime from ..core.http_response import AsyncHttpResponse, HttpResponse -from ..core.jsonable_encoder import jsonable_encoder from ..core.pydantic_utilities import parse_obj_as from ..core.request_options import RequestOptions from .types.get_scores_response import GetScoresResponse @@ -29,96 +25,109 @@ def __init__(self, *, client_wrapper: SyncClientWrapper): def get_many( self, *, - page: typing.Optional[int] = None, limit: typing.Optional[int] = None, - user_id: typing.Optional[str] = None, + cursor: typing.Optional[str] = None, + fields: typing.Optional[str] = None, + id: typing.Optional[str] = None, 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, - score_ids: typing.Optional[str] = None, + source: typing.Optional[str] = None, + data_type: typing.Optional[str] = None, + environment: typing.Optional[str] = None, config_id: typing.Optional[str] = None, - session_id: typing.Optional[str] = None, - dataset_run_id: typing.Optional[str] = None, + queue_id: typing.Optional[str] = None, + author_user_id: typing.Optional[str] = None, + value: typing.Optional[str] = None, + value_min: typing.Optional[float] = None, + value_max: typing.Optional[float] = None, trace_id: typing.Optional[str] = None, + session_id: typing.Optional[str] = None, observation_id: typing.Optional[str] = None, - queue_id: typing.Optional[str] = None, - data_type: typing.Optional[ScoreDataType] = None, - trace_tags: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None, - fields: typing.Optional[str] = None, - filter: typing.Optional[str] = None, + experiment_id: typing.Optional[str] = None, + from_timestamp: typing.Optional[dt.datetime] = None, + to_timestamp: typing.Optional[dt.datetime] = None, request_options: typing.Optional[RequestOptions] = None, ) -> HttpResponse[GetScoresResponse]: """ - Get a list of scores (supports both trace and session scores) + Get a list of scores with a polymorphic `value` field (v3). + + The `value` field type depends on `dataType`: + - `NUMERIC` → number + - `BOOLEAN` → boolean + - `CATEGORICAL`, `TEXT`, `CORRECTION` → string + + The response always includes the core fields: id, projectId, name, + value, dataType, source, timestamp, environment, createdAt, updatedAt. + + Additional field groups can be requested via the `fields` parameter: + - `details` — adds comment, configId, metadata + - `subject` — adds the subject object describing the entity the score + is attached to: kind (trace, observation, session, or experiment), + id, and traceId for observation-level scores + - `annotation` — adds authorUserId, queueId + + Unknown group names return HTTP 400. Parameters ---------- - page : typing.Optional[int] - Page number, starts at 1. - limit : typing.Optional[int] - Limit of items per page. Maximum 100. Defaults to 50. Requests with a limit greater than 100 return HTTP 400. If you encounter api issues due to too large page sizes, try to reduce the limit. + Number of items per page. Maximum 100, default 50. Requests with a limit greater than 100 return HTTP 400. - user_id : typing.Optional[str] - Retrieve only scores with this userId associated to the trace. + cursor : typing.Optional[str] + URL-safe base64 (base64url) cursor for pagination. Use the cursor from the previous response to get the next page. Absent on the final page. - name : typing.Optional[str] - Retrieve only scores with this name. + fields : typing.Optional[str] + Comma-separated field groups to include in addition to the always-returned core fields. Allowed: details, subject, annotation — see the endpoint description for the fields each group adds. Unknown names return HTTP 400. - from_timestamp : typing.Optional[dt.datetime] - Optional filter to only include scores created on or after a certain datetime (ISO 8601) + id : typing.Optional[str] + Comma-separated list of score IDs to filter by (OR within, AND across filters). - to_timestamp : typing.Optional[dt.datetime] - Optional filter to only include scores created before a certain datetime (ISO 8601) + name : typing.Optional[str] + Comma-separated list of score names to filter by. - 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[str] + Comma-separated list of score sources to filter by (e.g. API, ANNOTATION, EVAL). Case-insensitive — `api` and `API` are equivalent. - source : typing.Optional[ScoreSource] - Retrieve only scores from a specific source. + data_type : typing.Optional[str] + Comma-separated list of data types to filter by (NUMERIC, BOOLEAN, CATEGORICAL, TEXT, CORRECTION). Case-insensitive — `numeric` and `NUMERIC` are equivalent. Must be a single value when used with value, valueMin, or valueMax; otherwise the request returns HTTP 400. Must be NUMERIC when used with valueMin or valueMax. - operator : typing.Optional[str] - Retrieve only scores with value. + environment : typing.Optional[str] + Comma-separated list of environments to filter by. - value : typing.Optional[float] - Retrieve only scores with value. + config_id : typing.Optional[str] + Comma-separated list of score config IDs to filter by. - score_ids : typing.Optional[str] - Comma-separated list of score IDs to limit the results to. + queue_id : typing.Optional[str] + Comma-separated list of annotation queue IDs to filter by. - config_id : typing.Optional[str] - Retrieve only scores with a specific configId. + author_user_id : typing.Optional[str] + Comma-separated list of author user IDs to filter by. - session_id : typing.Optional[str] - Retrieve only scores with a specific sessionId. + value : typing.Optional[str] + Comma-separated list of exact values to filter by. Requires a single dataType from NUMERIC, BOOLEAN, or CATEGORICAL; any other dataType, multiple dataTypes, or omitting dataType returns HTTP 400. For BOOLEAN, each value must be "true" or "false"; for NUMERIC, each value must be a finite number. Otherwise the request returns HTTP 400. - dataset_run_id : typing.Optional[str] - Retrieve only scores with a specific datasetRunId. + value_min : typing.Optional[float] + Inclusive lower bound on the numeric value. Requires dataType=NUMERIC as a single value; otherwise the request returns HTTP 400. - trace_id : typing.Optional[str] - Retrieve only scores with a specific traceId. + value_max : typing.Optional[float] + Inclusive upper bound on the numeric value. Requires dataType=NUMERIC as a single value; otherwise the request returns HTTP 400. - observation_id : typing.Optional[str] - Comma-separated list of observation IDs to filter scores by. + trace_id : typing.Optional[str] + Comma-separated list of trace IDs to filter by. Mutually exclusive with sessionId, experimentId. May be combined with observationId to scope the observation lookup to a specific trace. - queue_id : typing.Optional[str] - Retrieve only scores with a specific annotation queueId. + session_id : typing.Optional[str] + Comma-separated list of session IDs to filter by. Mutually exclusive with traceId, observationId, experimentId. - data_type : typing.Optional[ScoreDataType] - Retrieve only scores with a specific dataType. + observation_id : typing.Optional[str] + Comma-separated list of observation IDs to filter by. Requires traceId to be specified, because observation IDs are scoped to a trace. Mutually exclusive with sessionId, experimentId. Returns HTTP 400 when used without traceId. - trace_tags : typing.Optional[typing.Union[str, typing.Sequence[str]]] - Only scores linked to traces that include all of these tags will be returned. + experiment_id : typing.Optional[str] + Comma-separated list of dataset run IDs (experiment IDs) to filter by. Mutually exclusive with traceId, sessionId, observationId. - fields : typing.Optional[str] - Comma-separated list of field groups to include in the response. Available field groups: 'score' (core score fields), 'trace' (trace properties: userId, tags, environment, sessionId). If not specified, both 'score' and 'trace' are returned by default. Example: 'score' to exclude trace data, 'score,trace' to include both. Note: When filtering by trace properties (using userId or traceTags parameters), the 'trace' field group must be included, otherwise a 400 error will be returned. + from_timestamp : typing.Optional[dt.datetime] + Inclusive lower bound on the score timestamp. - filter : typing.Optional[str] - A JSON stringified array of filter objects. Each object requires type, column, operator, and value. Supports filtering by score metadata using the stringObject type. Example: [{"type":"stringObject","column":"metadata","key":"user_id","operator":"=","value":"abc123"}]. Supported types: stringObject (metadata key-value filtering), string, number, datetime, stringOptions, arrayOptions. Supported operators for stringObject: =, contains, does not contain, starts with, ends with. + to_timestamp : typing.Optional[dt.datetime] + Exclusive upper bound on the score timestamp. request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -128,34 +137,33 @@ def get_many( HttpResponse[GetScoresResponse] """ _response = self._client_wrapper.httpx_client.request( - "api/public/v2/scores", + "api/public/v3/scores", method="GET", params={ - "page": page, "limit": limit, - "userId": user_id, + "cursor": cursor, + "fields": fields, + "id": id, "name": name, + "source": source, + "dataType": data_type, + "environment": environment, + "configId": config_id, + "queueId": queue_id, + "authorUserId": author_user_id, + "value": value, + "valueMin": value_min, + "valueMax": value_max, + "traceId": trace_id, + "sessionId": session_id, + "observationId": observation_id, + "experimentId": experiment_id, "fromTimestamp": serialize_datetime(from_timestamp) if from_timestamp is not None else None, "toTimestamp": serialize_datetime(to_timestamp) if to_timestamp is not None else None, - "environment": environment, - "source": source, - "operator": operator, - "value": value, - "scoreIds": score_ids, - "configId": config_id, - "sessionId": session_id, - "datasetRunId": dataset_run_id, - "traceId": trace_id, - "observationId": observation_id, - "queueId": queue_id, - "dataType": data_type, - "traceTags": trace_tags, - "fields": fields, - "filter": filter, }, request_options=request_options, ) @@ -237,107 +245,6 @@ def get_many( body=_response_json, ) - def get_by_id( - self, score_id: str, *, request_options: typing.Optional[RequestOptions] = None - ) -> HttpResponse[Score]: - """ - Get a score (supports both trace and session scores) - - Parameters - ---------- - score_id : str - The unique langfuse identifier of a score - - request_options : typing.Optional[RequestOptions] - Request-specific configuration. - - Returns - ------- - HttpResponse[Score] - """ - _response = self._client_wrapper.httpx_client.request( - f"api/public/v2/scores/{jsonable_encoder(score_id)}", - method="GET", - request_options=request_options, - ) - try: - if 200 <= _response.status_code < 300: - _data = typing.cast( - Score, - parse_obj_as( - type_=Score, # type: ignore - object_=_response.json(), - ), - ) - return HttpResponse(response=_response, data=_data) - if _response.status_code == 400: - raise Error( - headers=dict(_response.headers), - body=typing.cast( - typing.Any, - parse_obj_as( - type_=typing.Any, # type: ignore - object_=_response.json(), - ), - ), - ) - if _response.status_code == 401: - raise UnauthorizedError( - headers=dict(_response.headers), - body=typing.cast( - typing.Any, - parse_obj_as( - type_=typing.Any, # type: ignore - object_=_response.json(), - ), - ), - ) - if _response.status_code == 403: - raise AccessDeniedError( - headers=dict(_response.headers), - body=typing.cast( - typing.Any, - parse_obj_as( - type_=typing.Any, # type: ignore - object_=_response.json(), - ), - ), - ) - if _response.status_code == 405: - raise MethodNotAllowedError( - headers=dict(_response.headers), - body=typing.cast( - typing.Any, - parse_obj_as( - type_=typing.Any, # type: ignore - object_=_response.json(), - ), - ), - ) - if _response.status_code == 404: - raise NotFoundError( - headers=dict(_response.headers), - body=typing.cast( - typing.Any, - parse_obj_as( - type_=typing.Any, # type: ignore - object_=_response.json(), - ), - ), - ) - _response_json = _response.json() - except JSONDecodeError: - raise ApiError( - status_code=_response.status_code, - headers=dict(_response.headers), - body=_response.text, - ) - raise ApiError( - status_code=_response.status_code, - headers=dict(_response.headers), - body=_response_json, - ) - class AsyncRawScoresClient: def __init__(self, *, client_wrapper: AsyncClientWrapper): @@ -346,96 +253,109 @@ def __init__(self, *, client_wrapper: AsyncClientWrapper): async def get_many( self, *, - page: typing.Optional[int] = None, limit: typing.Optional[int] = None, - user_id: typing.Optional[str] = None, + cursor: typing.Optional[str] = None, + fields: typing.Optional[str] = None, + id: typing.Optional[str] = None, 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, - score_ids: typing.Optional[str] = None, + source: typing.Optional[str] = None, + data_type: typing.Optional[str] = None, + environment: typing.Optional[str] = None, config_id: typing.Optional[str] = None, - session_id: typing.Optional[str] = None, - dataset_run_id: typing.Optional[str] = None, + queue_id: typing.Optional[str] = None, + author_user_id: typing.Optional[str] = None, + value: typing.Optional[str] = None, + value_min: typing.Optional[float] = None, + value_max: typing.Optional[float] = None, trace_id: typing.Optional[str] = None, + session_id: typing.Optional[str] = None, observation_id: typing.Optional[str] = None, - queue_id: typing.Optional[str] = None, - data_type: typing.Optional[ScoreDataType] = None, - trace_tags: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None, - fields: typing.Optional[str] = None, - filter: typing.Optional[str] = None, + experiment_id: typing.Optional[str] = None, + from_timestamp: typing.Optional[dt.datetime] = None, + to_timestamp: typing.Optional[dt.datetime] = None, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncHttpResponse[GetScoresResponse]: """ - Get a list of scores (supports both trace and session scores) + Get a list of scores with a polymorphic `value` field (v3). + + The `value` field type depends on `dataType`: + - `NUMERIC` → number + - `BOOLEAN` → boolean + - `CATEGORICAL`, `TEXT`, `CORRECTION` → string + + The response always includes the core fields: id, projectId, name, + value, dataType, source, timestamp, environment, createdAt, updatedAt. + + Additional field groups can be requested via the `fields` parameter: + - `details` — adds comment, configId, metadata + - `subject` — adds the subject object describing the entity the score + is attached to: kind (trace, observation, session, or experiment), + id, and traceId for observation-level scores + - `annotation` — adds authorUserId, queueId + + Unknown group names return HTTP 400. Parameters ---------- - page : typing.Optional[int] - Page number, starts at 1. - limit : typing.Optional[int] - Limit of items per page. Maximum 100. Defaults to 50. Requests with a limit greater than 100 return HTTP 400. If you encounter api issues due to too large page sizes, try to reduce the limit. + Number of items per page. Maximum 100, default 50. Requests with a limit greater than 100 return HTTP 400. - user_id : typing.Optional[str] - Retrieve only scores with this userId associated to the trace. + cursor : typing.Optional[str] + URL-safe base64 (base64url) cursor for pagination. Use the cursor from the previous response to get the next page. Absent on the final page. - name : typing.Optional[str] - Retrieve only scores with this name. + fields : typing.Optional[str] + Comma-separated field groups to include in addition to the always-returned core fields. Allowed: details, subject, annotation — see the endpoint description for the fields each group adds. Unknown names return HTTP 400. - from_timestamp : typing.Optional[dt.datetime] - Optional filter to only include scores created on or after a certain datetime (ISO 8601) + id : typing.Optional[str] + Comma-separated list of score IDs to filter by (OR within, AND across filters). - to_timestamp : typing.Optional[dt.datetime] - Optional filter to only include scores created before a certain datetime (ISO 8601) + name : typing.Optional[str] + Comma-separated list of score names to filter by. - 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[str] + Comma-separated list of score sources to filter by (e.g. API, ANNOTATION, EVAL). Case-insensitive — `api` and `API` are equivalent. - source : typing.Optional[ScoreSource] - Retrieve only scores from a specific source. + data_type : typing.Optional[str] + Comma-separated list of data types to filter by (NUMERIC, BOOLEAN, CATEGORICAL, TEXT, CORRECTION). Case-insensitive — `numeric` and `NUMERIC` are equivalent. Must be a single value when used with value, valueMin, or valueMax; otherwise the request returns HTTP 400. Must be NUMERIC when used with valueMin or valueMax. - operator : typing.Optional[str] - Retrieve only scores with value. + environment : typing.Optional[str] + Comma-separated list of environments to filter by. - value : typing.Optional[float] - Retrieve only scores with value. + config_id : typing.Optional[str] + Comma-separated list of score config IDs to filter by. - score_ids : typing.Optional[str] - Comma-separated list of score IDs to limit the results to. + queue_id : typing.Optional[str] + Comma-separated list of annotation queue IDs to filter by. - config_id : typing.Optional[str] - Retrieve only scores with a specific configId. + author_user_id : typing.Optional[str] + Comma-separated list of author user IDs to filter by. - session_id : typing.Optional[str] - Retrieve only scores with a specific sessionId. + value : typing.Optional[str] + Comma-separated list of exact values to filter by. Requires a single dataType from NUMERIC, BOOLEAN, or CATEGORICAL; any other dataType, multiple dataTypes, or omitting dataType returns HTTP 400. For BOOLEAN, each value must be "true" or "false"; for NUMERIC, each value must be a finite number. Otherwise the request returns HTTP 400. - dataset_run_id : typing.Optional[str] - Retrieve only scores with a specific datasetRunId. + value_min : typing.Optional[float] + Inclusive lower bound on the numeric value. Requires dataType=NUMERIC as a single value; otherwise the request returns HTTP 400. - trace_id : typing.Optional[str] - Retrieve only scores with a specific traceId. + value_max : typing.Optional[float] + Inclusive upper bound on the numeric value. Requires dataType=NUMERIC as a single value; otherwise the request returns HTTP 400. - observation_id : typing.Optional[str] - Comma-separated list of observation IDs to filter scores by. + trace_id : typing.Optional[str] + Comma-separated list of trace IDs to filter by. Mutually exclusive with sessionId, experimentId. May be combined with observationId to scope the observation lookup to a specific trace. - queue_id : typing.Optional[str] - Retrieve only scores with a specific annotation queueId. + session_id : typing.Optional[str] + Comma-separated list of session IDs to filter by. Mutually exclusive with traceId, observationId, experimentId. - data_type : typing.Optional[ScoreDataType] - Retrieve only scores with a specific dataType. + observation_id : typing.Optional[str] + Comma-separated list of observation IDs to filter by. Requires traceId to be specified, because observation IDs are scoped to a trace. Mutually exclusive with sessionId, experimentId. Returns HTTP 400 when used without traceId. - trace_tags : typing.Optional[typing.Union[str, typing.Sequence[str]]] - Only scores linked to traces that include all of these tags will be returned. + experiment_id : typing.Optional[str] + Comma-separated list of dataset run IDs (experiment IDs) to filter by. Mutually exclusive with traceId, sessionId, observationId. - fields : typing.Optional[str] - Comma-separated list of field groups to include in the response. Available field groups: 'score' (core score fields), 'trace' (trace properties: userId, tags, environment, sessionId). If not specified, both 'score' and 'trace' are returned by default. Example: 'score' to exclude trace data, 'score,trace' to include both. Note: When filtering by trace properties (using userId or traceTags parameters), the 'trace' field group must be included, otherwise a 400 error will be returned. + from_timestamp : typing.Optional[dt.datetime] + Inclusive lower bound on the score timestamp. - filter : typing.Optional[str] - A JSON stringified array of filter objects. Each object requires type, column, operator, and value. Supports filtering by score metadata using the stringObject type. Example: [{"type":"stringObject","column":"metadata","key":"user_id","operator":"=","value":"abc123"}]. Supported types: stringObject (metadata key-value filtering), string, number, datetime, stringOptions, arrayOptions. Supported operators for stringObject: =, contains, does not contain, starts with, ends with. + to_timestamp : typing.Optional[dt.datetime] + Exclusive upper bound on the score timestamp. request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -445,34 +365,33 @@ async def get_many( AsyncHttpResponse[GetScoresResponse] """ _response = await self._client_wrapper.httpx_client.request( - "api/public/v2/scores", + "api/public/v3/scores", method="GET", params={ - "page": page, "limit": limit, - "userId": user_id, + "cursor": cursor, + "fields": fields, + "id": id, "name": name, + "source": source, + "dataType": data_type, + "environment": environment, + "configId": config_id, + "queueId": queue_id, + "authorUserId": author_user_id, + "value": value, + "valueMin": value_min, + "valueMax": value_max, + "traceId": trace_id, + "sessionId": session_id, + "observationId": observation_id, + "experimentId": experiment_id, "fromTimestamp": serialize_datetime(from_timestamp) if from_timestamp is not None else None, "toTimestamp": serialize_datetime(to_timestamp) if to_timestamp is not None else None, - "environment": environment, - "source": source, - "operator": operator, - "value": value, - "scoreIds": score_ids, - "configId": config_id, - "sessionId": session_id, - "datasetRunId": dataset_run_id, - "traceId": trace_id, - "observationId": observation_id, - "queueId": queue_id, - "dataType": data_type, - "traceTags": trace_tags, - "fields": fields, - "filter": filter, }, request_options=request_options, ) @@ -553,104 +472,3 @@ async def get_many( headers=dict(_response.headers), body=_response_json, ) - - async def get_by_id( - self, score_id: str, *, request_options: typing.Optional[RequestOptions] = None - ) -> AsyncHttpResponse[Score]: - """ - Get a score (supports both trace and session scores) - - Parameters - ---------- - score_id : str - The unique langfuse identifier of a score - - request_options : typing.Optional[RequestOptions] - Request-specific configuration. - - Returns - ------- - AsyncHttpResponse[Score] - """ - _response = await self._client_wrapper.httpx_client.request( - f"api/public/v2/scores/{jsonable_encoder(score_id)}", - method="GET", - request_options=request_options, - ) - try: - if 200 <= _response.status_code < 300: - _data = typing.cast( - Score, - parse_obj_as( - type_=Score, # type: ignore - object_=_response.json(), - ), - ) - return AsyncHttpResponse(response=_response, data=_data) - if _response.status_code == 400: - raise Error( - headers=dict(_response.headers), - body=typing.cast( - typing.Any, - parse_obj_as( - type_=typing.Any, # type: ignore - object_=_response.json(), - ), - ), - ) - if _response.status_code == 401: - raise UnauthorizedError( - headers=dict(_response.headers), - body=typing.cast( - typing.Any, - parse_obj_as( - type_=typing.Any, # type: ignore - object_=_response.json(), - ), - ), - ) - if _response.status_code == 403: - raise AccessDeniedError( - headers=dict(_response.headers), - body=typing.cast( - typing.Any, - parse_obj_as( - type_=typing.Any, # type: ignore - object_=_response.json(), - ), - ), - ) - if _response.status_code == 405: - raise MethodNotAllowedError( - headers=dict(_response.headers), - body=typing.cast( - typing.Any, - parse_obj_as( - type_=typing.Any, # type: ignore - object_=_response.json(), - ), - ), - ) - if _response.status_code == 404: - raise NotFoundError( - headers=dict(_response.headers), - body=typing.cast( - typing.Any, - parse_obj_as( - type_=typing.Any, # type: ignore - object_=_response.json(), - ), - ), - ) - _response_json = _response.json() - except JSONDecodeError: - raise ApiError( - status_code=_response.status_code, - headers=dict(_response.headers), - body=_response.text, - ) - raise ApiError( - status_code=_response.status_code, - headers=dict(_response.headers), - body=_response_json, - ) diff --git a/langfuse/api/scores/types/__init__.py b/langfuse/api/scores/types/__init__.py index 5b82ed448..552f09f48 100644 --- a/langfuse/api/scores/types/__init__.py +++ b/langfuse/api/scores/types/__init__.py @@ -6,35 +6,57 @@ from importlib import import_module if typing.TYPE_CHECKING: + from .base_score_v3 import BaseScoreV3 + from .boolean_score_v3 import BooleanScoreV3 + from .categorical_score_v3 import CategoricalScoreV3 + from .correction_score_v3 import CorrectionScoreV3 + from .get_scores_meta import GetScoresMeta from .get_scores_response import GetScoresResponse - from .get_scores_response_data import ( - GetScoresResponseData, - GetScoresResponseData_Boolean, - GetScoresResponseData_Categorical, - GetScoresResponseData_Correction, - GetScoresResponseData_Numeric, - GetScoresResponseData_Text, + from .numeric_score_v3 import NumericScoreV3 + from .score_subject import ( + ScoreSubject, + ScoreSubject_Experiment, + ScoreSubject_Observation, + ScoreSubject_Session, + ScoreSubject_Trace, ) - from .get_scores_response_data_boolean import GetScoresResponseDataBoolean - from .get_scores_response_data_categorical import GetScoresResponseDataCategorical - from .get_scores_response_data_correction import GetScoresResponseDataCorrection - from .get_scores_response_data_numeric import GetScoresResponseDataNumeric - from .get_scores_response_data_text import GetScoresResponseDataText - from .get_scores_response_trace_data import GetScoresResponseTraceData + from .score_subject_experiment import ScoreSubjectExperiment + from .score_subject_observation import ScoreSubjectObservation + from .score_subject_session import ScoreSubjectSession + from .score_subject_trace import ScoreSubjectTrace + from .score_v3 import ( + ScoreV3, + ScoreV3_Boolean, + ScoreV3_Categorical, + ScoreV3_Correction, + ScoreV3_Numeric, + ScoreV3_Text, + ) + from .text_score_v3 import TextScoreV3 _dynamic_imports: typing.Dict[str, str] = { + "BaseScoreV3": ".base_score_v3", + "BooleanScoreV3": ".boolean_score_v3", + "CategoricalScoreV3": ".categorical_score_v3", + "CorrectionScoreV3": ".correction_score_v3", + "GetScoresMeta": ".get_scores_meta", "GetScoresResponse": ".get_scores_response", - "GetScoresResponseData": ".get_scores_response_data", - "GetScoresResponseDataBoolean": ".get_scores_response_data_boolean", - "GetScoresResponseDataCategorical": ".get_scores_response_data_categorical", - "GetScoresResponseDataCorrection": ".get_scores_response_data_correction", - "GetScoresResponseDataNumeric": ".get_scores_response_data_numeric", - "GetScoresResponseDataText": ".get_scores_response_data_text", - "GetScoresResponseData_Boolean": ".get_scores_response_data", - "GetScoresResponseData_Categorical": ".get_scores_response_data", - "GetScoresResponseData_Correction": ".get_scores_response_data", - "GetScoresResponseData_Numeric": ".get_scores_response_data", - "GetScoresResponseData_Text": ".get_scores_response_data", - "GetScoresResponseTraceData": ".get_scores_response_trace_data", + "NumericScoreV3": ".numeric_score_v3", + "ScoreSubject": ".score_subject", + "ScoreSubjectExperiment": ".score_subject_experiment", + "ScoreSubjectObservation": ".score_subject_observation", + "ScoreSubjectSession": ".score_subject_session", + "ScoreSubjectTrace": ".score_subject_trace", + "ScoreSubject_Experiment": ".score_subject", + "ScoreSubject_Observation": ".score_subject", + "ScoreSubject_Session": ".score_subject", + "ScoreSubject_Trace": ".score_subject", + "ScoreV3": ".score_v3", + "ScoreV3_Boolean": ".score_v3", + "ScoreV3_Categorical": ".score_v3", + "ScoreV3_Correction": ".score_v3", + "ScoreV3_Numeric": ".score_v3", + "ScoreV3_Text": ".score_v3", + "TextScoreV3": ".text_score_v3", } @@ -66,17 +88,27 @@ def __dir__(): __all__ = [ + "BaseScoreV3", + "BooleanScoreV3", + "CategoricalScoreV3", + "CorrectionScoreV3", + "GetScoresMeta", "GetScoresResponse", - "GetScoresResponseData", - "GetScoresResponseDataBoolean", - "GetScoresResponseDataCategorical", - "GetScoresResponseDataCorrection", - "GetScoresResponseDataNumeric", - "GetScoresResponseDataText", - "GetScoresResponseData_Boolean", - "GetScoresResponseData_Categorical", - "GetScoresResponseData_Correction", - "GetScoresResponseData_Numeric", - "GetScoresResponseData_Text", - "GetScoresResponseTraceData", + "NumericScoreV3", + "ScoreSubject", + "ScoreSubjectExperiment", + "ScoreSubjectObservation", + "ScoreSubjectSession", + "ScoreSubjectTrace", + "ScoreSubject_Experiment", + "ScoreSubject_Observation", + "ScoreSubject_Session", + "ScoreSubject_Trace", + "ScoreV3", + "ScoreV3_Boolean", + "ScoreV3_Categorical", + "ScoreV3_Correction", + "ScoreV3_Numeric", + "ScoreV3_Text", + "TextScoreV3", ] diff --git a/langfuse/api/scores_v3/types/base_score_v3.py b/langfuse/api/scores/types/base_score_v3.py similarity index 95% rename from langfuse/api/scores_v3/types/base_score_v3.py rename to langfuse/api/scores/types/base_score_v3.py index 3d5394f95..1666c267e 100644 --- a/langfuse/api/scores_v3/types/base_score_v3.py +++ b/langfuse/api/scores/types/base_score_v3.py @@ -8,7 +8,7 @@ from ...commons.types.score_source import ScoreSource from ...core.pydantic_utilities import UniversalBaseModel from ...core.serialization import FieldMetadata -from .score_subject_v3 import ScoreSubjectV3 +from .score_subject import ScoreSubject class BaseScoreV3(UniversalBaseModel): @@ -61,7 +61,7 @@ class BaseScoreV3(UniversalBaseModel): The annotation queue this score belongs to, if any. Present when "annotation" is included in the fields parameter. """ - subject: typing.Optional[ScoreSubjectV3] = pydantic.Field(default=None) + subject: typing.Optional[ScoreSubject] = pydantic.Field(default=None) """ The entity this score is attached to (trace, observation, session, or experiment). Present when "subject" is included in the fields parameter. """ diff --git a/langfuse/api/scores_v3/types/boolean_score_v3.py b/langfuse/api/scores/types/boolean_score_v3.py similarity index 100% rename from langfuse/api/scores_v3/types/boolean_score_v3.py rename to langfuse/api/scores/types/boolean_score_v3.py diff --git a/langfuse/api/scores_v3/types/categorical_score_v3.py b/langfuse/api/scores/types/categorical_score_v3.py similarity index 100% rename from langfuse/api/scores_v3/types/categorical_score_v3.py rename to langfuse/api/scores/types/categorical_score_v3.py diff --git a/langfuse/api/scores_v3/types/correction_score_v3.py b/langfuse/api/scores/types/correction_score_v3.py similarity index 100% rename from langfuse/api/scores_v3/types/correction_score_v3.py rename to langfuse/api/scores/types/correction_score_v3.py diff --git a/langfuse/api/scores_v3/types/get_scores_v3meta.py b/langfuse/api/scores/types/get_scores_meta.py similarity index 91% rename from langfuse/api/scores_v3/types/get_scores_v3meta.py rename to langfuse/api/scores/types/get_scores_meta.py index 7dfcfe0e1..b6a03a9b8 100644 --- a/langfuse/api/scores_v3/types/get_scores_v3meta.py +++ b/langfuse/api/scores/types/get_scores_meta.py @@ -6,7 +6,7 @@ from ...core.pydantic_utilities import UniversalBaseModel -class GetScoresV3Meta(UniversalBaseModel): +class GetScoresMeta(UniversalBaseModel): limit: int cursor: typing.Optional[str] = pydantic.Field(default=None) """ diff --git a/langfuse/api/scores/types/get_scores_response.py b/langfuse/api/scores/types/get_scores_response.py index 0ca4d0e40..c5732bee2 100644 --- a/langfuse/api/scores/types/get_scores_response.py +++ b/langfuse/api/scores/types/get_scores_response.py @@ -4,13 +4,13 @@ import pydantic from ...core.pydantic_utilities import UniversalBaseModel -from ...utils.pagination.types.meta_response import MetaResponse -from .get_scores_response_data import GetScoresResponseData +from .get_scores_meta import GetScoresMeta +from .score_v3 import ScoreV3 class GetScoresResponse(UniversalBaseModel): - data: typing.List[GetScoresResponseData] - meta: MetaResponse + data: typing.List[ScoreV3] + meta: GetScoresMeta model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict( extra="allow", frozen=True diff --git a/langfuse/api/scores_v3/types/numeric_score_v3.py b/langfuse/api/scores/types/numeric_score_v3.py similarity index 100% rename from langfuse/api/scores_v3/types/numeric_score_v3.py rename to langfuse/api/scores/types/numeric_score_v3.py diff --git a/langfuse/api/scores_v3/types/score_subject_v3.py b/langfuse/api/scores/types/score_subject.py similarity index 82% rename from langfuse/api/scores_v3/types/score_subject_v3.py rename to langfuse/api/scores/types/score_subject.py index 7464fda55..eb92b6a40 100644 --- a/langfuse/api/scores_v3/types/score_subject_v3.py +++ b/langfuse/api/scores/types/score_subject.py @@ -10,7 +10,7 @@ from ...core.serialization import FieldMetadata -class ScoreSubjectV3_Trace(UniversalBaseModel): +class ScoreSubject_Trace(UniversalBaseModel): """ A reference to the entity this score is attached to. Discriminated by "kind" — one of trace, observation, session, or experiment. """ @@ -23,7 +23,7 @@ class ScoreSubjectV3_Trace(UniversalBaseModel): ) -class ScoreSubjectV3_Observation(UniversalBaseModel): +class ScoreSubject_Observation(UniversalBaseModel): """ A reference to the entity this score is attached to. Discriminated by "kind" — one of trace, observation, session, or experiment. """ @@ -39,7 +39,7 @@ class ScoreSubjectV3_Observation(UniversalBaseModel): ) -class ScoreSubjectV3_Session(UniversalBaseModel): +class ScoreSubject_Session(UniversalBaseModel): """ A reference to the entity this score is attached to. Discriminated by "kind" — one of trace, observation, session, or experiment. """ @@ -52,7 +52,7 @@ class ScoreSubjectV3_Session(UniversalBaseModel): ) -class ScoreSubjectV3_Experiment(UniversalBaseModel): +class ScoreSubject_Experiment(UniversalBaseModel): """ A reference to the entity this score is attached to. Discriminated by "kind" — one of trace, observation, session, or experiment. """ @@ -65,12 +65,12 @@ class ScoreSubjectV3_Experiment(UniversalBaseModel): ) -ScoreSubjectV3 = typing_extensions.Annotated[ +ScoreSubject = typing_extensions.Annotated[ typing.Union[ - ScoreSubjectV3_Trace, - ScoreSubjectV3_Observation, - ScoreSubjectV3_Session, - ScoreSubjectV3_Experiment, + ScoreSubject_Trace, + ScoreSubject_Observation, + ScoreSubject_Session, + ScoreSubject_Experiment, ], pydantic.Field(discriminator="kind"), ] diff --git a/langfuse/api/scores_v3/types/score_subject_experiment_v3.py b/langfuse/api/scores/types/score_subject_experiment.py similarity index 87% rename from langfuse/api/scores_v3/types/score_subject_experiment_v3.py rename to langfuse/api/scores/types/score_subject_experiment.py index a71a49241..d1ab9a0d7 100644 --- a/langfuse/api/scores_v3/types/score_subject_experiment_v3.py +++ b/langfuse/api/scores/types/score_subject_experiment.py @@ -6,7 +6,7 @@ from ...core.pydantic_utilities import UniversalBaseModel -class ScoreSubjectExperimentV3(UniversalBaseModel): +class ScoreSubjectExperiment(UniversalBaseModel): id: str = pydantic.Field() """ The dataset run ID (experiment ID). diff --git a/langfuse/api/scores_v3/types/score_subject_observation_v3.py b/langfuse/api/scores/types/score_subject_observation.py similarity index 92% rename from langfuse/api/scores_v3/types/score_subject_observation_v3.py rename to langfuse/api/scores/types/score_subject_observation.py index 1bc2edf20..153a0d7b9 100644 --- a/langfuse/api/scores_v3/types/score_subject_observation_v3.py +++ b/langfuse/api/scores/types/score_subject_observation.py @@ -8,7 +8,7 @@ from ...core.serialization import FieldMetadata -class ScoreSubjectObservationV3(UniversalBaseModel): +class ScoreSubjectObservation(UniversalBaseModel): id: str = pydantic.Field() """ The observation ID. diff --git a/langfuse/api/scores_v3/types/score_subject_session_v3.py b/langfuse/api/scores/types/score_subject_session.py similarity index 87% rename from langfuse/api/scores_v3/types/score_subject_session_v3.py rename to langfuse/api/scores/types/score_subject_session.py index cb9347583..9f2d1fef0 100644 --- a/langfuse/api/scores_v3/types/score_subject_session_v3.py +++ b/langfuse/api/scores/types/score_subject_session.py @@ -6,7 +6,7 @@ from ...core.pydantic_utilities import UniversalBaseModel -class ScoreSubjectSessionV3(UniversalBaseModel): +class ScoreSubjectSession(UniversalBaseModel): id: str = pydantic.Field() """ The session ID. diff --git a/langfuse/api/scores_v3/types/score_subject_trace_v3.py b/langfuse/api/scores/types/score_subject_trace.py similarity index 87% rename from langfuse/api/scores_v3/types/score_subject_trace_v3.py rename to langfuse/api/scores/types/score_subject_trace.py index 26aab7f07..266fd860d 100644 --- a/langfuse/api/scores_v3/types/score_subject_trace_v3.py +++ b/langfuse/api/scores/types/score_subject_trace.py @@ -6,7 +6,7 @@ from ...core.pydantic_utilities import UniversalBaseModel -class ScoreSubjectTraceV3(UniversalBaseModel): +class ScoreSubjectTrace(UniversalBaseModel): id: str = pydantic.Field() """ The trace ID. diff --git a/langfuse/api/scores_v3/types/score_v3.py b/langfuse/api/scores/types/score_v3.py similarity index 95% rename from langfuse/api/scores_v3/types/score_v3.py rename to langfuse/api/scores/types/score_v3.py index 9921d1bda..4b2808635 100644 --- a/langfuse/api/scores_v3/types/score_v3.py +++ b/langfuse/api/scores/types/score_v3.py @@ -10,7 +10,7 @@ from ...commons.types.score_source import ScoreSource from ...core.pydantic_utilities import UniversalBaseModel from ...core.serialization import FieldMetadata -from .score_subject_v3 import ScoreSubjectV3 +from .score_subject import ScoreSubject class ScoreV3_Numeric(UniversalBaseModel): @@ -41,7 +41,7 @@ class ScoreV3_Numeric(UniversalBaseModel): queue_id: typing_extensions.Annotated[ typing.Optional[str], FieldMetadata(alias="queueId") ] = None - subject: typing.Optional[ScoreSubjectV3] = None + subject: typing.Optional[ScoreSubject] = None model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict( extra="allow", frozen=True @@ -76,7 +76,7 @@ class ScoreV3_Boolean(UniversalBaseModel): queue_id: typing_extensions.Annotated[ typing.Optional[str], FieldMetadata(alias="queueId") ] = None - subject: typing.Optional[ScoreSubjectV3] = None + subject: typing.Optional[ScoreSubject] = None model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict( extra="allow", frozen=True @@ -111,7 +111,7 @@ class ScoreV3_Categorical(UniversalBaseModel): queue_id: typing_extensions.Annotated[ typing.Optional[str], FieldMetadata(alias="queueId") ] = None - subject: typing.Optional[ScoreSubjectV3] = None + subject: typing.Optional[ScoreSubject] = None model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict( extra="allow", frozen=True @@ -146,7 +146,7 @@ class ScoreV3_Text(UniversalBaseModel): queue_id: typing_extensions.Annotated[ typing.Optional[str], FieldMetadata(alias="queueId") ] = None - subject: typing.Optional[ScoreSubjectV3] = None + subject: typing.Optional[ScoreSubject] = None model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict( extra="allow", frozen=True @@ -181,7 +181,7 @@ class ScoreV3_Correction(UniversalBaseModel): queue_id: typing_extensions.Annotated[ typing.Optional[str], FieldMetadata(alias="queueId") ] = None - subject: typing.Optional[ScoreSubjectV3] = None + subject: typing.Optional[ScoreSubject] = None model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict( extra="allow", frozen=True diff --git a/langfuse/api/scores_v3/types/text_score_v3.py b/langfuse/api/scores/types/text_score_v3.py similarity index 100% rename from langfuse/api/scores_v3/types/text_score_v3.py rename to langfuse/api/scores/types/text_score_v3.py diff --git a/langfuse/api/scores_v3/__init__.py b/langfuse/api/scores_v3/__init__.py deleted file mode 100644 index 855868335..000000000 --- a/langfuse/api/scores_v3/__init__.py +++ /dev/null @@ -1,112 +0,0 @@ -# This file was auto-generated by Fern from our API Definition. - -# isort: skip_file - -import typing -from importlib import import_module - -if typing.TYPE_CHECKING: - from .types import ( - BaseScoreV3, - BooleanScoreV3, - CategoricalScoreV3, - CorrectionScoreV3, - GetScoresV3Meta, - GetScoresV3Response, - NumericScoreV3, - ScoreSubjectExperimentV3, - ScoreSubjectObservationV3, - ScoreSubjectSessionV3, - ScoreSubjectTraceV3, - ScoreSubjectV3, - ScoreSubjectV3_Experiment, - ScoreSubjectV3_Observation, - ScoreSubjectV3_Session, - ScoreSubjectV3_Trace, - ScoreV3, - ScoreV3_Boolean, - ScoreV3_Categorical, - ScoreV3_Correction, - ScoreV3_Numeric, - ScoreV3_Text, - TextScoreV3, - ) -_dynamic_imports: typing.Dict[str, str] = { - "BaseScoreV3": ".types", - "BooleanScoreV3": ".types", - "CategoricalScoreV3": ".types", - "CorrectionScoreV3": ".types", - "GetScoresV3Meta": ".types", - "GetScoresV3Response": ".types", - "NumericScoreV3": ".types", - "ScoreSubjectExperimentV3": ".types", - "ScoreSubjectObservationV3": ".types", - "ScoreSubjectSessionV3": ".types", - "ScoreSubjectTraceV3": ".types", - "ScoreSubjectV3": ".types", - "ScoreSubjectV3_Experiment": ".types", - "ScoreSubjectV3_Observation": ".types", - "ScoreSubjectV3_Session": ".types", - "ScoreSubjectV3_Trace": ".types", - "ScoreV3": ".types", - "ScoreV3_Boolean": ".types", - "ScoreV3_Categorical": ".types", - "ScoreV3_Correction": ".types", - "ScoreV3_Numeric": ".types", - "ScoreV3_Text": ".types", - "TextScoreV3": ".types", -} - - -def __getattr__(attr_name: str) -> typing.Any: - module_name = _dynamic_imports.get(attr_name) - if module_name is None: - raise AttributeError( - f"No {attr_name} found in _dynamic_imports for module name -> {__name__}" - ) - try: - module = import_module(module_name, __package__) - if module_name == f".{attr_name}": - return module - else: - return getattr(module, attr_name) - except ImportError as e: - raise ImportError( - f"Failed to import {attr_name} from {module_name}: {e}" - ) from e - except AttributeError as e: - raise AttributeError( - f"Failed to get {attr_name} from {module_name}: {e}" - ) from e - - -def __dir__(): - lazy_attrs = list(_dynamic_imports.keys()) - return sorted(lazy_attrs) - - -__all__ = [ - "BaseScoreV3", - "BooleanScoreV3", - "CategoricalScoreV3", - "CorrectionScoreV3", - "GetScoresV3Meta", - "GetScoresV3Response", - "NumericScoreV3", - "ScoreSubjectExperimentV3", - "ScoreSubjectObservationV3", - "ScoreSubjectSessionV3", - "ScoreSubjectTraceV3", - "ScoreSubjectV3", - "ScoreSubjectV3_Experiment", - "ScoreSubjectV3_Observation", - "ScoreSubjectV3_Session", - "ScoreSubjectV3_Trace", - "ScoreV3", - "ScoreV3_Boolean", - "ScoreV3_Categorical", - "ScoreV3_Correction", - "ScoreV3_Numeric", - "ScoreV3_Text", - "TextScoreV3", -] diff --git a/langfuse/api/scores_v3/client.py b/langfuse/api/scores_v3/client.py deleted file mode 100644 index 2755d3e74..000000000 --- a/langfuse/api/scores_v3/client.py +++ /dev/null @@ -1,341 +0,0 @@ -# This file was auto-generated by Fern from our API Definition. - -import datetime as dt -import typing - -from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper -from ..core.request_options import RequestOptions -from .raw_client import AsyncRawScoresV3Client, RawScoresV3Client -from .types.get_scores_v3response import GetScoresV3Response - - -class ScoresV3Client: - def __init__(self, *, client_wrapper: SyncClientWrapper): - self._raw_client = RawScoresV3Client(client_wrapper=client_wrapper) - - @property - def with_raw_response(self) -> RawScoresV3Client: - """ - Retrieves a raw implementation of this client that returns raw responses. - - Returns - ------- - RawScoresV3Client - """ - return self._raw_client - - def get_many_v3( - self, - *, - limit: typing.Optional[int] = None, - cursor: typing.Optional[str] = None, - fields: typing.Optional[str] = None, - id: typing.Optional[str] = None, - name: typing.Optional[str] = None, - source: typing.Optional[str] = None, - data_type: typing.Optional[str] = None, - environment: typing.Optional[str] = None, - config_id: typing.Optional[str] = None, - queue_id: typing.Optional[str] = None, - author_user_id: typing.Optional[str] = None, - value: typing.Optional[str] = None, - value_min: typing.Optional[float] = None, - value_max: typing.Optional[float] = None, - trace_id: typing.Optional[str] = None, - session_id: typing.Optional[str] = None, - observation_id: typing.Optional[str] = None, - experiment_id: typing.Optional[str] = None, - from_timestamp: typing.Optional[dt.datetime] = None, - to_timestamp: typing.Optional[dt.datetime] = None, - request_options: typing.Optional[RequestOptions] = None, - ) -> GetScoresV3Response: - """ - Get a list of scores with a polymorphic `value` field (v3). - - This endpoint requires Langfuse v4 or later. - - The `value` field type depends on `dataType`: - - `NUMERIC` → number - - `BOOLEAN` → boolean - - `CATEGORICAL`, `TEXT`, `CORRECTION` → string - - Use the `fields` parameter to include optional field groups beyond the - default `core`. Unknown group names return HTTP 400. - - Parameters - ---------- - limit : typing.Optional[int] - Number of items per page. Maximum 100, default 50. Requests with a limit greater than 100 return HTTP 400. - - cursor : typing.Optional[str] - URL-safe base64 (base64url) cursor for pagination. Use the cursor from the previous response to get the next page. Absent on the final page. - - fields : typing.Optional[str] - Comma-separated field groups to include. Allowed: core, details, subject, annotation. Defaults to "core". Unknown names return HTTP 400. - - id : typing.Optional[str] - Comma-separated list of score IDs to filter by (OR within, AND across filters). - - name : typing.Optional[str] - Comma-separated list of score names to filter by. - - source : typing.Optional[str] - Comma-separated list of score sources to filter by (e.g. API, ANNOTATION, EVAL). Case-insensitive — `api` and `API` are equivalent. - - data_type : typing.Optional[str] - Comma-separated list of data types to filter by (NUMERIC, BOOLEAN, CATEGORICAL, TEXT, CORRECTION). Case-insensitive — `numeric` and `NUMERIC` are equivalent. Must be a single value when used with value, valueMin, or valueMax; otherwise the request returns HTTP 400. Must be NUMERIC when used with valueMin or valueMax. - - environment : typing.Optional[str] - Comma-separated list of environments to filter by. - - config_id : typing.Optional[str] - Comma-separated list of score config IDs to filter by. - - queue_id : typing.Optional[str] - Comma-separated list of annotation queue IDs to filter by. - - author_user_id : typing.Optional[str] - Comma-separated list of author user IDs to filter by. - - value : typing.Optional[str] - Comma-separated list of exact values to filter by. Requires a single dataType from NUMERIC, BOOLEAN, or CATEGORICAL; any other dataType, multiple dataTypes, or omitting dataType returns HTTP 400. For BOOLEAN, each value must be "true" or "false"; for NUMERIC, each value must be a finite number. Otherwise the request returns HTTP 400. - - value_min : typing.Optional[float] - Inclusive lower bound on the numeric value. Requires dataType=NUMERIC as a single value; otherwise the request returns HTTP 400. - - value_max : typing.Optional[float] - Inclusive upper bound on the numeric value. Requires dataType=NUMERIC as a single value; otherwise the request returns HTTP 400. - - trace_id : typing.Optional[str] - Comma-separated list of trace IDs to filter by. Mutually exclusive with sessionId, experimentId. May be combined with observationId to scope the observation lookup to a specific trace. - - session_id : typing.Optional[str] - Comma-separated list of session IDs to filter by. Mutually exclusive with traceId, observationId, experimentId. - - observation_id : typing.Optional[str] - Comma-separated list of observation IDs to filter by. Requires traceId to be specified, because observation IDs are scoped to a trace. Mutually exclusive with sessionId, experimentId. Returns HTTP 400 when used without traceId. - - experiment_id : typing.Optional[str] - Comma-separated list of dataset run IDs (experiment IDs) to filter by. Mutually exclusive with traceId, sessionId, observationId. - - from_timestamp : typing.Optional[dt.datetime] - Inclusive lower bound on the score timestamp. - - to_timestamp : typing.Optional[dt.datetime] - Exclusive upper bound on the score timestamp. - - request_options : typing.Optional[RequestOptions] - Request-specific configuration. - - Returns - ------- - GetScoresV3Response - - Examples - -------- - from langfuse import LangfuseAPI - - client = LangfuseAPI( - 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.scores_v3.get_many_v3() - """ - _response = self._raw_client.get_many_v3( - limit=limit, - cursor=cursor, - fields=fields, - id=id, - name=name, - source=source, - data_type=data_type, - environment=environment, - config_id=config_id, - queue_id=queue_id, - author_user_id=author_user_id, - value=value, - value_min=value_min, - value_max=value_max, - trace_id=trace_id, - session_id=session_id, - observation_id=observation_id, - experiment_id=experiment_id, - from_timestamp=from_timestamp, - to_timestamp=to_timestamp, - request_options=request_options, - ) - return _response.data - - -class AsyncScoresV3Client: - def __init__(self, *, client_wrapper: AsyncClientWrapper): - self._raw_client = AsyncRawScoresV3Client(client_wrapper=client_wrapper) - - @property - def with_raw_response(self) -> AsyncRawScoresV3Client: - """ - Retrieves a raw implementation of this client that returns raw responses. - - Returns - ------- - AsyncRawScoresV3Client - """ - return self._raw_client - - async def get_many_v3( - self, - *, - limit: typing.Optional[int] = None, - cursor: typing.Optional[str] = None, - fields: typing.Optional[str] = None, - id: typing.Optional[str] = None, - name: typing.Optional[str] = None, - source: typing.Optional[str] = None, - data_type: typing.Optional[str] = None, - environment: typing.Optional[str] = None, - config_id: typing.Optional[str] = None, - queue_id: typing.Optional[str] = None, - author_user_id: typing.Optional[str] = None, - value: typing.Optional[str] = None, - value_min: typing.Optional[float] = None, - value_max: typing.Optional[float] = None, - trace_id: typing.Optional[str] = None, - session_id: typing.Optional[str] = None, - observation_id: typing.Optional[str] = None, - experiment_id: typing.Optional[str] = None, - from_timestamp: typing.Optional[dt.datetime] = None, - to_timestamp: typing.Optional[dt.datetime] = None, - request_options: typing.Optional[RequestOptions] = None, - ) -> GetScoresV3Response: - """ - Get a list of scores with a polymorphic `value` field (v3). - - This endpoint requires Langfuse v4 or later. - - The `value` field type depends on `dataType`: - - `NUMERIC` → number - - `BOOLEAN` → boolean - - `CATEGORICAL`, `TEXT`, `CORRECTION` → string - - Use the `fields` parameter to include optional field groups beyond the - default `core`. Unknown group names return HTTP 400. - - Parameters - ---------- - limit : typing.Optional[int] - Number of items per page. Maximum 100, default 50. Requests with a limit greater than 100 return HTTP 400. - - cursor : typing.Optional[str] - URL-safe base64 (base64url) cursor for pagination. Use the cursor from the previous response to get the next page. Absent on the final page. - - fields : typing.Optional[str] - Comma-separated field groups to include. Allowed: core, details, subject, annotation. Defaults to "core". Unknown names return HTTP 400. - - id : typing.Optional[str] - Comma-separated list of score IDs to filter by (OR within, AND across filters). - - name : typing.Optional[str] - Comma-separated list of score names to filter by. - - source : typing.Optional[str] - Comma-separated list of score sources to filter by (e.g. API, ANNOTATION, EVAL). Case-insensitive — `api` and `API` are equivalent. - - data_type : typing.Optional[str] - Comma-separated list of data types to filter by (NUMERIC, BOOLEAN, CATEGORICAL, TEXT, CORRECTION). Case-insensitive — `numeric` and `NUMERIC` are equivalent. Must be a single value when used with value, valueMin, or valueMax; otherwise the request returns HTTP 400. Must be NUMERIC when used with valueMin or valueMax. - - environment : typing.Optional[str] - Comma-separated list of environments to filter by. - - config_id : typing.Optional[str] - Comma-separated list of score config IDs to filter by. - - queue_id : typing.Optional[str] - Comma-separated list of annotation queue IDs to filter by. - - author_user_id : typing.Optional[str] - Comma-separated list of author user IDs to filter by. - - value : typing.Optional[str] - Comma-separated list of exact values to filter by. Requires a single dataType from NUMERIC, BOOLEAN, or CATEGORICAL; any other dataType, multiple dataTypes, or omitting dataType returns HTTP 400. For BOOLEAN, each value must be "true" or "false"; for NUMERIC, each value must be a finite number. Otherwise the request returns HTTP 400. - - value_min : typing.Optional[float] - Inclusive lower bound on the numeric value. Requires dataType=NUMERIC as a single value; otherwise the request returns HTTP 400. - - value_max : typing.Optional[float] - Inclusive upper bound on the numeric value. Requires dataType=NUMERIC as a single value; otherwise the request returns HTTP 400. - - trace_id : typing.Optional[str] - Comma-separated list of trace IDs to filter by. Mutually exclusive with sessionId, experimentId. May be combined with observationId to scope the observation lookup to a specific trace. - - session_id : typing.Optional[str] - Comma-separated list of session IDs to filter by. Mutually exclusive with traceId, observationId, experimentId. - - observation_id : typing.Optional[str] - Comma-separated list of observation IDs to filter by. Requires traceId to be specified, because observation IDs are scoped to a trace. Mutually exclusive with sessionId, experimentId. Returns HTTP 400 when used without traceId. - - experiment_id : typing.Optional[str] - Comma-separated list of dataset run IDs (experiment IDs) to filter by. Mutually exclusive with traceId, sessionId, observationId. - - from_timestamp : typing.Optional[dt.datetime] - Inclusive lower bound on the score timestamp. - - to_timestamp : typing.Optional[dt.datetime] - Exclusive upper bound on the score timestamp. - - request_options : typing.Optional[RequestOptions] - Request-specific configuration. - - Returns - ------- - GetScoresV3Response - - Examples - -------- - import asyncio - - from langfuse import AsyncLangfuseAPI - - client = AsyncLangfuseAPI( - 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.scores_v3.get_many_v3() - - - asyncio.run(main()) - """ - _response = await self._raw_client.get_many_v3( - limit=limit, - cursor=cursor, - fields=fields, - id=id, - name=name, - source=source, - data_type=data_type, - environment=environment, - config_id=config_id, - queue_id=queue_id, - author_user_id=author_user_id, - value=value, - value_min=value_min, - value_max=value_max, - trace_id=trace_id, - session_id=session_id, - observation_id=observation_id, - experiment_id=experiment_id, - from_timestamp=from_timestamp, - to_timestamp=to_timestamp, - request_options=request_options, - ) - return _response.data diff --git a/langfuse/api/scores_v3/raw_client.py b/langfuse/api/scores_v3/raw_client.py deleted file mode 100644 index 47c9f3f8d..000000000 --- a/langfuse/api/scores_v3/raw_client.py +++ /dev/null @@ -1,460 +0,0 @@ -# This file was auto-generated by Fern from our API Definition. - -import datetime as dt -import typing -from json.decoder import JSONDecodeError - -from ..commons.errors.access_denied_error import AccessDeniedError -from ..commons.errors.error import Error -from ..commons.errors.method_not_allowed_error import MethodNotAllowedError -from ..commons.errors.not_found_error import NotFoundError -from ..commons.errors.unauthorized_error import UnauthorizedError -from ..core.api_error import ApiError -from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper -from ..core.datetime_utils import serialize_datetime -from ..core.http_response import AsyncHttpResponse, HttpResponse -from ..core.pydantic_utilities import parse_obj_as -from ..core.request_options import RequestOptions -from .types.get_scores_v3response import GetScoresV3Response - - -class RawScoresV3Client: - def __init__(self, *, client_wrapper: SyncClientWrapper): - self._client_wrapper = client_wrapper - - def get_many_v3( - self, - *, - limit: typing.Optional[int] = None, - cursor: typing.Optional[str] = None, - fields: typing.Optional[str] = None, - id: typing.Optional[str] = None, - name: typing.Optional[str] = None, - source: typing.Optional[str] = None, - data_type: typing.Optional[str] = None, - environment: typing.Optional[str] = None, - config_id: typing.Optional[str] = None, - queue_id: typing.Optional[str] = None, - author_user_id: typing.Optional[str] = None, - value: typing.Optional[str] = None, - value_min: typing.Optional[float] = None, - value_max: typing.Optional[float] = None, - trace_id: typing.Optional[str] = None, - session_id: typing.Optional[str] = None, - observation_id: typing.Optional[str] = None, - experiment_id: typing.Optional[str] = None, - from_timestamp: typing.Optional[dt.datetime] = None, - to_timestamp: typing.Optional[dt.datetime] = None, - request_options: typing.Optional[RequestOptions] = None, - ) -> HttpResponse[GetScoresV3Response]: - """ - Get a list of scores with a polymorphic `value` field (v3). - - This endpoint requires Langfuse v4 or later. - - The `value` field type depends on `dataType`: - - `NUMERIC` → number - - `BOOLEAN` → boolean - - `CATEGORICAL`, `TEXT`, `CORRECTION` → string - - Use the `fields` parameter to include optional field groups beyond the - default `core`. Unknown group names return HTTP 400. - - Parameters - ---------- - limit : typing.Optional[int] - Number of items per page. Maximum 100, default 50. Requests with a limit greater than 100 return HTTP 400. - - cursor : typing.Optional[str] - URL-safe base64 (base64url) cursor for pagination. Use the cursor from the previous response to get the next page. Absent on the final page. - - fields : typing.Optional[str] - Comma-separated field groups to include. Allowed: core, details, subject, annotation. Defaults to "core". Unknown names return HTTP 400. - - id : typing.Optional[str] - Comma-separated list of score IDs to filter by (OR within, AND across filters). - - name : typing.Optional[str] - Comma-separated list of score names to filter by. - - source : typing.Optional[str] - Comma-separated list of score sources to filter by (e.g. API, ANNOTATION, EVAL). Case-insensitive — `api` and `API` are equivalent. - - data_type : typing.Optional[str] - Comma-separated list of data types to filter by (NUMERIC, BOOLEAN, CATEGORICAL, TEXT, CORRECTION). Case-insensitive — `numeric` and `NUMERIC` are equivalent. Must be a single value when used with value, valueMin, or valueMax; otherwise the request returns HTTP 400. Must be NUMERIC when used with valueMin or valueMax. - - environment : typing.Optional[str] - Comma-separated list of environments to filter by. - - config_id : typing.Optional[str] - Comma-separated list of score config IDs to filter by. - - queue_id : typing.Optional[str] - Comma-separated list of annotation queue IDs to filter by. - - author_user_id : typing.Optional[str] - Comma-separated list of author user IDs to filter by. - - value : typing.Optional[str] - Comma-separated list of exact values to filter by. Requires a single dataType from NUMERIC, BOOLEAN, or CATEGORICAL; any other dataType, multiple dataTypes, or omitting dataType returns HTTP 400. For BOOLEAN, each value must be "true" or "false"; for NUMERIC, each value must be a finite number. Otherwise the request returns HTTP 400. - - value_min : typing.Optional[float] - Inclusive lower bound on the numeric value. Requires dataType=NUMERIC as a single value; otherwise the request returns HTTP 400. - - value_max : typing.Optional[float] - Inclusive upper bound on the numeric value. Requires dataType=NUMERIC as a single value; otherwise the request returns HTTP 400. - - trace_id : typing.Optional[str] - Comma-separated list of trace IDs to filter by. Mutually exclusive with sessionId, experimentId. May be combined with observationId to scope the observation lookup to a specific trace. - - session_id : typing.Optional[str] - Comma-separated list of session IDs to filter by. Mutually exclusive with traceId, observationId, experimentId. - - observation_id : typing.Optional[str] - Comma-separated list of observation IDs to filter by. Requires traceId to be specified, because observation IDs are scoped to a trace. Mutually exclusive with sessionId, experimentId. Returns HTTP 400 when used without traceId. - - experiment_id : typing.Optional[str] - Comma-separated list of dataset run IDs (experiment IDs) to filter by. Mutually exclusive with traceId, sessionId, observationId. - - from_timestamp : typing.Optional[dt.datetime] - Inclusive lower bound on the score timestamp. - - to_timestamp : typing.Optional[dt.datetime] - Exclusive upper bound on the score timestamp. - - request_options : typing.Optional[RequestOptions] - Request-specific configuration. - - Returns - ------- - HttpResponse[GetScoresV3Response] - """ - _response = self._client_wrapper.httpx_client.request( - "api/public/v3/scores", - method="GET", - params={ - "limit": limit, - "cursor": cursor, - "fields": fields, - "id": id, - "name": name, - "source": source, - "dataType": data_type, - "environment": environment, - "configId": config_id, - "queueId": queue_id, - "authorUserId": author_user_id, - "value": value, - "valueMin": value_min, - "valueMax": value_max, - "traceId": trace_id, - "sessionId": session_id, - "observationId": observation_id, - "experimentId": experiment_id, - "fromTimestamp": serialize_datetime(from_timestamp) - if from_timestamp is not None - else None, - "toTimestamp": serialize_datetime(to_timestamp) - if to_timestamp is not None - else None, - }, - request_options=request_options, - ) - try: - if 200 <= _response.status_code < 300: - _data = typing.cast( - GetScoresV3Response, - parse_obj_as( - type_=GetScoresV3Response, # type: ignore - object_=_response.json(), - ), - ) - return HttpResponse(response=_response, data=_data) - if _response.status_code == 400: - raise Error( - headers=dict(_response.headers), - body=typing.cast( - typing.Any, - parse_obj_as( - type_=typing.Any, # type: ignore - object_=_response.json(), - ), - ), - ) - if _response.status_code == 401: - raise UnauthorizedError( - headers=dict(_response.headers), - body=typing.cast( - typing.Any, - parse_obj_as( - type_=typing.Any, # type: ignore - object_=_response.json(), - ), - ), - ) - if _response.status_code == 403: - raise AccessDeniedError( - headers=dict(_response.headers), - body=typing.cast( - typing.Any, - parse_obj_as( - type_=typing.Any, # type: ignore - object_=_response.json(), - ), - ), - ) - if _response.status_code == 405: - raise MethodNotAllowedError( - headers=dict(_response.headers), - body=typing.cast( - typing.Any, - parse_obj_as( - type_=typing.Any, # type: ignore - object_=_response.json(), - ), - ), - ) - if _response.status_code == 404: - raise NotFoundError( - headers=dict(_response.headers), - body=typing.cast( - typing.Any, - parse_obj_as( - type_=typing.Any, # type: ignore - object_=_response.json(), - ), - ), - ) - _response_json = _response.json() - except JSONDecodeError: - raise ApiError( - status_code=_response.status_code, - headers=dict(_response.headers), - body=_response.text, - ) - raise ApiError( - status_code=_response.status_code, - headers=dict(_response.headers), - body=_response_json, - ) - - -class AsyncRawScoresV3Client: - def __init__(self, *, client_wrapper: AsyncClientWrapper): - self._client_wrapper = client_wrapper - - async def get_many_v3( - self, - *, - limit: typing.Optional[int] = None, - cursor: typing.Optional[str] = None, - fields: typing.Optional[str] = None, - id: typing.Optional[str] = None, - name: typing.Optional[str] = None, - source: typing.Optional[str] = None, - data_type: typing.Optional[str] = None, - environment: typing.Optional[str] = None, - config_id: typing.Optional[str] = None, - queue_id: typing.Optional[str] = None, - author_user_id: typing.Optional[str] = None, - value: typing.Optional[str] = None, - value_min: typing.Optional[float] = None, - value_max: typing.Optional[float] = None, - trace_id: typing.Optional[str] = None, - session_id: typing.Optional[str] = None, - observation_id: typing.Optional[str] = None, - experiment_id: typing.Optional[str] = None, - from_timestamp: typing.Optional[dt.datetime] = None, - to_timestamp: typing.Optional[dt.datetime] = None, - request_options: typing.Optional[RequestOptions] = None, - ) -> AsyncHttpResponse[GetScoresV3Response]: - """ - Get a list of scores with a polymorphic `value` field (v3). - - This endpoint requires Langfuse v4 or later. - - The `value` field type depends on `dataType`: - - `NUMERIC` → number - - `BOOLEAN` → boolean - - `CATEGORICAL`, `TEXT`, `CORRECTION` → string - - Use the `fields` parameter to include optional field groups beyond the - default `core`. Unknown group names return HTTP 400. - - Parameters - ---------- - limit : typing.Optional[int] - Number of items per page. Maximum 100, default 50. Requests with a limit greater than 100 return HTTP 400. - - cursor : typing.Optional[str] - URL-safe base64 (base64url) cursor for pagination. Use the cursor from the previous response to get the next page. Absent on the final page. - - fields : typing.Optional[str] - Comma-separated field groups to include. Allowed: core, details, subject, annotation. Defaults to "core". Unknown names return HTTP 400. - - id : typing.Optional[str] - Comma-separated list of score IDs to filter by (OR within, AND across filters). - - name : typing.Optional[str] - Comma-separated list of score names to filter by. - - source : typing.Optional[str] - Comma-separated list of score sources to filter by (e.g. API, ANNOTATION, EVAL). Case-insensitive — `api` and `API` are equivalent. - - data_type : typing.Optional[str] - Comma-separated list of data types to filter by (NUMERIC, BOOLEAN, CATEGORICAL, TEXT, CORRECTION). Case-insensitive — `numeric` and `NUMERIC` are equivalent. Must be a single value when used with value, valueMin, or valueMax; otherwise the request returns HTTP 400. Must be NUMERIC when used with valueMin or valueMax. - - environment : typing.Optional[str] - Comma-separated list of environments to filter by. - - config_id : typing.Optional[str] - Comma-separated list of score config IDs to filter by. - - queue_id : typing.Optional[str] - Comma-separated list of annotation queue IDs to filter by. - - author_user_id : typing.Optional[str] - Comma-separated list of author user IDs to filter by. - - value : typing.Optional[str] - Comma-separated list of exact values to filter by. Requires a single dataType from NUMERIC, BOOLEAN, or CATEGORICAL; any other dataType, multiple dataTypes, or omitting dataType returns HTTP 400. For BOOLEAN, each value must be "true" or "false"; for NUMERIC, each value must be a finite number. Otherwise the request returns HTTP 400. - - value_min : typing.Optional[float] - Inclusive lower bound on the numeric value. Requires dataType=NUMERIC as a single value; otherwise the request returns HTTP 400. - - value_max : typing.Optional[float] - Inclusive upper bound on the numeric value. Requires dataType=NUMERIC as a single value; otherwise the request returns HTTP 400. - - trace_id : typing.Optional[str] - Comma-separated list of trace IDs to filter by. Mutually exclusive with sessionId, experimentId. May be combined with observationId to scope the observation lookup to a specific trace. - - session_id : typing.Optional[str] - Comma-separated list of session IDs to filter by. Mutually exclusive with traceId, observationId, experimentId. - - observation_id : typing.Optional[str] - Comma-separated list of observation IDs to filter by. Requires traceId to be specified, because observation IDs are scoped to a trace. Mutually exclusive with sessionId, experimentId. Returns HTTP 400 when used without traceId. - - experiment_id : typing.Optional[str] - Comma-separated list of dataset run IDs (experiment IDs) to filter by. Mutually exclusive with traceId, sessionId, observationId. - - from_timestamp : typing.Optional[dt.datetime] - Inclusive lower bound on the score timestamp. - - to_timestamp : typing.Optional[dt.datetime] - Exclusive upper bound on the score timestamp. - - request_options : typing.Optional[RequestOptions] - Request-specific configuration. - - Returns - ------- - AsyncHttpResponse[GetScoresV3Response] - """ - _response = await self._client_wrapper.httpx_client.request( - "api/public/v3/scores", - method="GET", - params={ - "limit": limit, - "cursor": cursor, - "fields": fields, - "id": id, - "name": name, - "source": source, - "dataType": data_type, - "environment": environment, - "configId": config_id, - "queueId": queue_id, - "authorUserId": author_user_id, - "value": value, - "valueMin": value_min, - "valueMax": value_max, - "traceId": trace_id, - "sessionId": session_id, - "observationId": observation_id, - "experimentId": experiment_id, - "fromTimestamp": serialize_datetime(from_timestamp) - if from_timestamp is not None - else None, - "toTimestamp": serialize_datetime(to_timestamp) - if to_timestamp is not None - else None, - }, - request_options=request_options, - ) - try: - if 200 <= _response.status_code < 300: - _data = typing.cast( - GetScoresV3Response, - parse_obj_as( - type_=GetScoresV3Response, # type: ignore - object_=_response.json(), - ), - ) - return AsyncHttpResponse(response=_response, data=_data) - if _response.status_code == 400: - raise Error( - headers=dict(_response.headers), - body=typing.cast( - typing.Any, - parse_obj_as( - type_=typing.Any, # type: ignore - object_=_response.json(), - ), - ), - ) - if _response.status_code == 401: - raise UnauthorizedError( - headers=dict(_response.headers), - body=typing.cast( - typing.Any, - parse_obj_as( - type_=typing.Any, # type: ignore - object_=_response.json(), - ), - ), - ) - if _response.status_code == 403: - raise AccessDeniedError( - headers=dict(_response.headers), - body=typing.cast( - typing.Any, - parse_obj_as( - type_=typing.Any, # type: ignore - object_=_response.json(), - ), - ), - ) - if _response.status_code == 405: - raise MethodNotAllowedError( - headers=dict(_response.headers), - body=typing.cast( - typing.Any, - parse_obj_as( - type_=typing.Any, # type: ignore - object_=_response.json(), - ), - ), - ) - if _response.status_code == 404: - raise NotFoundError( - headers=dict(_response.headers), - body=typing.cast( - typing.Any, - parse_obj_as( - type_=typing.Any, # type: ignore - object_=_response.json(), - ), - ), - ) - _response_json = _response.json() - except JSONDecodeError: - raise ApiError( - status_code=_response.status_code, - headers=dict(_response.headers), - body=_response.text, - ) - raise ApiError( - status_code=_response.status_code, - headers=dict(_response.headers), - body=_response_json, - ) diff --git a/langfuse/api/scores_v3/types/__init__.py b/langfuse/api/scores_v3/types/__init__.py deleted file mode 100644 index 14da0ca73..000000000 --- a/langfuse/api/scores_v3/types/__init__.py +++ /dev/null @@ -1,114 +0,0 @@ -# This file was auto-generated by Fern from our API Definition. - -# isort: skip_file - -import typing -from importlib import import_module - -if typing.TYPE_CHECKING: - from .base_score_v3 import BaseScoreV3 - from .boolean_score_v3 import BooleanScoreV3 - from .categorical_score_v3 import CategoricalScoreV3 - from .correction_score_v3 import CorrectionScoreV3 - from .get_scores_v3meta import GetScoresV3Meta - from .get_scores_v3response import GetScoresV3Response - from .numeric_score_v3 import NumericScoreV3 - from .score_subject_experiment_v3 import ScoreSubjectExperimentV3 - from .score_subject_observation_v3 import ScoreSubjectObservationV3 - from .score_subject_session_v3 import ScoreSubjectSessionV3 - from .score_subject_trace_v3 import ScoreSubjectTraceV3 - from .score_subject_v3 import ( - ScoreSubjectV3, - ScoreSubjectV3_Experiment, - ScoreSubjectV3_Observation, - ScoreSubjectV3_Session, - ScoreSubjectV3_Trace, - ) - from .score_v3 import ( - ScoreV3, - ScoreV3_Boolean, - ScoreV3_Categorical, - ScoreV3_Correction, - ScoreV3_Numeric, - ScoreV3_Text, - ) - from .text_score_v3 import TextScoreV3 -_dynamic_imports: typing.Dict[str, str] = { - "BaseScoreV3": ".base_score_v3", - "BooleanScoreV3": ".boolean_score_v3", - "CategoricalScoreV3": ".categorical_score_v3", - "CorrectionScoreV3": ".correction_score_v3", - "GetScoresV3Meta": ".get_scores_v3meta", - "GetScoresV3Response": ".get_scores_v3response", - "NumericScoreV3": ".numeric_score_v3", - "ScoreSubjectExperimentV3": ".score_subject_experiment_v3", - "ScoreSubjectObservationV3": ".score_subject_observation_v3", - "ScoreSubjectSessionV3": ".score_subject_session_v3", - "ScoreSubjectTraceV3": ".score_subject_trace_v3", - "ScoreSubjectV3": ".score_subject_v3", - "ScoreSubjectV3_Experiment": ".score_subject_v3", - "ScoreSubjectV3_Observation": ".score_subject_v3", - "ScoreSubjectV3_Session": ".score_subject_v3", - "ScoreSubjectV3_Trace": ".score_subject_v3", - "ScoreV3": ".score_v3", - "ScoreV3_Boolean": ".score_v3", - "ScoreV3_Categorical": ".score_v3", - "ScoreV3_Correction": ".score_v3", - "ScoreV3_Numeric": ".score_v3", - "ScoreV3_Text": ".score_v3", - "TextScoreV3": ".text_score_v3", -} - - -def __getattr__(attr_name: str) -> typing.Any: - module_name = _dynamic_imports.get(attr_name) - if module_name is None: - raise AttributeError( - f"No {attr_name} found in _dynamic_imports for module name -> {__name__}" - ) - try: - module = import_module(module_name, __package__) - if module_name == f".{attr_name}": - return module - else: - return getattr(module, attr_name) - except ImportError as e: - raise ImportError( - f"Failed to import {attr_name} from {module_name}: {e}" - ) from e - except AttributeError as e: - raise AttributeError( - f"Failed to get {attr_name} from {module_name}: {e}" - ) from e - - -def __dir__(): - lazy_attrs = list(_dynamic_imports.keys()) - return sorted(lazy_attrs) - - -__all__ = [ - "BaseScoreV3", - "BooleanScoreV3", - "CategoricalScoreV3", - "CorrectionScoreV3", - "GetScoresV3Meta", - "GetScoresV3Response", - "NumericScoreV3", - "ScoreSubjectExperimentV3", - "ScoreSubjectObservationV3", - "ScoreSubjectSessionV3", - "ScoreSubjectTraceV3", - "ScoreSubjectV3", - "ScoreSubjectV3_Experiment", - "ScoreSubjectV3_Observation", - "ScoreSubjectV3_Session", - "ScoreSubjectV3_Trace", - "ScoreV3", - "ScoreV3_Boolean", - "ScoreV3_Categorical", - "ScoreV3_Correction", - "ScoreV3_Numeric", - "ScoreV3_Text", - "TextScoreV3", -] diff --git a/langfuse/api/scores_v3/types/get_scores_v3response.py b/langfuse/api/scores_v3/types/get_scores_v3response.py deleted file mode 100644 index 4d625b29a..000000000 --- a/langfuse/api/scores_v3/types/get_scores_v3response.py +++ /dev/null @@ -1,17 +0,0 @@ -# This file was auto-generated by Fern from our API Definition. - -import typing - -import pydantic -from ...core.pydantic_utilities import UniversalBaseModel -from .get_scores_v3meta import GetScoresV3Meta -from .score_v3 import ScoreV3 - - -class GetScoresV3Response(UniversalBaseModel): - data: typing.List[ScoreV3] - meta: GetScoresV3Meta - - model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict( - extra="allow", frozen=True - )