33
44import dataclasses
55from datetime import datetime
6- from typing import TYPE_CHECKING , Any , AsyncIterator , Iterator , TypeVar
6+ from typing import TYPE_CHECKING , Any , AsyncIterator , Iterator , TypeVar , cast
77
8- from typing_extensions import Self
8+ from typing_extensions import Self , TypeAlias
99from yandex .cloud .ai .assistants .v1 .searchindex .search_index_file_pb2 import SearchIndexFile as ProtoSearchIndexFile
1010from yandex .cloud .ai .assistants .v1 .searchindex .search_index_file_service_pb2 import (
11- GetSearchIndexFileRequest , ListSearchIndexFilesRequest , ListSearchIndexFilesResponse
11+ BatchCreateSearchIndexFileRequest , BatchCreateSearchIndexFileResponse , GetSearchIndexFileRequest ,
12+ ListSearchIndexFilesRequest , ListSearchIndexFilesResponse
1213)
1314from yandex .cloud .ai .assistants .v1 .searchindex .search_index_file_service_pb2_grpc import SearchIndexFileServiceStub
1415from yandex .cloud .ai .assistants .v1 .searchindex .search_index_pb2 import SearchIndex as ProtoSearchIndex
1516from yandex .cloud .ai .assistants .v1 .searchindex .search_index_service_pb2 import (
1617 DeleteSearchIndexRequest , DeleteSearchIndexResponse , UpdateSearchIndexRequest
1718)
1819from yandex .cloud .ai .assistants .v1 .searchindex .search_index_service_pb2_grpc import SearchIndexServiceStub
20+ from yandex .cloud .operation .operation_pb2 import Operation as ProtoOperation
1921
22+ from yandex_cloud_ml_sdk ._files .file import BaseFile
2023from yandex_cloud_ml_sdk ._types .expiration import ExpirationConfig , ExpirationPolicyAlias
2124from yandex_cloud_ml_sdk ._types .misc import UNDEFINED , UndefinedOr , get_defined_value
25+ from yandex_cloud_ml_sdk ._types .operation import AsyncOperation , Operation , OperationTypeT , ReturnsOperationMixin
2226from yandex_cloud_ml_sdk ._types .resource import ExpirableResource , safe_on_delete
2327from yandex_cloud_ml_sdk ._types .result import BaseResult
28+ from yandex_cloud_ml_sdk ._utils .coerce import ResourceType , coerce_resource_ids
2429from yandex_cloud_ml_sdk ._utils .sync import run_sync , run_sync_generator
2530
2631from .file import SearchIndexFile
3035 from yandex_cloud_ml_sdk ._sdk import BaseSDK
3136
3237
38+ SearchIndexFileTuple : TypeAlias = tuple [SearchIndexFile , ...]
39+
40+
3341@dataclasses .dataclass (frozen = True )
34- class BaseSearchIndex (ExpirableResource , BaseResult ):
42+ class BaseSearchIndex (ExpirableResource , BaseResult , ReturnsOperationMixin [ OperationTypeT ] ):
3543 @classmethod
3644 def _kwargs_from_message (cls , proto : ProtoSearchIndex , sdk : BaseSDK ) -> dict [str , Any ]: # type: ignore[override]
3745 kwargs = super ()._kwargs_from_message (proto , sdk = sdk )
@@ -128,6 +136,42 @@ async def _get_file(
128136
129137 return SearchIndexFile ._from_proto (proto = response , sdk = self ._sdk )
130138
139+ # pylint: disable=unused-argument
140+ async def _transform_add_files (self , proto : BatchCreateSearchIndexFileResponse , timeout : float ) -> SearchIndexFileTuple :
141+ return tuple (
142+ SearchIndexFile ._from_proto (proto = f , sdk = self ._sdk )
143+ for f in proto .files
144+ )
145+
146+ @safe_on_delete
147+ async def _add_files_deferred (
148+ self ,
149+ files : ResourceType [BaseFile ],
150+ * ,
151+ timeout : float = 60 ,
152+ ) -> OperationTypeT :
153+ file_ids = coerce_resource_ids (files , BaseFile )
154+ request = BatchCreateSearchIndexFileRequest (
155+ file_ids = file_ids ,
156+ search_index_id = self .id
157+ )
158+
159+ async with self ._client .get_service_stub (SearchIndexFileServiceStub , timeout = timeout ) as stub :
160+ response = await self ._client .call_service (
161+ stub .BatchCreate ,
162+ request ,
163+ timeout = timeout ,
164+ expected_type = ProtoOperation
165+ )
166+
167+ return self ._operation_impl (
168+ id = response .id ,
169+ sdk = self ._sdk ,
170+ proto_result_type = BatchCreateSearchIndexFileResponse ,
171+ result_type = SearchIndexFileTuple ,
172+ transformer = self ._transform_add_files
173+ )
174+
131175 async def _list_files (
132176 self ,
133177 * ,
@@ -161,7 +205,7 @@ async def _list_files(
161205
162206
163207@dataclasses .dataclass (frozen = True )
164- class RichSearchIndex (BaseSearchIndex ):
208+ class RichSearchIndex (BaseSearchIndex [ OperationTypeT ] ):
165209 folder_id : str
166210 name : str | None
167211 description : str | None
@@ -174,7 +218,9 @@ class RichSearchIndex(BaseSearchIndex):
174218 index_type : BaseSearchIndexType
175219
176220
177- class AsyncSearchIndex (RichSearchIndex ):
221+ class AsyncSearchIndex (RichSearchIndex [AsyncOperation [SearchIndexFileTuple ]]):
222+ _operation_impl = AsyncOperation [SearchIndexFileTuple ]
223+
178224 async def update (
179225 self ,
180226 * ,
@@ -224,12 +270,26 @@ async def list_files(
224270 ):
225271 yield file
226272
273+ async def add_files_deferred (
274+ self ,
275+ files : ResourceType [BaseFile ],
276+ * ,
277+ timeout : float = 60 ,
278+ ) -> AsyncOperation [SearchIndexFileTuple ]:
279+ return await self ._add_files_deferred (
280+ files = files ,
281+ timeout = timeout
282+ )
283+
227284
228- class SearchIndex (RichSearchIndex ):
285+ # pylint: disable=protected-access
286+ class SearchIndex (RichSearchIndex [Operation [SearchIndexFileTuple ]]):
287+ _operation_impl = Operation [SearchIndexFileTuple ]
229288 __update = run_sync (RichSearchIndex ._update )
230289 __delete = run_sync (RichSearchIndex ._delete )
231290 __get_file = run_sync (RichSearchIndex ._get_file )
232291 __list_files = run_sync_generator (RichSearchIndex ._list_files )
292+ __add_files_deferred = run_sync (RichSearchIndex ._add_files_deferred )
233293
234294 def update (
235295 self ,
@@ -279,5 +339,17 @@ def list_files(
279339 timeout = timeout ,
280340 )
281341
342+ def add_files_deferred (
343+ self ,
344+ files : ResourceType [BaseFile ],
345+ * ,
346+ timeout : float = 60 ,
347+ ) -> Operation [SearchIndexFileTuple ]:
348+ # mypy is going crazy as always, with run_sync over generic
349+ return cast (
350+ Operation [SearchIndexFileTuple ],
351+ self .__add_files_deferred (files = files , timeout = timeout )
352+ )
353+
282354
283355SearchIndexTypeT = TypeVar ('SearchIndexTypeT' , bound = BaseSearchIndex )
0 commit comments