This is an automated email from the ASF dual-hosted git repository.
liuxun pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/gravitino.git
The following commit(s) were added to refs/heads/main by this push:
new 2668aaf2bd [#5202] feat(client-python): Support Column and its default
value part1 (#6542)
2668aaf2bd is described below
commit 2668aaf2bd01120318fb80f8dd010364cd330d0d
Author: George T. C. Lai <[email protected]>
AuthorDate: Fri Mar 28 15:00:44 2025 +0800
[#5202] feat(client-python): Support Column and its default value part1
(#6542)
### What changes were proposed in this pull request?
This is first part (totally 4 planned) of implementation to the
following classes from Java to support Column and its default value,
including:
- SupportsTags.java
- Tag.java
- NoSuchTagException.java
- TagAlreadyExistsException.java
### Why are the changes needed?
We need to support Column and its default value in python client.
#5202
### Does this PR introduce _any_ user-facing change?
No
### How was this patch tested?
Unit tests
---------
Signed-off-by: George T. C. Lai <[email protected]>
---
.../client-python/gravitino/api/tag/__init__.py | 16 +++
.../gravitino/api/tag/supports_tags.py | 87 +++++++++++++++
clients/client-python/gravitino/api/tag/tag.py | 118 +++++++++++++++++++++
clients/client-python/gravitino/exceptions/base.py | 8 ++
4 files changed, 229 insertions(+)
diff --git a/clients/client-python/gravitino/api/tag/__init__.py
b/clients/client-python/gravitino/api/tag/__init__.py
new file mode 100644
index 0000000000..13a83393a9
--- /dev/null
+++ b/clients/client-python/gravitino/api/tag/__init__.py
@@ -0,0 +1,16 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
diff --git a/clients/client-python/gravitino/api/tag/supports_tags.py
b/clients/client-python/gravitino/api/tag/supports_tags.py
new file mode 100644
index 0000000000..89b405f890
--- /dev/null
+++ b/clients/client-python/gravitino/api/tag/supports_tags.py
@@ -0,0 +1,87 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+
+from abc import ABC, abstractmethod
+from typing import List
+
+from gravitino.api.tag.tag import Tag
+
+
+class SupportsTags(ABC):
+ """Interface for supporting getting or associate tags to objects.
+
+ This interface will be mixed with metadata objects to provide tag
operations.
+ """
+
+ @abstractmethod
+ def list_tags(self) -> List[str]:
+ """List all the tag names for the specific object.
+
+ Returns:
+ List[str]: The list of tag names.
+ """
+ pass
+
+ @abstractmethod
+ def list_tags_info(self) -> List[Tag]:
+ """List all the tags with details for the specific object.
+
+ Returns:
+ List[Tag]: The list of tags.
+ """
+ pass
+
+ @abstractmethod
+ def get_tag(self, name: str) -> Tag:
+ """Get a tag by its name for the specific object.
+
+ Args:
+ name (str): The name of the tag.
+
+ Raises:
+ NoSuchTagException: If the tag does not associate with the object.
+
+ Returns:
+ Tag: The tag.
+ """
+ pass
+
+ @abstractmethod
+ def associate_tags(
+ self, tags_to_add: List[str], tags_to_remove: List[str]
+ ) -> List[str]:
+ """Associate tags to the specific object.
+
+ The `tags_to_add` will be added to the object, and the
`tags_to_remove` will be removed from the object.
+
+ Note that:
+ 1. Adding or removing tags that are not existed will be ignored.
+ 2. If the same name tag is in both `tags_to_add` and `tags_to_remove`,
it will be ignored.
+ 3. If the tag is already associated with the object, it will raise
`TagAlreadyAssociatedException`.
+
+ Args:
+ tags_to_add (List[str]): The arrays of tag name to be added to the
object.
+ tags_to_remove (List[str]): The array of tag name to be removed
from the object.
+
+ Raises:
+ TagAlreadyAssociatedException: If the tag is already associated
with the object.
+
+ Returns:
+ List[str]: The array of tag names that are associated with the
object.
+ """
+ pass
diff --git a/clients/client-python/gravitino/api/tag/tag.py
b/clients/client-python/gravitino/api/tag/tag.py
new file mode 100644
index 0000000000..6e2a510461
--- /dev/null
+++ b/clients/client-python/gravitino/api/tag/tag.py
@@ -0,0 +1,118 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+
+from abc import ABC, abstractmethod
+from typing import ClassVar, Dict, List, Optional
+
+from gravitino.api.auditable import Auditable
+from gravitino.api.metadata_object import MetadataObject
+from gravitino.exceptions.base import UnsupportedOperationException
+
+
+class AssociatedObjects(ABC):
+ """The interface of the associated objects of the tag."""
+
+ @abstractmethod
+ def count(self) -> int:
+ """Get the number of associated objects.
+
+ Returns:
+ int: The number of associated objects.
+ """
+ objects = self.objects()
+ return 0 if objects is None else len(objects)
+
+ @abstractmethod
+ def objects(self) -> Optional[List[MetadataObject]]:
+ """Get the associated objects.
+
+ Returns:
+ Optional[List[MetadataObject]]: The list of objects that are
associated with this tag..
+ """
+ pass
+
+
+class Tag(Auditable):
+ """The interface of a tag.
+
+ A tag is a label that can be attached to a catalog, schema, table,
fileset, topic,
+ or column. It can be used to categorize, classify, or annotate these
objects.
+ """
+
+ PROPERTY_COLOR: ClassVar[str] = "color"
+ """
+ A reserved property to specify the color of the tag. The color is a string
of hex code that
+ represents the color of the tag. The color is used to visually distinguish
the tag from other
+ tags.
+ """
+
+ @abstractmethod
+ def name(self) -> str:
+ """Get the name of the tag.
+
+ Returns:
+ str: The name of the tag.
+ """
+ pass
+
+ @abstractmethod
+ def comment(self) -> str:
+ """Get the comment of the tag.
+
+ Returns:
+ str: The comment of the tag.
+ """
+ pass
+
+ @abstractmethod
+ def properties(self) -> Dict[str, str]:
+ """Get the properties of the tag.
+
+ Returns:
+ Dict[str, str]: The properties of the tag.
+ """
+ pass
+
+ @abstractmethod
+ def inherited(self) -> Optional[bool]:
+ """Check if the tag is inherited from a parent object or not.
+
+ If the tag is inherited, it will return `True`, if it is owned by the
object itself, it will return `False`.
+
+ **Note**. The return value is optional, only when the tag is
associated with an object, and called from the
+ object, the return value will be present. Otherwise, it will be empty.
+
+ Returns:
+ Optional[bool]:
+ True if the tag is inherited, false if it is owned by the
object itself. Empty if the
+ tag is not associated with any object.
+ """
+ pass
+
+ def associated_objects(self) -> AssociatedObjects:
+ """The associated objects of the tag.
+
+ Raises:
+ UnsupportedOperationException: The associated_objects method is
not supported.
+
+ Returns:
+ AssociatedObjects: The associated objects of the tag.
+ """
+ raise UnsupportedOperationException(
+ "The associated_objects method is not supported."
+ )
diff --git a/clients/client-python/gravitino/exceptions/base.py
b/clients/client-python/gravitino/exceptions/base.py
index e06bcc1b70..f742381214 100644
--- a/clients/client-python/gravitino/exceptions/base.py
+++ b/clients/client-python/gravitino/exceptions/base.py
@@ -159,3 +159,11 @@ class BadRequestException(GravitinoRuntimeException):
class IllegalStateException(GravitinoRuntimeException):
"""An exception thrown when the state is invalid."""
+
+
+class NoSuchTagException(NotFoundException):
+ """An exception thrown when a tag with specified name is not existed."""
+
+
+class TagAlreadyExistsException(AlreadyExistsException):
+ """An exception thrown when a tag with specified name already associated
to a metadata object."""