9090 SaveSemantic ,
9191)
9292from pyatlan_v9 .model .aggregation import Aggregations
93+ from pyatlan_v9 .model .aio .core import AsyncAtlanRequest
9394from pyatlan_v9 .model .core import (
9495 Announcement ,
9596 AssetRequest ,
@@ -307,6 +308,15 @@ def _make_bulk_request_payload(entities: list, client) -> dict:
307308 return retranslated .translated
308309
309310
311+ async def _make_bulk_request_payload_async (entities : list , client ) -> dict :
312+ """Async version: serialize entities into API-ready dict with tag retranslation."""
313+ bulk = BulkRequest (entities = entities )
314+ request_dict = bulk .to_dict ()
315+ async_request = AsyncAtlanRequest (instance = request_dict , client = client )
316+ await async_request .retranslate ()
317+ return async_request .translated
318+
319+
310320def _make_asset_request_payload (asset : Asset , client ) -> dict :
311321 """Serialize a single Asset entity into an API-ready dict,
312322 applying AtlanTag retranslation.
@@ -316,6 +326,14 @@ def _make_asset_request_payload(asset: Asset, client) -> dict:
316326 return retranslated .translated
317327
318328
329+ async def _make_asset_request_payload_async (asset : Asset , client ) -> dict :
330+ """Async version: serialize a single Asset entity into API-ready dict."""
331+ asset_dict = {"entity" : json .loads (asset .to_json (nested = True ))}
332+ async_request = AsyncAtlanRequest (instance = asset_dict , client = client )
333+ await async_request .retranslate ()
334+ return async_request .translated
335+
336+
319337# ---------------------------------------------------------------------------
320338# V9 Async Asset Client (standalone)
321339# ---------------------------------------------------------------------------
@@ -401,6 +419,44 @@ async def get_lineage_list(
401419 # Find by name helpers
402420 # ------------------------------------------------------------------
403421
422+ def _prepare_fluent_search (
423+ self ,
424+ wheres : List [Query ],
425+ attributes : Optional [List [str ]] = None ,
426+ related_attributes : Optional [List [str ]] = None ,
427+ ):
428+ from pyatlan_v9 .model .fluent_search import FluentSearch
429+
430+ search = FluentSearch ()
431+ for w in wheres :
432+ search = search .where (w )
433+ for attr in attributes or []:
434+ search = search .include_on_results (attr )
435+ for rel_attr in related_attributes or []:
436+ search = search .include_on_relations (rel_attr )
437+ return search
438+
439+ def _build_find_request (
440+ self ,
441+ name : str ,
442+ type_name : str ,
443+ attributes : Optional [List [str ]] = None ,
444+ ) -> IndexSearchRequest :
445+ from pyatlan .model .search import Term
446+ from pyatlan_v9 .model .search import DSL as V9DSL
447+
448+ if attributes is None :
449+ attributes = []
450+ query = (
451+ Term .with_state ("ACTIVE" )
452+ + Term .with_type_name (type_name )
453+ + Term .with_name (name )
454+ )
455+ dsl = V9DSL (query = query )
456+ return IndexSearchRequest (
457+ dsl = dsl , attributes = attributes , relation_attributes = ["name" ]
458+ )
459+
404460 @validate_arguments
405461 async def find_personas_by_name (
406462 self ,
@@ -415,7 +471,7 @@ async def find_personas_by_name(
415471 :returns: all personas with that name, if found
416472 :raises NotFoundError: if no persona with the provided name exists
417473 """
418- search_request = FindPersonasByName . prepare_request (name , attributes )
474+ search_request = self . _build_find_request (name , "PERSONA" , attributes )
419475 search_results = await self .search (search_request )
420476 return FindPersonasByName .process_response (
421477 search_results , name , allow_multiple = True
@@ -435,7 +491,7 @@ async def find_purposes_by_name(
435491 :returns: all purposes with that name, if found
436492 :raises NotFoundError: if no purpose with the provided name exists
437493 """
438- search_request = FindPurposesByName . prepare_request (name , attributes )
494+ search_request = self . _build_find_request (name , "PURPOSE" , attributes )
439495 search_results = await self .search (search_request )
440496 return FindPurposesByName .process_response (
441497 search_results , name , allow_multiple = True
@@ -476,11 +532,13 @@ async def get_by_qualified_name(
476532 if (normalized_attributes and len (normalized_attributes )) or (
477533 normalized_related_attributes and len (normalized_related_attributes )
478534 ):
479- search = GetByQualifiedName .prepare_fluent_search_request (
480- qualified_name ,
481- asset_type ,
482- normalized_attributes ,
483- normalized_related_attributes ,
535+ search = self ._prepare_fluent_search (
536+ wheres = [
537+ Asset .QUALIFIED_NAME .eq (qualified_name ),
538+ Asset .TYPE_NAME .eq (asset_type .__name__ ),
539+ ],
540+ attributes = normalized_attributes ,
541+ related_attributes = normalized_related_attributes ,
484542 )
485543 results = await search .execute_async (client = self ._client )
486544 if results and results .current_page ():
@@ -533,8 +591,13 @@ async def get_by_guid(
533591 if (normalized_attributes and len (normalized_attributes )) or (
534592 normalized_related_attributes and len (normalized_related_attributes )
535593 ):
536- search = GetByGuid .prepare_fluent_search_request (
537- guid , asset_type , normalized_attributes , normalized_related_attributes
594+ search = self ._prepare_fluent_search (
595+ wheres = [
596+ Asset .GUID .eq (guid ),
597+ Asset .TYPE_NAME .eq (asset_type .__name__ ),
598+ ],
599+ attributes = normalized_attributes ,
600+ related_attributes = normalized_related_attributes ,
538601 )
539602 results = await search .execute_async (client = self ._client )
540603 if results and results .current_page ():
@@ -638,8 +701,10 @@ async def save(
638701 asset .validate_required ()
639702 await asset .flush_custom_metadata_async (client = self ._client )
640703
641- request = BulkRequest (entities = entities )
642- raw_json = await self ._client ._call_api (BULK_UPDATE , query_params , request )
704+ request_payload = await _make_bulk_request_payload_async (
705+ entities , self ._client
706+ )
707+ raw_json = await self ._client ._call_api (BULK_UPDATE , query_params , request_payload )
643708 response = _parse_mutation_response (raw_json )
644709
645710 if connections_created := response .assets_created (Connection ):
@@ -766,8 +831,10 @@ async def save_replacing_cm(
766831 asset .validate_required ()
767832 await asset .flush_custom_metadata_async (self ._client )
768833
769- request = BulkRequest (entities = entities )
770- raw_json = await self ._client ._call_api (BULK_UPDATE , query_params , request )
834+ request_payload = await _make_bulk_request_payload_async (
835+ entities , self ._client
836+ )
837+ raw_json = await self ._client ._call_api (BULK_UPDATE , query_params , request_payload )
771838 return _parse_mutation_response (raw_json )
772839
773840 @validate_arguments
@@ -910,8 +977,10 @@ async def _restore_asset(self, asset: Asset) -> AssetMutationResponse:
910977 for restored in entities :
911978 await restored .flush_custom_metadata_async (self ._client )
912979
913- request = BulkRequest (entities = entities )
914- raw_json = await self ._client ._call_api (BULK_UPDATE , query_params , request )
980+ request_payload = await _make_bulk_request_payload_async (
981+ entities , self ._client
982+ )
983+ raw_json = await self ._client ._call_api (BULK_UPDATE , query_params , request_payload )
915984 return _parse_mutation_response (raw_json )
916985
917986 # ------------------------------------------------------------------
@@ -1436,7 +1505,14 @@ async def _search_for_asset_with_name(
14361505 attributes : Optional [List ],
14371506 allow_multiple : bool = False ,
14381507 ) -> List [A ]:
1439- search_request = SearchForAssetWithName .build_search_request (query , attributes )
1508+ from pyatlan_v9 .model .search import DSL as V9DSL
1509+
1510+ dsl = V9DSL (query = query )
1511+ search_request = IndexSearchRequest (
1512+ dsl = dsl ,
1513+ attributes = attributes or [],
1514+ relation_attributes = ["name" ],
1515+ )
14401516 results = await self .search (search_request )
14411517 return await SearchForAssetWithName .process_async_search_results (
14421518 results , name , asset_type , allow_multiple
@@ -1450,17 +1526,27 @@ async def _manage_terms(
14501526 guid : Optional [str ] = None ,
14511527 qualified_name : Optional [str ] = None ,
14521528 ) -> A :
1529+ from pyatlan_v9 .model .fluent_search import FluentSearch
1530+
14531531 ManageTerms .validate_guid_and_qualified_name (guid , qualified_name )
14541532
14551533 if guid :
1456- search_query = ManageTerms .build_fluent_search_by_guid (asset_type , guid )
1534+ search_query = (
1535+ FluentSearch ()
1536+ .select ()
1537+ .where (Asset .TYPE_NAME .eq (asset_type .__name__ ))
1538+ .where (asset_type .GUID .eq (guid ))
1539+ )
14571540 else :
14581541 if qualified_name is None :
14591542 raise ValueError (
14601543 "qualified_name cannot be None when guid is not provided"
14611544 )
1462- search_query = ManageTerms .build_fluent_search_by_qualified_name (
1463- asset_type , qualified_name
1545+ search_query = (
1546+ FluentSearch ()
1547+ .select ()
1548+ .where (Asset .TYPE_NAME .eq (asset_type .__name__ ))
1549+ .where (asset_type .QUALIFIED_NAME .eq (qualified_name ))
14641550 )
14651551
14661552 results = await search_query .execute_async (client = self ._client )
0 commit comments