Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: update prompts and invalidate cache #1082

Merged
merged 17 commits into from
Jan 28, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions langfuse/api/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@
models,
observations,
projects,
prompt_version,
prompts,
score,
score_configs,
Expand Down Expand Up @@ -302,6 +303,7 @@
"models",
"observations",
"projects",
"prompt_version",
"prompts",
"score",
"score_configs",
Expand Down
8 changes: 8 additions & 0 deletions langfuse/api/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@
from .resources.models.client import AsyncModelsClient, ModelsClient
from .resources.observations.client import AsyncObservationsClient, ObservationsClient
from .resources.projects.client import AsyncProjectsClient, ProjectsClient
from .resources.prompt_version.client import (
AsyncPromptVersionClient,
PromptVersionClient,
)
from .resources.prompts.client import AsyncPromptsClient, PromptsClient
from .resources.score.client import AsyncScoreClient, ScoreClient
from .resources.score_configs.client import AsyncScoreConfigsClient, ScoreConfigsClient
Expand Down Expand Up @@ -108,6 +112,7 @@ def __init__(
self.models = ModelsClient(client_wrapper=self._client_wrapper)
self.observations = ObservationsClient(client_wrapper=self._client_wrapper)
self.projects = ProjectsClient(client_wrapper=self._client_wrapper)
self.prompt_version = PromptVersionClient(client_wrapper=self._client_wrapper)
self.prompts = PromptsClient(client_wrapper=self._client_wrapper)
self.score_configs = ScoreConfigsClient(client_wrapper=self._client_wrapper)
self.score = ScoreClient(client_wrapper=self._client_wrapper)
Expand Down Expand Up @@ -199,6 +204,9 @@ def __init__(
self.models = AsyncModelsClient(client_wrapper=self._client_wrapper)
self.observations = AsyncObservationsClient(client_wrapper=self._client_wrapper)
self.projects = AsyncProjectsClient(client_wrapper=self._client_wrapper)
self.prompt_version = AsyncPromptVersionClient(
client_wrapper=self._client_wrapper
)
self.prompts = AsyncPromptsClient(client_wrapper=self._client_wrapper)
self.score_configs = AsyncScoreConfigsClient(
client_wrapper=self._client_wrapper
Expand Down
100 changes: 96 additions & 4 deletions langfuse/api/reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -2237,6 +2237,100 @@ client.projects.get()
</dl>


</dd>
</dl>
</details>

## PromptVersion
<details><summary><code>client.prompt_version.<a href="src/langfuse/resources/prompt_version/client.py">update</a>(...)</code></summary>
<dl>
<dd>

#### 📝 Description

<dl>
<dd>

<dl>
<dd>

Update labels for a specific prompt version
</dd>
</dl>
</dd>
</dl>

#### 🔌 Usage

<dl>
<dd>

<dl>
<dd>

```python
from langfuse.client import FernLangfuse

client = FernLangfuse(
x_langfuse_sdk_name="YOUR_X_LANGFUSE_SDK_NAME",
x_langfuse_sdk_version="YOUR_X_LANGFUSE_SDK_VERSION",
x_langfuse_public_key="YOUR_X_LANGFUSE_PUBLIC_KEY",
username="YOUR_USERNAME",
password="YOUR_PASSWORD",
base_url="https://yourhost.com/path/to/api",
)
client.prompt_version.update(
name="string",
version=1,
new_labels=["string"],
)

```
</dd>
</dl>
</dd>
</dl>

#### ⚙️ Parameters

<dl>
<dd>

<dl>
<dd>

**name:** `str` — The name of the prompt

</dd>
</dl>

<dl>
<dd>

**version:** `int` — Version of the prompt to update

</dd>
</dl>

<dl>
<dd>

**new_labels:** `typing.Sequence[str]` — New labels for the prompt version. Labels are unique across versions. The "latest" label is reserved and managed by Langfuse.

</dd>
</dl>

<dl>
<dd>

**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.

</dd>
</dl>
</dd>
</dl>


</dd>
</dl>
</details>
Expand Down Expand Up @@ -2944,7 +3038,7 @@ client.score.get(
config_id="string",
queue_id="string",
data_type=ScoreDataType.NUMERIC,
trace_tags=["string"],
trace_tags="string",
)

```
Expand Down Expand Up @@ -3065,9 +3159,7 @@ client.score.get(
<dl>
<dd>

**trace_tags:** `typing.Optional[
typing.Union[typing.Sequence[str], typing.Sequence[typing.Sequence[str]]]
]` — Only scores linked to traces that include all of these tags will be returned.
**trace_tags:** `typing.Optional[typing.Union[str, typing.Sequence[str]]]` — Only scores linked to traces that include all of these tags will be returned.

</dd>
</dl>
Expand Down
2 changes: 2 additions & 0 deletions langfuse/api/resources/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
models,
observations,
projects,
prompt_version,
prompts,
score,
score_configs,
Expand Down Expand Up @@ -299,6 +300,7 @@
"models",
"observations",
"projects",
"prompt_version",
"prompts",
"score",
"score_configs",
Expand Down
2 changes: 2 additions & 0 deletions langfuse/api/resources/prompt_version/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# This file was auto-generated by Fern from our API Definition.

197 changes: 197 additions & 0 deletions langfuse/api/resources/prompt_version/client.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,197 @@
# This file was auto-generated by Fern from our API Definition.

import typing
from json.decoder import JSONDecodeError

from ...core.api_error import ApiError
from ...core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
from ...core.jsonable_encoder import jsonable_encoder
from ...core.pydantic_utilities import pydantic_v1
from ...core.request_options import RequestOptions
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 ..prompts.types.prompt import Prompt

# this is used as the default value for optional parameters
OMIT = typing.cast(typing.Any, ...)


class PromptVersionClient:
def __init__(self, *, client_wrapper: SyncClientWrapper):
self._client_wrapper = client_wrapper

def update(
self,
name: str,
version: int,
*,
new_labels: typing.Sequence[str],
request_options: typing.Optional[RequestOptions] = None,
) -> Prompt:
"""
Update labels for a specific prompt version

Parameters
----------
name : str
The name of the prompt

version : int
Version of the prompt to update

new_labels : typing.Sequence[str]
New labels for the prompt version. Labels are unique across versions. The "latest" label is reserved and managed by Langfuse.

request_options : typing.Optional[RequestOptions]
Request-specific configuration.

Returns
-------
Prompt

Examples
--------
from langfuse.client import FernLangfuse

client = FernLangfuse(
x_langfuse_sdk_name="YOUR_X_LANGFUSE_SDK_NAME",
x_langfuse_sdk_version="YOUR_X_LANGFUSE_SDK_VERSION",
x_langfuse_public_key="YOUR_X_LANGFUSE_PUBLIC_KEY",
username="YOUR_USERNAME",
password="YOUR_PASSWORD",
base_url="https://yourhost.com/path/to/api",
)
client.prompt_version.update(
name="string",
version=1,
new_labels=["string"],
)
"""
_response = self._client_wrapper.httpx_client.request(
f"api/public/v2/prompts/{jsonable_encoder(name)}/versions/{jsonable_encoder(version)}",
method="PATCH",
json={"newLabels": new_labels},
request_options=request_options,
omit=OMIT,
)
try:
if 200 <= _response.status_code < 300:
return pydantic_v1.parse_obj_as(Prompt, _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 AsyncPromptVersionClient:
def __init__(self, *, client_wrapper: AsyncClientWrapper):
self._client_wrapper = client_wrapper

async def update(
self,
name: str,
version: int,
*,
new_labels: typing.Sequence[str],
request_options: typing.Optional[RequestOptions] = None,
) -> Prompt:
"""
Update labels for a specific prompt version

Parameters
----------
name : str
The name of the prompt

version : int
Version of the prompt to update

new_labels : typing.Sequence[str]
New labels for the prompt version. Labels are unique across versions. The "latest" label is reserved and managed by Langfuse.

request_options : typing.Optional[RequestOptions]
Request-specific configuration.

Returns
-------
Prompt

Examples
--------
import asyncio

from langfuse.client import AsyncFernLangfuse

client = AsyncFernLangfuse(
x_langfuse_sdk_name="YOUR_X_LANGFUSE_SDK_NAME",
x_langfuse_sdk_version="YOUR_X_LANGFUSE_SDK_VERSION",
x_langfuse_public_key="YOUR_X_LANGFUSE_PUBLIC_KEY",
username="YOUR_USERNAME",
password="YOUR_PASSWORD",
base_url="https://yourhost.com/path/to/api",
)


async def main() -> None:
await client.prompt_version.update(
name="string",
version=1,
new_labels=["string"],
)


asyncio.run(main())
"""
_response = await self._client_wrapper.httpx_client.request(
f"api/public/v2/prompts/{jsonable_encoder(name)}/versions/{jsonable_encoder(version)}",
method="PATCH",
json={"newLabels": new_labels},
request_options=request_options,
omit=OMIT,
)
try:
if 200 <= _response.status_code < 300:
return pydantic_v1.parse_obj_as(Prompt, _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)
Loading
Loading