6161from pyatlan .utils import unflatten_custom_metadata_for_entity
6262
6363if TYPE_CHECKING :
64+ from pyatlan .client .aio import AsyncAtlanClient
65+ from pyatlan .client .atlan import AtlanClient
6466 from pyatlan .model .fluent_search import FluentSearch
6567
6668LOGGER = logging .getLogger (__name__ )
@@ -676,6 +678,7 @@ def prepare_request(
676678 replace_custom_metadata : bool = False ,
677679 overwrite_custom_metadata : bool = False ,
678680 append_atlan_tags : bool = False ,
681+ client : Optional [AtlanClient ] = None ,
679682 ) -> tuple [Dict [str , Any ], BulkRequest [Asset ]]:
680683 """
681684 Prepare the request for saving assets.
@@ -685,6 +688,48 @@ def prepare_request(
685688 :param replace_custom_metadata: replaces any custom metadata with non-empty values provided
686689 :param overwrite_custom_metadata: overwrites any custom metadata, even with empty values
687690 :param append_atlan_tags: whether to add/update/remove AtlanTags during an update
691+ :param client: the Atlan client instance for flushing custom metadata
692+ :returns: tuple of (query_params, bulk_request)
693+ """
694+ query_params = {
695+ "replaceTags" : replace_atlan_tags ,
696+ "appendTags" : append_atlan_tags ,
697+ "replaceBusinessAttributes" : replace_custom_metadata ,
698+ "overwriteBusinessAttributes" : overwrite_custom_metadata ,
699+ }
700+
701+ entities : List [Asset ] = []
702+ if isinstance (entity , list ):
703+ entities .extend (entity )
704+ else :
705+ entities .append (entity )
706+
707+ if not client :
708+ raise ValueError (
709+ "AtlanClient instance must be provided to validate and flush cm for assets."
710+ )
711+ # Validate and flush entities BEFORE creating the BulkRequest
712+ Save .validate_and_flush_entities (entities , client )
713+ return query_params , BulkRequest [Asset ](entities = entities )
714+
715+ @staticmethod
716+ async def prepare_request_async (
717+ entity : Union [Asset , List [Asset ]],
718+ replace_atlan_tags : bool = False ,
719+ replace_custom_metadata : bool = False ,
720+ overwrite_custom_metadata : bool = False ,
721+ append_atlan_tags : bool = False ,
722+ client : Optional [AsyncAtlanClient ] = None ,
723+ ) -> tuple [Dict [str , Any ], BulkRequest [Asset ]]:
724+ """
725+ Prepare the request for saving assets.
726+
727+ :param entity: one or more assets to save
728+ :param replace_atlan_tags: whether to replace AtlanTags during an update
729+ :param replace_custom_metadata: replaces any custom metadata with non-empty values provided
730+ :param overwrite_custom_metadata: overwrites any custom metadata, even with empty values
731+ :param append_atlan_tags: whether to add/update/remove AtlanTags during an update
732+ :param client: Optional[AsyncAtlanClient] = None,
688733 :returns: tuple of (query_params, bulk_request)
689734 """
690735 query_params = {
@@ -700,10 +745,16 @@ def prepare_request(
700745 else :
701746 entities .append (entity )
702747
748+ if not client :
749+ raise ValueError (
750+ "AsyncAtlanClient instance must be provided to validate and flush cm for assets."
751+ )
752+ # Validate and flush entities BEFORE creating the BulkRequest
753+ await Save .validate_and_flush_entities_async (entities , client )
703754 return query_params , BulkRequest [Asset ](entities = entities )
704755
705756 @staticmethod
706- def validate_and_flush_entities (entities : List [Asset ], client ) -> None :
757+ def validate_and_flush_entities (entities : List [Asset ], client : AtlanClient ) -> None :
707758 """
708759 Validate required fields and flush custom metadata for each asset.
709760
@@ -714,6 +765,20 @@ def validate_and_flush_entities(entities: List[Asset], client) -> None:
714765 asset .validate_required ()
715766 asset .flush_custom_metadata (client = client )
716767
768+ @staticmethod
769+ async def validate_and_flush_entities_async (
770+ entities : List [Asset ], client : AsyncAtlanClient
771+ ) -> None :
772+ """
773+ Validate required fields and flush custom metadata for each asset.
774+
775+ :param entities: list of assets to validate and flush
776+ :param client: the Atlan client instance
777+ """
778+ for asset in entities :
779+ asset .validate_required ()
780+ await asset .flush_custom_metadata_async (client = client )
781+
717782 @staticmethod
718783 def process_response (raw_json : Dict [str , Any ]) -> AssetMutationResponse :
719784 """
@@ -750,7 +815,7 @@ def log_connections_finished():
750815 def prepare_request_replacing_cm (
751816 entity : Union [Asset , List [Asset ]],
752817 replace_atlan_tags : bool = False ,
753- client = None ,
818+ client : Optional [ AtlanClient ] = None ,
754819 ) -> tuple [Dict [str , Any ], BulkRequest [Asset ]]:
755820 """
756821 Prepare the request for saving assets with replacing custom metadata.
@@ -773,12 +838,12 @@ def prepare_request_replacing_cm(
773838 else :
774839 entities .append (entity )
775840
841+ if not client :
842+ raise ValueError (
843+ "AtlanClient instance must be provided to validate and flush cm for assets."
844+ )
776845 # Validate and flush entities BEFORE creating the BulkRequest
777- if client :
778- for asset in entities :
779- asset .validate_required ()
780- asset .flush_custom_metadata (client = client )
781-
846+ Save .validate_and_flush_entities (entities , client )
782847 return query_params , BulkRequest [Asset ](entities = entities )
783848
784849 @staticmethod
0 commit comments