Skip to content

Commit 535e9c5

Browse files
authored
chore(llma): apply prompt SDK review cleanups (#456)
* chore(llma): apply prompt SDK review cleanups * chore(llma): add review cleanup changeset
1 parent 11466c6 commit 535e9c5

3 files changed

Lines changed: 60 additions & 61 deletions

File tree

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
pypi/posthog: patch
3+
---
4+
5+
chore(llma): clean up prompt SDK review follow-ups

posthog/ai/prompts.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,12 @@ def _cache_key(name: str, version: Optional[int]) -> PromptCacheKey:
3535
return (name, version)
3636

3737

38-
def _prompt_reference(name: str, version: Optional[int]) -> str:
38+
def _prompt_reference(
39+
name: str, version: Optional[int], *, capitalize: bool = False
40+
) -> str:
3941
"""Format a prompt reference for logs and errors."""
40-
label = f'prompt "{name}"'
42+
prefix = "Prompt" if capitalize else "prompt"
43+
label = f'{prefix} "{name}"'
4144
if version is not None:
4245
return f"{label} version {version}"
4346
return label
@@ -291,7 +294,7 @@ def _fetch_prompt_from_api(self, name: str, version: Optional[int] = None) -> st
291294
encoded_query = urllib.parse.urlencode(query_params)
292295
url = f"{self._host}/api/environments/@current/llm_prompts/name/{encoded_name}/?{encoded_query}"
293296
prompt_reference = _prompt_reference(name, version)
294-
prompt_label = prompt_reference[:1].upper() + prompt_reference[1:]
297+
prompt_label = _prompt_reference(name, version, capitalize=True)
295298

296299
headers = {
297300
"Authorization": f"Bearer {self._personal_api_key}",

posthog/test/ai/test_prompts.py

Lines changed: 49 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import unittest
22
from unittest.mock import MagicMock, patch
33

4+
from parameterized import parameterized
5+
46
from posthog.ai.prompts import Prompts
57

68

@@ -256,36 +258,31 @@ def test_throw_when_no_cache_no_fallback_and_fetch_fails(self, mock_get_session)
256258

257259
self.assertIn("Network error", str(context.exception))
258260

261+
@parameterized.expand(
262+
[
263+
("latest", {}, 'Prompt "nonexistent-prompt" not found'),
264+
(
265+
"versioned",
266+
{"version": 3},
267+
'Prompt "nonexistent-prompt" version 3 not found',
268+
),
269+
]
270+
)
259271
@patch("posthog.ai.prompts._get_session")
260-
def test_handle_404_response(self, mock_get_session):
261-
"""Should handle 404 response."""
262-
mock_get = mock_get_session.return_value.get
263-
mock_get.return_value = MockResponse(status_code=404, ok=False)
264-
265-
posthog = self.create_mock_posthog()
266-
prompts = Prompts(posthog)
267-
268-
with self.assertRaises(Exception) as context:
269-
prompts.get("nonexistent-prompt")
270-
271-
self.assertIn('Prompt "nonexistent-prompt" not found', str(context.exception))
272-
273-
@patch("posthog.ai.prompts._get_session")
274-
def test_handle_404_response_for_specific_prompt_version(self, mock_get_session):
275-
"""Should handle 404 response for a specific prompt version."""
272+
def test_handle_404_response(
273+
self, _scenario, get_kwargs, expected_message, mock_get_session
274+
):
275+
"""Should handle 404 responses for latest and versioned prompts."""
276276
mock_get = mock_get_session.return_value.get
277277
mock_get.return_value = MockResponse(status_code=404, ok=False)
278278

279279
posthog = self.create_mock_posthog()
280280
prompts = Prompts(posthog)
281281

282282
with self.assertRaises(Exception) as context:
283-
prompts.get("nonexistent-prompt", version=3)
283+
prompts.get("nonexistent-prompt", **get_kwargs)
284284

285-
self.assertIn(
286-
'Prompt "nonexistent-prompt" version 3 not found',
287-
str(context.exception),
288-
)
285+
self.assertIn(expected_message, str(context.exception))
289286

290287
@patch("posthog.ai.prompts._get_session")
291288
def test_handle_403_response(self, mock_get_session):
@@ -618,6 +615,28 @@ def test_handle_variables_with_dots(self):
618615
class TestPromptsClearCache(TestPrompts):
619616
"""Tests for the Prompts.clear_cache() method."""
620617

618+
def _populate_versioned_cache(self, prompts, mock_get):
619+
"""Populate cache with latest and versioned entries for the same prompt."""
620+
latest_prompt_response = {
621+
**self.mock_prompt_response,
622+
"prompt": "Latest prompt",
623+
"version": 2,
624+
}
625+
versioned_prompt_response = {
626+
**self.mock_prompt_response,
627+
"prompt": "Prompt version 1",
628+
"version": 1,
629+
}
630+
mock_get.side_effect = [
631+
MockResponse(json_data=latest_prompt_response),
632+
MockResponse(json_data=versioned_prompt_response),
633+
]
634+
635+
prompts.get("test-prompt")
636+
prompts.get("test-prompt", version=1)
637+
638+
return latest_prompt_response, versioned_prompt_response
639+
621640
def test_clear_cache_with_version_and_no_name_raises_value_error(self):
622641
"""Should enforce that versioned cache clearing requires a prompt name."""
623642
posthog = self.create_mock_posthog()
@@ -663,30 +682,14 @@ def test_clear_a_specific_prompt_from_cache(self, mock_get_session):
663682
def test_clear_a_specific_prompt_version_from_cache(self, mock_get_session):
664683
"""Should clear only the requested prompt version from cache."""
665684
mock_get = mock_get_session.return_value.get
666-
latest_prompt_response = {
667-
**self.mock_prompt_response,
668-
"prompt": "Latest prompt",
669-
"version": 2,
670-
}
671-
versioned_prompt_response = {
672-
**self.mock_prompt_response,
673-
"prompt": "Prompt version 1",
674-
"version": 1,
675-
}
676-
677-
mock_get.side_effect = [
678-
MockResponse(json_data=latest_prompt_response),
679-
MockResponse(json_data=versioned_prompt_response),
680-
MockResponse(json_data=versioned_prompt_response),
681-
]
682685

683686
posthog = self.create_mock_posthog()
684687
prompts = Prompts(posthog)
685688

686-
prompts.get("test-prompt")
687-
prompts.get("test-prompt", version=1)
689+
_, versioned_prompt_response = self._populate_versioned_cache(prompts, mock_get)
688690
self.assertEqual(mock_get.call_count, 2)
689691

692+
mock_get.side_effect = [MockResponse(json_data=versioned_prompt_response)]
690693
prompts.clear_cache("test-prompt", version=1)
691694

692695
prompts.get("test-prompt")
@@ -699,31 +702,19 @@ def test_clear_a_specific_prompt_version_from_cache(self, mock_get_session):
699702
def test_clear_a_prompt_name_clears_all_cached_versions(self, mock_get_session):
700703
"""Should clear latest and versioned cache entries for the same prompt name."""
701704
mock_get = mock_get_session.return_value.get
702-
latest_prompt_response = {
703-
**self.mock_prompt_response,
704-
"prompt": "Latest prompt",
705-
"version": 2,
706-
}
707-
versioned_prompt_response = {
708-
**self.mock_prompt_response,
709-
"prompt": "Prompt version 1",
710-
"version": 1,
711-
}
712-
713-
mock_get.side_effect = [
714-
MockResponse(json_data=latest_prompt_response),
715-
MockResponse(json_data=versioned_prompt_response),
716-
MockResponse(json_data=latest_prompt_response),
717-
MockResponse(json_data=versioned_prompt_response),
718-
]
719705

720706
posthog = self.create_mock_posthog()
721707
prompts = Prompts(posthog)
722708

723-
prompts.get("test-prompt")
724-
prompts.get("test-prompt", version=1)
709+
latest_prompt_response, versioned_prompt_response = (
710+
self._populate_versioned_cache(prompts, mock_get)
711+
)
725712
self.assertEqual(mock_get.call_count, 2)
726713

714+
mock_get.side_effect = [
715+
MockResponse(json_data=latest_prompt_response),
716+
MockResponse(json_data=versioned_prompt_response),
717+
]
727718
prompts.clear_cache("test-prompt")
728719

729720
prompts.get("test-prompt")

0 commit comments

Comments
 (0)