diff --git a/promptlayer/__init__.py b/promptlayer/__init__.py index b0c9806..a4bd6b4 100644 --- a/promptlayer/__init__.py +++ b/promptlayer/__init__.py @@ -16,7 +16,7 @@ ) from .promptlayer import AsyncPromptLayer, PromptLayer -__version__ = "1.4.0" +__version__ = "1.4.1" __all__ = [ "PromptLayer", "AsyncPromptLayer", diff --git a/promptlayer/promptlayer.py b/promptlayer/promptlayer.py index c218894..12cbf7e 100644 --- a/promptlayer/promptlayer.py +++ b/promptlayer/promptlayer.py @@ -85,6 +85,10 @@ def __init__( ) self.track = TrackManager(api_key, self.base_url, self.throw_on_error) + def invalidate(self, prompt_name: Optional[str] = None) -> None: + """Invalidate SDK template cache for a prompt or entirely.""" + self.templates.invalidate(prompt_name) + def __getattr__( self, name: Union[Literal["openai"], Literal["anthropic"], Literal["prompts"]], @@ -468,6 +472,10 @@ def __init__( ) self.track = AsyncTrackManager(api_key, self.base_url, self.throw_on_error) + def invalidate(self, prompt_name: Optional[str] = None) -> None: + """Invalidate SDK template cache for a prompt or entirely.""" + self.templates.invalidate(prompt_name) + def __getattr__(self, name: Union[Literal["openai"], Literal["anthropic"], Literal["prompts"]]): if name == "openai": import openai as openai_module diff --git a/promptlayer/templates.py b/promptlayer/templates.py index 025803f..5e2cbc2 100644 --- a/promptlayer/templates.py +++ b/promptlayer/templates.py @@ -1,5 +1,5 @@ import logging -from typing import Union +from typing import Optional, Union from promptlayer import exceptions as _exceptions from promptlayer.span_exporter import set_prompt_span_attributes @@ -112,6 +112,14 @@ def publish(self, body: PublishPromptTemplate): self._cache.invalidate(prompt_name) return result + def invalidate(self, prompt_name: Optional[str] = None) -> None: + if not self._cache: + return + if prompt_name: + self._cache.invalidate(prompt_name) + else: + self._cache.clear() + def all(self, page: int = 1, per_page: int = 30, label: str = None): return get_all_prompt_templates(self.api_key, self.base_url, self.throw_on_error, page, per_page, label) @@ -188,3 +196,11 @@ async def _aget_with_cache(self, prompt_name, params): async def all(self, page: int = 1, per_page: int = 30, label: str = None): return await aget_all_prompt_templates(self.api_key, self.base_url, self.throw_on_error, page, per_page, label) + + def invalidate(self, prompt_name: Optional[str] = None) -> None: + if not self._cache: + return + if prompt_name: + self._cache.invalidate(prompt_name) + else: + self._cache.clear() diff --git a/pyproject.toml b/pyproject.toml index 309e49c..039ce3a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "promptlayer" -version = "1.4.0" +version = "1.4.1" description = "PromptLayer is a platform for prompt engineering and tracks your LLM requests." authors = ["Magniv "] license = "Apache-2.0" diff --git a/tests/test_client_cache_invalidation.py b/tests/test_client_cache_invalidation.py new file mode 100644 index 0000000..4235df7 --- /dev/null +++ b/tests/test_client_cache_invalidation.py @@ -0,0 +1,48 @@ +from promptlayer import AsyncPromptLayer, PromptLayer + + +def test_promptlayer_client_invalidate_prompt_name(promptlayer_api_key, base_url): + client = PromptLayer(api_key=promptlayer_api_key, base_url=base_url, cache_ttl_seconds=60) + cache = client.templates._cache + + alpha_key = cache.make_key("alpha") + beta_key = cache.make_key("beta") + cache.put(alpha_key, {"prompt_template": {"type": "chat", "messages": []}}) + cache.put(beta_key, {"prompt_template": {"type": "chat", "messages": []}}) + + client.invalidate("alpha") + + alpha_cached, _ = cache.get(alpha_key) + beta_cached, _ = cache.get(beta_key) + assert alpha_cached is None + assert beta_cached is not None + + +def test_promptlayer_client_invalidate_all(promptlayer_api_key, base_url): + client = PromptLayer(api_key=promptlayer_api_key, base_url=base_url, cache_ttl_seconds=60) + cache = client.templates._cache + + first_key = cache.make_key("first") + second_key = cache.make_key("second") + cache.put(first_key, {"prompt_template": {"type": "chat", "messages": []}}) + cache.put(second_key, {"prompt_template": {"type": "chat", "messages": []}}) + + client.invalidate() + + first_cached, _ = cache.get(first_key) + second_cached, _ = cache.get(second_key) + assert first_cached is None + assert second_cached is None + + +def test_async_promptlayer_client_invalidate(promptlayer_api_key, base_url): + client = AsyncPromptLayer(api_key=promptlayer_api_key, base_url=base_url, cache_ttl_seconds=60) + cache = client.templates._cache + + key = cache.make_key("async-template") + cache.put(key, {"prompt_template": {"type": "chat", "messages": []}}) + + client.invalidate("async-template") + + cached, _ = cache.get(key) + assert cached is None