diff --git a/langfuse/_client/client.py b/langfuse/_client/client.py index a3f653ada..2b620e789 100644 --- a/langfuse/_client/client.py +++ b/langfuse/_client/client.py @@ -3775,6 +3775,35 @@ def update_prompt( return updated_prompt + def delete_prompt( + self, + name: str, + *, + label: Optional[str] = None, + version: Optional[int] = None, + ) -> None: + """Delete a prompt with all its versions or selected versions from Langfuse. + + The Langfuse SDK prompt cache is invalidated for all cached versions with the specified name. + + Args: + name: The name of the prompt to delete prompt versions for. If neither `label` nor `version` are specified, all prompt versions will be deleted. + label: Label of the prompt versions to delete. All prompt versions with the given label will be deleted. + version: Optional version of the prompt to delete. + + Raises: + NotFoundError: If the prompt does not exist. + Error: If the API request fails. + """ + self.api.prompts.delete( + prompt_name=self._url_encode(name), + label=label, + version=version, + ) + + if self._resources is not None: + self._resources.prompt_cache.invalidate(name) + def _url_encode(self, url: str, *, is_url_param: Optional[bool] = False) -> str: # httpx ≥ 0.28 does its own WHATWG-compliant quoting (eg. encodes bare # “%”, “?”, “#”, “|”, … in query/path parts). Re-quoting here would diff --git a/tests/test_prompt.py b/tests/test_prompt.py index bc3a5b7eb..7490fa843 100644 --- a/tests/test_prompt.py +++ b/tests/test_prompt.py @@ -682,7 +682,7 @@ def test_prompt_end_to_end(): @pytest.fixture def langfuse(): from langfuse._client.resource_manager import LangfuseResourceManager - + langfuse_instance = Langfuse() langfuse_instance.api = Mock() @@ -1485,6 +1485,36 @@ def test_update_prompt(): assert sorted(updated_prompt.labels) == expected_labels +def test_delete_prompt(): + """Test that deleting a prompt works and invalidates cache.""" + langfuse = Langfuse() + prompt_name = f"folder/subfolder/{create_uuid()}" + + langfuse.create_prompt( + name=prompt_name, + prompt="test prompt", + labels=["production"], + ) + + # Fetch to populate cache + cached_prompt = langfuse.get_prompt(prompt_name) + assert cached_prompt.prompt == "test prompt" + + cache_key = PromptCache.generate_cache_key( + prompt_name, version=None, label="production" + ) + assert langfuse._resources.prompt_cache.get(cache_key) is not None + + langfuse.delete_prompt(prompt_name) + + # Verify cache is invalidated + assert langfuse._resources.prompt_cache.get(cache_key) is None + + # Verify prompt is deleted from server + with pytest.raises(NotFoundError): + langfuse.get_prompt(prompt_name, cache_ttl_seconds=0) + + def test_update_prompt_in_folder(): langfuse = Langfuse() prompt_name = f"some-folder/{create_uuid()}"