diff --git a/pyatlan/errors.py b/pyatlan/errors.py index 390889ea8..434a38552 100644 --- a/pyatlan/errors.py +++ b/pyatlan/errors.py @@ -668,6 +668,13 @@ class ErrorCode(Enum): "Use client.asset.set_dq_row_scope_filter_column() to configure the row scope filter column first.", InvalidRequestError, ) + INVALID_RICH_TEXT_CREATION = ( + 400, + "ATLAN-PYTHON-400-076", + "Rich text attributes cannot be multi-valued for '{0}'.", + "Set multi_valued=False when creating rich text attributes.", + InvalidRequestError, + ) AUTHENTICATION_PASSTHROUGH = ( 401, "ATLAN-PYTHON-401-000", diff --git a/pyatlan/model/enums.py b/pyatlan/model/enums.py index 2c1ba433a..4eb94696c 100644 --- a/pyatlan/model/enums.py +++ b/pyatlan/model/enums.py @@ -401,6 +401,7 @@ class AtlanCustomAttributePrimitiveType(str, Enum): URL = "url" SQL = "SQL" LONG = "long" + RICH_TEXT = "string" class AtlanDeleteType(str, Enum): diff --git a/pyatlan/model/typedef.py b/pyatlan/model/typedef.py index 51573859c..23bb96a11 100644 --- a/pyatlan/model/typedef.py +++ b/pyatlan/model/typedef.py @@ -547,6 +547,10 @@ class Options(AtlanObject): "These cover any asset type that is not managed within a connection or a glossary. " "Only assets of one of these types will have this attribute available.", ) + is_rich_text: Optional[bool] = Field( + default=False, + description="Whether this attribute supports rich text formatting (true) or not (false). ", + ) def __setattr__(self, name, value): super().__setattr__(name, value) @@ -579,6 +583,7 @@ def create( multi_value_select=False, show_in_overview=False, is_enum=False, + is_rich_text=False, ) if attribute_type in ( AtlanCustomAttributePrimitiveType.USERS, @@ -590,6 +595,11 @@ def create( elif attribute_type == AtlanCustomAttributePrimitiveType.OPTIONS: options.is_enum = True options.enum_type = options_name + elif attribute_type == AtlanCustomAttributePrimitiveType.RICH_TEXT: + # For RichText, we set the primitive type as string and enable rich text + options.is_rich_text = True + # Rich text attributes cannot be multi-valued + options.multi_value_select = False return options is_new: Optional[bool] = Field( @@ -935,6 +945,14 @@ def create( ["display_name", "attribute_type"], [display_name, attribute_type], ) + # RichText attributes cannot be multi-valued + if ( + attribute_type == AtlanCustomAttributePrimitiveType.RICH_TEXT + and multi_valued + ): + raise ErrorCode.INVALID_RICH_TEXT_CREATION.exception_with_parameters( + display_name + ) # Explicitly set all defaults to ensure inclusion during pydantic serialization attr_def = AttributeDef( display_name=display_name, @@ -1035,6 +1053,14 @@ async def create_async( ["display_name", "attribute_type"], [display_name, attribute_type], ) + # RichText attributes cannot be multi-valued + if ( + attribute_type == AtlanCustomAttributePrimitiveType.RICH_TEXT + and multi_valued + ): + raise ErrorCode.INVALID_RICH_TEXT_CREATION.exception_with_parameters( + display_name + ) # Async version of _get_all_qualified_names helper async def _get_all_qualified_names_async(asset_type: str):