40
40
ADD_BUSINESS_ATTRIBUTE_BY_ID ,
41
41
BULK_UPDATE ,
42
42
DELETE_ENTITIES_BY_GUIDS ,
43
- DELETE_ENTITY_BY_ATTRIBUTE ,
44
43
GET_ENTITY_BY_GUID ,
45
44
GET_ENTITY_BY_UNIQUE_ATTRIBUTE ,
46
45
GET_LINEAGE_LIST ,
47
46
INDEX_SEARCH ,
48
47
PARTIAL_UPDATE_ENTITY_BY_ATTRIBUTE ,
49
- UPDATE_ENTITY_BY_ATTRIBUTE ,
50
48
)
51
49
from pyatlan .errors import AtlanError , ErrorCode
52
50
from pyatlan .model .aggregation import Aggregations
74
72
AtlanObject ,
75
73
AtlanTag ,
76
74
AtlanTagName ,
77
- AtlanTags ,
78
75
BulkRequest ,
79
76
SearchRequest ,
80
77
)
@@ -587,6 +584,7 @@ def save(
587
584
self ,
588
585
entity : Union [Asset , List [Asset ]],
589
586
replace_atlan_tags : bool = False ,
587
+ append_atlan_tags : bool = False ,
590
588
replace_custom_metadata : bool = False ,
591
589
overwrite_custom_metadata : bool = False ,
592
590
) -> AssetMutationResponse :
@@ -604,7 +602,8 @@ def save(
604
602
:raises ApiError: if a connection was created and blocking until policies are synced overruns the retry limit
605
603
"""
606
604
query_params = {
607
- "replaceClassifications" : replace_atlan_tags ,
605
+ "replaceTags" : replace_atlan_tags ,
606
+ "appendTags" : append_atlan_tags ,
608
607
"replaceBusinessAttributes" : replace_custom_metadata ,
609
608
"overwriteBusinessAttributes" : overwrite_custom_metadata ,
610
609
}
@@ -876,36 +875,6 @@ def _restore_asset(self, asset: Asset) -> AssetMutationResponse:
876
875
raw_json = self ._client ._call_api (BULK_UPDATE , query_params , request )
877
876
return AssetMutationResponse (** raw_json )
878
877
879
- def _modify_tags (
880
- self ,
881
- api : API ,
882
- asset_type : Type [A ],
883
- qualified_name : str ,
884
- atlan_tag_names : List [str ],
885
- propagate : bool = False ,
886
- remove_propagation_on_delete : bool = True ,
887
- restrict_lineage_propagation : bool = False ,
888
- restrict_propagation_through_hierarchy : bool = False ,
889
- ) -> None :
890
- atlan_tags = AtlanTags (
891
- __root__ = [
892
- AtlanTag (
893
- type_name = AtlanTagName (display_text = name ),
894
- propagate = propagate ,
895
- remove_propagations_on_entity_delete = remove_propagation_on_delete ,
896
- restrict_propagation_through_lineage = restrict_lineage_propagation ,
897
- restrict_propagation_through_hierarchy = restrict_propagation_through_hierarchy ,
898
- )
899
- for name in atlan_tag_names
900
- ]
901
- )
902
- query_params = {"attr:qualifiedName" : qualified_name }
903
- self ._client ._call_api (
904
- api .format_path_with_params (asset_type .__name__ , "classifications" ),
905
- query_params ,
906
- atlan_tags ,
907
- )
908
-
909
878
@validate_arguments
910
879
def add_atlan_tags (
911
880
self ,
@@ -916,11 +885,9 @@ def add_atlan_tags(
916
885
remove_propagation_on_delete : bool = True ,
917
886
restrict_lineage_propagation : bool = False ,
918
887
restrict_propagation_through_hierarchy : bool = False ,
919
- ) -> None :
888
+ ) -> A :
920
889
"""
921
890
Add one or more Atlan tags to the provided asset.
922
- Note: if one or more of the provided Atlan tags already exist on the asset, an error
923
- will be raised. (In other words, this operation is NOT idempotent.)
924
891
925
892
:param asset_type: type of asset to which to add the Atlan tags
926
893
:param qualified_name: qualified_name of the asset to which to add the Atlan tags
@@ -932,19 +899,40 @@ def add_atlan_tags(
932
899
through lineage (True) or do propagate through lineage (False)
933
900
:param restrict_propagation_through_hierarchy: whether to prevent this Atlan tag from
934
901
propagating through hierarchy (True) or allow it to propagate through hierarchy (False)
902
+ :returns: the asset that was updated (note that it will NOT contain details of the added Atlan tags)
935
903
:raises AtlanError: on any API communication issue
936
904
"""
937
- self ._modify_tags (
938
- UPDATE_ENTITY_BY_ATTRIBUTE ,
939
- asset_type ,
940
- qualified_name ,
941
- atlan_tag_names ,
942
- propagate ,
943
- remove_propagation_on_delete ,
944
- restrict_lineage_propagation ,
945
- restrict_propagation_through_hierarchy ,
905
+ from pyatlan .client .atlan import AtlanClient
906
+
907
+ client = AtlanClient .get_current_client ()
908
+
909
+ name_asset = client .asset .get_by_qualified_name (
910
+ qualified_name = qualified_name , asset_type = asset_type
911
+ )
912
+
913
+ updated_asset = asset_type .updater (
914
+ qualified_name = qualified_name , name = name_asset .name
946
915
)
947
916
917
+ atlan_tag = [
918
+ AtlanTag (
919
+ type_name = AtlanTagName (display_text = name ),
920
+ propagate = propagate ,
921
+ remove_propagations_on_entity_delete = remove_propagation_on_delete ,
922
+ restrict_propagation_through_lineage = restrict_lineage_propagation ,
923
+ restrict_propagation_through_hierarchy = restrict_propagation_through_hierarchy ,
924
+ )
925
+ for name in atlan_tag_names
926
+ ]
927
+
928
+ updated_asset .add_or_update_classifications = atlan_tag
929
+
930
+ response = self .save (entity = updated_asset , append_atlan_tags = True )
931
+
932
+ if assets := response .assets_updated (asset_type = asset_type ):
933
+ return assets [0 ]
934
+ return updated_asset
935
+
948
936
@validate_arguments
949
937
def update_atlan_tags (
950
938
self ,
@@ -955,11 +943,9 @@ def update_atlan_tags(
955
943
remove_propagation_on_delete : bool = True ,
956
944
restrict_lineage_propagation : bool = True ,
957
945
restrict_propagation_through_hierarchy : bool = False ,
958
- ) -> None :
946
+ ) -> A :
959
947
"""
960
948
Update one or more Atlan tags to the provided asset.
961
- Note: if one or more of the provided Atlan tags already exist on the asset, an error
962
- will be raised. (In other words, this operation is NOT idempotent.)
963
949
964
950
:param asset_type: type of asset to which to update the Atlan tags
965
951
:param qualified_name: qualified_name of the asset to which to update the Atlan tags
@@ -971,52 +957,70 @@ def update_atlan_tags(
971
957
through lineage (True) or do propagate through lineage (False)
972
958
:param restrict_propagation_through_hierarchy: whether to prevent this Atlan tag from
973
959
propagating through hierarchy (True) or allow it to propagate through hierarchy (False)
960
+ :returns: the asset that was updated (note that it will NOT contain details of the updated Atlan tags)
974
961
:raises AtlanError: on any API communication issue
975
962
"""
976
- self ._modify_tags (
977
- PARTIAL_UPDATE_ENTITY_BY_ATTRIBUTE ,
978
- asset_type ,
979
- qualified_name ,
980
- atlan_tag_names ,
981
- propagate ,
982
- remove_propagation_on_delete ,
983
- restrict_lineage_propagation ,
984
- restrict_propagation_through_hierarchy ,
963
+ from pyatlan .client .atlan import AtlanClient
964
+
965
+ client = AtlanClient .get_current_client ()
966
+ name_asset = client .asset .get_by_qualified_name (
967
+ qualified_name = qualified_name , asset_type = asset_type
968
+ )
969
+ updated_asset = asset_type .updater (
970
+ qualified_name = qualified_name , name = name_asset .name
985
971
)
986
972
973
+ atlan_tag = [
974
+ AtlanTag (
975
+ type_name = AtlanTagName (display_text = name ),
976
+ propagate = propagate ,
977
+ remove_propagations_on_entity_delete = remove_propagation_on_delete ,
978
+ restrict_propagation_through_lineage = restrict_lineage_propagation ,
979
+ restrict_propagation_through_hierarchy = restrict_propagation_through_hierarchy ,
980
+ )
981
+ for name in atlan_tag_names
982
+ ]
983
+ updated_asset .add_or_update_classifications = atlan_tag
984
+ response = self .save (entity = updated_asset , append_atlan_tags = True )
985
+ if assets := response .assets_updated (asset_type = asset_type ):
986
+ return assets [0 ]
987
+ return updated_asset
988
+
987
989
@validate_arguments
988
- def remove_atlan_tag (
989
- self , asset_type : Type [A ], qualified_name : str , atlan_tag_name : str
990
- ) -> None :
990
+ def remove_atlan_tags (
991
+ self ,
992
+ asset_type : Type [A ],
993
+ qualified_name : str ,
994
+ atlan_tag_names : List [str ],
995
+ ) -> A :
991
996
"""
992
- Removes a single Atlan tag from the provided asset.
993
- Note: if the provided Atlan tag does not exist on the asset, an error will be raised.
994
- (In other words, this operation is NOT idempotent.)
997
+ Removes one or more Atlan tag from the provided asset.
995
998
996
999
:param asset_type: type of asset to which to add the Atlan tags
997
1000
:param qualified_name: qualified_name of the asset to which to add the Atlan tags
998
- :param atlan_tag_name : human-readable name of the Atlan tag to remove from the asset
1001
+ :param atlan_tag_names : human-readable name of the Atlan tag to remove from the asset
999
1002
:raises AtlanError: on any API communication issue
1000
1003
"""
1001
1004
from pyatlan .client .atlan import AtlanClient
1002
1005
1003
- classification_id = (
1004
- AtlanClient .get_current_client ().atlan_tag_cache .get_id_for_name (
1005
- atlan_tag_name
1006
- )
1006
+ client = AtlanClient .get_current_client ()
1007
+ name_asset = client .asset .get_by_qualified_name (
1008
+ qualified_name = qualified_name , asset_type = asset_type
1007
1009
)
1008
- if not classification_id :
1009
- raise ErrorCode .ATLAN_TAG_NOT_FOUND_BY_NAME .exception_with_parameters (
1010
- atlan_tag_name
1011
- )
1012
- query_params = {"attr:qualifiedName" : qualified_name }
1013
- self ._client ._call_api (
1014
- DELETE_ENTITY_BY_ATTRIBUTE .format_path_with_params (
1015
- asset_type .__name__ , "classification" , classification_id
1016
- ),
1017
- query_params ,
1010
+ updated_asset = asset_type .updater (
1011
+ qualified_name = qualified_name , name = name_asset .name
1018
1012
)
1019
1013
1014
+ atlan_tag = [
1015
+ AtlanTag (type_name = AtlanTagName (display_text = name ))
1016
+ for name in atlan_tag_names
1017
+ ]
1018
+ updated_asset .remove_classifications = atlan_tag
1019
+ response = self .save (entity = updated_asset , append_atlan_tags = True )
1020
+ if assets := response .assets_updated (asset_type = asset_type ):
1021
+ return assets [0 ]
1022
+ return updated_asset
1023
+
1020
1024
def _update_asset_by_attribute (
1021
1025
self , asset : A , asset_type : Type [A ], qualified_name : str
1022
1026
):
0 commit comments