diff --git a/langfuse/api/__init__.py b/langfuse/api/__init__.py index 932a60e93..3dd6de4e4 100644 --- a/langfuse/api/__init__.py +++ b/langfuse/api/__init__.py @@ -200,6 +200,7 @@ UpdateGenerationBody, UpdateGenerationEvent, UpdateObservationEvent, + UpdateScoreConfigRequest, UpdateSpanBody, UpdateSpanEvent, UpsertLlmConnectionRequest, @@ -433,6 +434,7 @@ "UpdateGenerationBody", "UpdateGenerationEvent", "UpdateObservationEvent", + "UpdateScoreConfigRequest", "UpdateSpanBody", "UpdateSpanEvent", "UpsertLlmConnectionRequest", diff --git a/langfuse/api/reference.md b/langfuse/api/reference.md index 6b243980f..b9e598e7e 100644 --- a/langfuse/api/reference.md +++ b/langfuse/api/reference.md @@ -5904,6 +5904,91 @@ client.score_configs.get_by_id( + + + + +
client.score_configs.update(...) +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Update a score config +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from langfuse import UpdateScoreConfigRequest +from langfuse.client import FernLangfuse + +client = FernLangfuse( + x_langfuse_sdk_name="YOUR_X_LANGFUSE_SDK_NAME", + x_langfuse_sdk_version="YOUR_X_LANGFUSE_SDK_VERSION", + x_langfuse_public_key="YOUR_X_LANGFUSE_PUBLIC_KEY", + username="YOUR_USERNAME", + password="YOUR_PASSWORD", + base_url="https://yourhost.com/path/to/api", +) +client.score_configs.update( + config_id="configId", + request=UpdateScoreConfigRequest(), +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**config_id:** `str` — The unique langfuse identifier of a score config + +
+
+ +
+
+ +**request:** `UpdateScoreConfigRequest` + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ +
diff --git a/langfuse/api/resources/__init__.py b/langfuse/api/resources/__init__.py index 8b0f6ec76..ae77cad9d 100644 --- a/langfuse/api/resources/__init__.py +++ b/langfuse/api/resources/__init__.py @@ -234,7 +234,11 @@ UserMeta, ) from .score import CreateScoreRequest, CreateScoreResponse -from .score_configs import CreateScoreConfigRequest, ScoreConfigs +from .score_configs import ( + CreateScoreConfigRequest, + ScoreConfigs, + UpdateScoreConfigRequest, +) from .score_v_2 import ( GetScoresResponse, GetScoresResponseData, @@ -449,6 +453,7 @@ "UpdateGenerationBody", "UpdateGenerationEvent", "UpdateObservationEvent", + "UpdateScoreConfigRequest", "UpdateSpanBody", "UpdateSpanEvent", "UpsertLlmConnectionRequest", diff --git a/langfuse/api/resources/score_configs/__init__.py b/langfuse/api/resources/score_configs/__init__.py index e46e2a578..da401d35d 100644 --- a/langfuse/api/resources/score_configs/__init__.py +++ b/langfuse/api/resources/score_configs/__init__.py @@ -1,5 +1,5 @@ # This file was auto-generated by Fern from our API Definition. -from .types import CreateScoreConfigRequest, ScoreConfigs +from .types import CreateScoreConfigRequest, ScoreConfigs, UpdateScoreConfigRequest -__all__ = ["CreateScoreConfigRequest", "ScoreConfigs"] +__all__ = ["CreateScoreConfigRequest", "ScoreConfigs", "UpdateScoreConfigRequest"] diff --git a/langfuse/api/resources/score_configs/client.py b/langfuse/api/resources/score_configs/client.py index 7bd2a72df..7faea8312 100644 --- a/langfuse/api/resources/score_configs/client.py +++ b/langfuse/api/resources/score_configs/client.py @@ -16,6 +16,7 @@ from ..commons.types.score_config import ScoreConfig from .types.create_score_config_request import CreateScoreConfigRequest from .types.score_configs import ScoreConfigs +from .types.update_score_config_request import UpdateScoreConfigRequest # this is used as the default value for optional parameters OMIT = typing.cast(typing.Any, ...) @@ -234,6 +235,81 @@ def get_by_id( raise ApiError(status_code=_response.status_code, body=_response.text) raise ApiError(status_code=_response.status_code, body=_response_json) + def update( + self, + config_id: str, + *, + request: UpdateScoreConfigRequest, + request_options: typing.Optional[RequestOptions] = None, + ) -> ScoreConfig: + """ + Update a score config + + Parameters + ---------- + config_id : str + The unique langfuse identifier of a score config + + request : UpdateScoreConfigRequest + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + ScoreConfig + + Examples + -------- + from langfuse import UpdateScoreConfigRequest + from langfuse.client import FernLangfuse + + client = FernLangfuse( + x_langfuse_sdk_name="YOUR_X_LANGFUSE_SDK_NAME", + x_langfuse_sdk_version="YOUR_X_LANGFUSE_SDK_VERSION", + x_langfuse_public_key="YOUR_X_LANGFUSE_PUBLIC_KEY", + username="YOUR_USERNAME", + password="YOUR_PASSWORD", + base_url="https://yourhost.com/path/to/api", + ) + client.score_configs.update( + config_id="configId", + request=UpdateScoreConfigRequest(), + ) + """ + _response = self._client_wrapper.httpx_client.request( + f"api/public/score-configs/{jsonable_encoder(config_id)}", + method="PATCH", + json=request, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + return pydantic_v1.parse_obj_as(ScoreConfig, _response.json()) # type: ignore + if _response.status_code == 400: + raise Error(pydantic_v1.parse_obj_as(typing.Any, _response.json())) # type: ignore + if _response.status_code == 401: + raise UnauthorizedError( + pydantic_v1.parse_obj_as(typing.Any, _response.json()) + ) # type: ignore + if _response.status_code == 403: + raise AccessDeniedError( + pydantic_v1.parse_obj_as(typing.Any, _response.json()) + ) # type: ignore + if _response.status_code == 405: + raise MethodNotAllowedError( + pydantic_v1.parse_obj_as(typing.Any, _response.json()) + ) # type: ignore + if _response.status_code == 404: + raise NotFoundError( + pydantic_v1.parse_obj_as(typing.Any, _response.json()) + ) # type: ignore + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, body=_response.text) + raise ApiError(status_code=_response.status_code, body=_response_json) + class AsyncScoreConfigsClient: def __init__(self, *, client_wrapper: AsyncClientWrapper): @@ -471,3 +547,86 @@ async def main() -> None: except JSONDecodeError: raise ApiError(status_code=_response.status_code, body=_response.text) raise ApiError(status_code=_response.status_code, body=_response_json) + + async def update( + self, + config_id: str, + *, + request: UpdateScoreConfigRequest, + request_options: typing.Optional[RequestOptions] = None, + ) -> ScoreConfig: + """ + Update a score config + + Parameters + ---------- + config_id : str + The unique langfuse identifier of a score config + + request : UpdateScoreConfigRequest + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + ScoreConfig + + Examples + -------- + import asyncio + + from langfuse import UpdateScoreConfigRequest + from langfuse.client import AsyncFernLangfuse + + client = AsyncFernLangfuse( + x_langfuse_sdk_name="YOUR_X_LANGFUSE_SDK_NAME", + x_langfuse_sdk_version="YOUR_X_LANGFUSE_SDK_VERSION", + x_langfuse_public_key="YOUR_X_LANGFUSE_PUBLIC_KEY", + username="YOUR_USERNAME", + password="YOUR_PASSWORD", + base_url="https://yourhost.com/path/to/api", + ) + + + async def main() -> None: + await client.score_configs.update( + config_id="configId", + request=UpdateScoreConfigRequest(), + ) + + + asyncio.run(main()) + """ + _response = await self._client_wrapper.httpx_client.request( + f"api/public/score-configs/{jsonable_encoder(config_id)}", + method="PATCH", + json=request, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + return pydantic_v1.parse_obj_as(ScoreConfig, _response.json()) # type: ignore + if _response.status_code == 400: + raise Error(pydantic_v1.parse_obj_as(typing.Any, _response.json())) # type: ignore + if _response.status_code == 401: + raise UnauthorizedError( + pydantic_v1.parse_obj_as(typing.Any, _response.json()) + ) # type: ignore + if _response.status_code == 403: + raise AccessDeniedError( + pydantic_v1.parse_obj_as(typing.Any, _response.json()) + ) # type: ignore + if _response.status_code == 405: + raise MethodNotAllowedError( + pydantic_v1.parse_obj_as(typing.Any, _response.json()) + ) # type: ignore + if _response.status_code == 404: + raise NotFoundError( + pydantic_v1.parse_obj_as(typing.Any, _response.json()) + ) # type: ignore + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, body=_response.text) + raise ApiError(status_code=_response.status_code, body=_response_json) diff --git a/langfuse/api/resources/score_configs/types/__init__.py b/langfuse/api/resources/score_configs/types/__init__.py index 401650f2b..1c328b614 100644 --- a/langfuse/api/resources/score_configs/types/__init__.py +++ b/langfuse/api/resources/score_configs/types/__init__.py @@ -2,5 +2,6 @@ from .create_score_config_request import CreateScoreConfigRequest from .score_configs import ScoreConfigs +from .update_score_config_request import UpdateScoreConfigRequest -__all__ = ["CreateScoreConfigRequest", "ScoreConfigs"] +__all__ = ["CreateScoreConfigRequest", "ScoreConfigs", "UpdateScoreConfigRequest"] diff --git a/langfuse/api/resources/score_configs/types/update_score_config_request.py b/langfuse/api/resources/score_configs/types/update_score_config_request.py new file mode 100644 index 000000000..ce5f980b8 --- /dev/null +++ b/langfuse/api/resources/score_configs/types/update_score_config_request.py @@ -0,0 +1,81 @@ +# This file was auto-generated by Fern from our API Definition. + +import datetime as dt +import typing + +from ....core.datetime_utils import serialize_datetime +from ....core.pydantic_utilities import deep_union_pydantic_dicts, pydantic_v1 +from ...commons.types.config_category import ConfigCategory + + +class UpdateScoreConfigRequest(pydantic_v1.BaseModel): + is_archived: typing.Optional[bool] = pydantic_v1.Field( + alias="isArchived", default=None + ) + """ + The status of the score config showing if it is archived or not + """ + + name: typing.Optional[str] = pydantic_v1.Field(default=None) + """ + The name of the score config + """ + + categories: typing.Optional[typing.List[ConfigCategory]] = pydantic_v1.Field( + default=None + ) + """ + Configure custom categories for categorical scores. Pass a list of objects with `label` and `value` properties. Categories are autogenerated for boolean configs and cannot be passed + """ + + min_value: typing.Optional[float] = pydantic_v1.Field( + alias="minValue", default=None + ) + """ + Configure a minimum value for numerical scores. If not set, the minimum value defaults to -∞ + """ + + max_value: typing.Optional[float] = pydantic_v1.Field( + alias="maxValue", default=None + ) + """ + Configure a maximum value for numerical scores. If not set, the maximum value defaults to +∞ + """ + + description: typing.Optional[str] = pydantic_v1.Field(default=None) + """ + Description is shown across the Langfuse UI and can be used to e.g. explain the config categories in detail, why a numeric range was set, or provide additional context on config name or usage + """ + + def json(self, **kwargs: typing.Any) -> str: + kwargs_with_defaults: typing.Any = { + "by_alias": True, + "exclude_unset": True, + **kwargs, + } + return super().json(**kwargs_with_defaults) + + def dict(self, **kwargs: typing.Any) -> typing.Dict[str, typing.Any]: + kwargs_with_defaults_exclude_unset: typing.Any = { + "by_alias": True, + "exclude_unset": True, + **kwargs, + } + kwargs_with_defaults_exclude_none: typing.Any = { + "by_alias": True, + "exclude_none": True, + **kwargs, + } + + return deep_union_pydantic_dicts( + super().dict(**kwargs_with_defaults_exclude_unset), + super().dict(**kwargs_with_defaults_exclude_none), + ) + + class Config: + frozen = True + smart_union = True + allow_population_by_field_name = True + populate_by_name = True + extra = pydantic_v1.Extra.allow + json_encoders = {dt.datetime: serialize_datetime}