diff --git a/README.md b/README.md index 465966e..3bc2db7 100644 --- a/README.md +++ b/README.md @@ -715,16 +715,20 @@ saved_prompt = client.prompts.save(prompt_url, prompt=prompt_payload) saved_prompt = await async_client.prompts.save(prompt_url, prompt=prompt_payload) ``` -As a result, you will receive a `PromptMetadata` object: +As a result, you will receive a `PromptItem` object: ```python -PromptMetadata( +PromptItem( name="my-prompt", parent_path="my-folder", bucket="my-bucket", url="prompts/my-bucket/my-folder/my-prompt", node_type="ITEM", resource_type="PROMPT", + etag="9749fad13d6e7092a6337c4af9d83764", + created_at=1724836229736, + updated_at=1724836248936, + author="user@example.com", ) ``` diff --git a/aidial_client/resources/prompts.py b/aidial_client/resources/prompts.py index f4088f9..94b1c2a 100644 --- a/aidial_client/resources/prompts.py +++ b/aidial_client/resources/prompts.py @@ -17,7 +17,7 @@ from aidial_client.helpers.storage_resource import DialStorageResourceMixin from aidial_client.resources.base import AsyncResource, Resource from aidial_client.resources.metadata import AsyncMetadata, Metadata -from aidial_client.types.metadata import PromptMetadata +from aidial_client.types.metadata import PromptItem, PromptMetadata from aidial_client.types.prompt import Prompt @@ -51,9 +51,9 @@ def save( prompt: Prompt, etag_if_match: str | None = None, etag_if_none_match: Literal["*"] | None = None, - ) -> PromptMetadata: + ) -> PromptItem: return self.http_client.request( - cast_to=PromptMetadata, + cast_to=PromptItem, options=FinalRequestOptions( method="PUT", url=urljoin(API_PREFIX, self.get_api_path(str(url))), @@ -115,9 +115,9 @@ async def save( prompt: Prompt, etag_if_match: str | None = None, etag_if_none_match: Literal["*"] | None = None, - ) -> PromptMetadata: + ) -> PromptItem: return await self.http_client.request( - cast_to=PromptMetadata, + cast_to=PromptItem, options=FinalRequestOptions( method="PUT", url=urljoin(API_PREFIX, self.get_api_path(str(url))), diff --git a/aidial_client/types/metadata.py b/aidial_client/types/metadata.py index ff033a7..d188d87 100644 --- a/aidial_client/types/metadata.py +++ b/aidial_client/types/metadata.py @@ -25,17 +25,20 @@ class Config: resource_type: Literal["FILE", "CONVERSATION", "PROMPT"] -class FileItem(BaseMetadata): - node_type: Literal["FOLDER", "ITEM"] - resource_type: Literal["FILE"] - content_length: int | None = None - content_type: str | None = None +class ResourceItemMetadata(BaseMetadata): created_at: int | None = None updated_at: int | None = None etag: str | None = None author: str | None = None +class FileItem(ResourceItemMetadata): + node_type: Literal["FOLDER", "ITEM"] + resource_type: Literal["FILE"] + content_length: int | None = None + content_type: str | None = None + + class FileMetadata(BaseMetadata): node_type: Literal["FOLDER", "ITEM"] resource_type: Literal["FILE"] @@ -46,8 +49,7 @@ class FileMetadata(BaseMetadata): etag: str | None = None -class ConversationItem(BaseMetadata): - updated_at: int +class ConversationItem(ResourceItemMetadata): resource_type: Literal["CONVERSATION"] @@ -58,8 +60,7 @@ class ConversationMetadata(BaseMetadata): resource_type: Literal["CONVERSATION"] -class PromptItem(BaseMetadata): - updated_at: int +class PromptItem(ResourceItemMetadata): resource_type: Literal["PROMPT"] diff --git a/tests/integration/test_async_prompts.py b/tests/integration/test_async_prompts.py index 81e3a5d..1ede0ec 100644 --- a/tests/integration/test_async_prompts.py +++ b/tests/integration/test_async_prompts.py @@ -5,7 +5,7 @@ from aidial_client import AsyncDial from aidial_client._exception import EtagMismatchError, ResourceNotFoundError -from aidial_client.types.metadata import PromptMetadata +from aidial_client.types.metadata import PromptItem from aidial_client.types.prompt import Prompt from tests.integration.fixtures import * # type: ignore # noqa @@ -26,7 +26,7 @@ def _create_prompt( return Prompt(id=url, name=name, folder_id=folder_id, content=content) -def _get_etag_or_skip(metadata: PromptMetadata) -> str: +def _get_etag_or_skip(metadata: PromptItem) -> str: etag = getattr(metadata, "etag", None) if not etag: pytest.skip("Prompt metadata does not include etag in this environment") @@ -44,7 +44,7 @@ async def test_save_get_delete(async_client: AsyncDial): save_result = await async_client.prompts.save( url=prompt_url, prompt=_create_prompt(prompt_url) ) - assert isinstance(save_result, PromptMetadata) + assert isinstance(save_result, PromptItem) assert save_result.node_type == "ITEM" assert save_result.bucket == await async_client.my_bucket() assert save_result.name == prompt_name diff --git a/tests/integration/test_sync_prompts.py b/tests/integration/test_sync_prompts.py index 78da5d0..55a17bd 100644 --- a/tests/integration/test_sync_prompts.py +++ b/tests/integration/test_sync_prompts.py @@ -5,7 +5,7 @@ from aidial_client import Dial from aidial_client._exception import EtagMismatchError, ResourceNotFoundError -from aidial_client.types.metadata import PromptMetadata +from aidial_client.types.metadata import PromptItem from aidial_client.types.prompt import Prompt from tests.integration.fixtures import * # type: ignore # noqa @@ -26,7 +26,7 @@ def _create_prompt( return Prompt(id=url, name=name, folder_id=folder_id, content=content) -def _get_etag_or_skip(metadata: PromptMetadata) -> str: +def _get_etag_or_skip(metadata: PromptItem) -> str: etag = getattr(metadata, "etag", None) if not etag: pytest.skip("Prompt metadata does not include etag in this environment") @@ -43,7 +43,7 @@ def test_save_get_delete(sync_client: Dial): save_result = sync_client.prompts.save( url=prompt_url, prompt=_create_prompt(prompt_url) ) - assert isinstance(save_result, PromptMetadata) + assert isinstance(save_result, PromptItem) assert save_result.node_type == "ITEM" assert save_result.bucket == sync_client.my_bucket() assert save_result.name == prompt_name diff --git a/tests/resources/test_prompts.py b/tests/resources/test_prompts.py index db994ae..13dbfbf 100644 --- a/tests/resources/test_prompts.py +++ b/tests/resources/test_prompts.py @@ -13,7 +13,7 @@ InvalidDialURLError, ResourceNotFoundError, ) -from aidial_client.types.metadata import PromptMetadata +from aidial_client.types.metadata import PromptItem, PromptMetadata from aidial_client.types.prompt import Prompt from tests.client_mock import get_async_client_mock, get_client_mock @@ -40,6 +40,19 @@ "items": [], } +PROMPT_ITEM_MOCK = { + "name": "my-prompt", + "parentPath": "my-folder", + "bucket": "test-bucket", + "url": "prompts/test-bucket/my-folder/my-prompt", + "nodeType": "ITEM", + "resourceType": "PROMPT", + "etag": "9749fad13d6e7092a6337c4af9d83764", + "createdAt": 1724836229736, + "updatedAt": 1724836248936, + "author": "user@example.com", +} + def _make_capturing_client(captured: list[httpx.Request]) -> Dial: client = Dial(api_key="dummy", base_url="http://dial.core") @@ -189,32 +202,38 @@ async def test_async_get_prompt_metadata(): def test_save_prompt(): - client = get_client_mock(status_code=200, json_mock=PROMPT_METADATA_MOCK) + client = get_client_mock(status_code=200, json_mock=PROMPT_ITEM_MOCK) prompt = Prompt(**PROMPT_MOCK) result = client.prompts.save( "prompts/test-bucket/my-folder/my-prompt", prompt=prompt ) - assert isinstance(result, PromptMetadata) + assert isinstance(result, PromptItem) assert result.node_type == "ITEM" assert result.bucket == "test-bucket" + assert result.etag == "9749fad13d6e7092a6337c4af9d83764" + assert result.created_at == 1724836229736 + assert result.updated_at == 1724836248936 + assert result.author == "user@example.com" @pytest.mark.asyncio async def test_async_save_prompt(): - client = get_async_client_mock( - status_code=200, json_mock=PROMPT_METADATA_MOCK - ) + client = get_async_client_mock(status_code=200, json_mock=PROMPT_ITEM_MOCK) prompt = Prompt(**PROMPT_MOCK) result = await client.prompts.save( "prompts/test-bucket/my-folder/my-prompt", prompt=prompt ) - assert isinstance(result, PromptMetadata) + assert isinstance(result, PromptItem) assert result.node_type == "ITEM" assert result.bucket == "test-bucket" + assert result.etag == "9749fad13d6e7092a6337c4af9d83764" + assert result.created_at == 1724836229736 + assert result.updated_at == 1724836248936 + assert result.author == "user@example.com" def test_save_prompt_sends_json_and_etag_headers(): @@ -229,7 +248,7 @@ def test_save_prompt_sends_json_and_etag_headers(): etag_if_none_match="*", ) - assert isinstance(result, PromptMetadata) + assert isinstance(result, PromptItem) assert len(captured) == 1 request = captured[0] assert request.method == "PUT" @@ -257,7 +276,7 @@ async def test_async_save_prompt_sends_json_and_etag_headers(): etag_if_none_match="*", ) - assert isinstance(result, PromptMetadata) + assert isinstance(result, PromptItem) assert len(captured) == 1 request = captured[0] assert request.method == "PUT"