Skip to content

Commit

Permalink
Merge branch 'branch-0.6' into branch-0.6
Browse files Browse the repository at this point in the history
  • Loading branch information
jerqi authored Aug 12, 2024
2 parents cb013fc + 867bcd8 commit ccb5ed7
Show file tree
Hide file tree
Showing 20 changed files with 317 additions and 58 deletions.
4 changes: 4 additions & 0 deletions .github/workflows/docker-image.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ on:
- 'gravitino-ci-trino'
- 'gravitino-ci-doris'
- 'gravitino-ci-ranger'
- 'gravitino-iceberg-rest-server'
- 'trino'
- 'hive'
- 'ranger'
Expand Down Expand Up @@ -64,6 +65,9 @@ jobs:
elif [ "${{ github.event.inputs.image }}" == "ranger" ]; then
echo "image_type=ranger" >> $GITHUB_ENV
echo "image_name=datastrato/ranger" >> $GITHUB_ENV
elif [ "${{ github.event.inputs.image }}" == "gravitino-iceberg-rest-server" ]; then
echo "image_type=iceberg-rest-server" >> $GITHUB_ENV
echo "image_name=datastrato/gravitino-iceberg-rest-server" >> $GITHUB_ENV
fi
- name: Check publish Docker token
Expand Down
3 changes: 2 additions & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -466,6 +466,7 @@ tasks.rat {
"dev/docker/**/*.conf",
"dev/docker/kerberos-hive/kadm5.acl",
"**/*.log",
"**/*.out",
"**/testsets",
"**/licenses/*.txt",
"**/licenses/*.md",
Expand All @@ -491,7 +492,7 @@ tasks.rat {
"ROADMAP.md",
"clients/client-python/.pytest_cache/*",
"clients/client-python/.venv/*",
"clients/client-python/gravitino.egg-info/*",
"clients/client-python/apache_gravitino.egg-info/*",
"clients/client-python/gravitino/utils/exceptions.py",
"clients/client-python/gravitino/utils/http_client.py",
"clients/client-python/tests/unittests/htmlcov/*",
Expand Down
2 changes: 1 addition & 1 deletion clients/client-python/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@

**/.pytest_cache/**
**/__pycache__/**
gravitino.egg-info
apache_gravitino.egg-info
vevn
venv
.vevn
Expand Down
6 changes: 3 additions & 3 deletions clients/client-python/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -135,13 +135,13 @@ fun generatePypiProjectHomePage() {
}

// Use regular expression to match the `![](./a/b/c.png)` link in the content
// Convert `![](./a/b/c.png)` to `[](https://raw.githubusercontent.org/apache/gravitino/main/docs/a/b/c.png)`
val assertUrl = "https://raw.githubusercontent.org/apache/gravitino/main/docs"
// Convert `![](./a/b/c.png)` to `[](https://github.com/apache/gravitino/blob/main/docs/a/b/c.png?raw=true)`
val assertUrl = "https://github.com/apache/gravitino/blob/main/docs"
val patternImage = """!\[([^\]]+)]\(\./assets/([^)]+)\)""".toRegex()
val contentUpdateImage = patternImage.replace(contentUpdateDocs) { matchResult ->
val altText = matchResult.groupValues[1]
val fileName = matchResult.groupValues[2]
"![${altText}]($assertUrl/assets/$fileName)"
"![${altText}]($assertUrl/assets/$fileName?raw=true)"
}

val readmeFile = file("README.md")
Expand Down
19 changes: 13 additions & 6 deletions clients/client-python/gravitino/client/gravitino_metalake.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
from gravitino.dto.responses.catalog_response import CatalogResponse
from gravitino.dto.responses.drop_response import DropResponse
from gravitino.dto.responses.entity_list_response import EntityListResponse
from gravitino.exceptions.handlers.catalog_error_handler import CATALOG_ERROR_HANDLER
from gravitino.utils import HTTPClient


Expand Down Expand Up @@ -66,7 +67,7 @@ def list_catalogs(self) -> List[str]:
A list of the catalog names under this metalake.
"""
url = f"api/metalakes/{self.name()}/catalogs"
response = self.rest_client.get(url)
response = self.rest_client.get(url, error_handler=CATALOG_ERROR_HANDLER)
entity_list = EntityListResponse.from_json(response.body, infer_missing=True)
entity_list.validate()
return [identifier.name() for identifier in entity_list.identifiers()]
Expand All @@ -82,7 +83,9 @@ def list_catalogs_info(self) -> List[Catalog]:
"""
params = {"details": "true"}
url = f"api/metalakes/{self.name()}/catalogs"
response = self.rest_client.get(url, params=params)
response = self.rest_client.get(
url, params=params, error_handler=CATALOG_ERROR_HANDLER
)
catalog_list = CatalogListResponse.from_json(response.body, infer_missing=True)

return [
Expand All @@ -103,7 +106,7 @@ def load_catalog(self, name: str) -> Catalog:
The Catalog with specified name.
"""
url = self.API_METALAKES_CATALOGS_PATH.format(self.name(), name)
response = self.rest_client.get(url)
response = self.rest_client.get(url, error_handler=CATALOG_ERROR_HANDLER)
catalog_resp = CatalogResponse.from_json(response.body, infer_missing=True)

return DTOConverters.to_catalog(
Expand Down Expand Up @@ -145,7 +148,9 @@ def create_catalog(
catalog_create_request.validate()

url = f"api/metalakes/{self.name()}/catalogs"
response = self.rest_client.post(url, json=catalog_create_request)
response = self.rest_client.post(
url, json=catalog_create_request, error_handler=CATALOG_ERROR_HANDLER
)
catalog_resp = CatalogResponse.from_json(response.body, infer_missing=True)

return DTOConverters.to_catalog(
Expand All @@ -172,7 +177,9 @@ def alter_catalog(self, name: str, *changes: CatalogChange) -> Catalog:
updates_request.validate()

url = self.API_METALAKES_CATALOGS_PATH.format(self.name(), name)
response = self.rest_client.put(url, json=updates_request)
response = self.rest_client.put(
url, json=updates_request, error_handler=CATALOG_ERROR_HANDLER
)
catalog_response = CatalogResponse.from_json(response.body, infer_missing=True)
catalog_response.validate()

Expand All @@ -191,7 +198,7 @@ def drop_catalog(self, name: str) -> bool:
"""
try:
url = self.API_METALAKES_CATALOGS_PATH.format(self.name(), name)
response = self.rest_client.delete(url)
response = self.rest_client.delete(url, error_handler=CATALOG_ERROR_HANDLER)

drop_response = DropResponse.from_json(response.body, infer_missing=True)
drop_response.validate()
Expand Down
5 changes: 5 additions & 0 deletions clients/client-python/gravitino/constants/error.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
from enum import IntEnum

from gravitino.exceptions.base import (
ConnectionFailedException,
RESTException,
IllegalArgumentException,
NotFoundException,
Expand Down Expand Up @@ -54,6 +55,9 @@ class ErrorConstants(IntEnum):
# Error codes for unsupported operation.
UNSUPPORTED_OPERATION_CODE = 1006

# Error codes for connect to catalog failed.
CONNECTION_FAILED_CODE = 1007

# Error codes for invalid state.
UNKNOWN_ERROR_CODE = 1100

Expand All @@ -66,6 +70,7 @@ class ErrorConstants(IntEnum):
AlreadyExistsException: ErrorConstants.ALREADY_EXISTS_CODE,
NotEmptyException: ErrorConstants.NON_EMPTY_CODE,
UnsupportedOperationException: ErrorConstants.UNSUPPORTED_OPERATION_CODE,
ConnectionFailedException: ErrorConstants.CONNECTION_FAILED_CODE,
}

ERROR_CODE_MAPPING = {v: k for k, v in EXCEPTION_MAPPING.items()}
4 changes: 3 additions & 1 deletion clients/client-python/gravitino/dto/dto_converters.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,8 @@ def to_catalog_update_request(change: CatalogChange):
change.property(), change.value()
)
if isinstance(change, CatalogChange.RemoveProperty):
return CatalogUpdateRequest.RemoveCatalogPropertyRequest(change.property())
return CatalogUpdateRequest.RemoveCatalogPropertyRequest(
change.get_property()
)

raise ValueError(f"Unknown change type: {type(change).__name__}")
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,8 @@ def validate(self):
Raises:
IllegalArgumentException if the new name is not set.
"""
assert (
self._new_name is None
), '"newName" field is required and cannot be empty'
if not self._new_name:
raise ValueError('"newName" field is required and cannot be empty')

@dataclass
class UpdateCatalogCommentRequest(CatalogUpdateRequestBase):
Expand All @@ -81,9 +80,8 @@ def catalog_change(self):
return CatalogChange.update_comment(self._new_comment)

def validate(self):
assert (
self._new_comment is None
), '"newComment" field is required and cannot be empty'
if not self._new_comment:
raise ValueError('"newComment" field is required and cannot be empty')

@dataclass
class SetCatalogPropertyRequest(CatalogUpdateRequestBase):
Expand All @@ -104,10 +102,10 @@ def catalog_change(self):
return CatalogChange.set_property(self._property, self._value)

def validate(self):
assert (
self._property is None
), '"property" field is required and cannot be empty'
assert self._value is None, '"value" field is required and cannot be empty'
if not self._property:
raise ValueError('"property" field is required and cannot be empty')
if not self._value:
raise ValueError('"value" field is required and cannot be empty')

class RemoveCatalogPropertyRequest(CatalogUpdateRequestBase):
"""Request to remove a property from a catalog."""
Expand All @@ -123,6 +121,5 @@ def catalog_change(self):
return CatalogChange.remove_property(self._property)

def validate(self):
assert (
self._property is None
), '"property" field is required and cannot be empty'
if not self._property:
raise ValueError('"property" field is required and cannot be empty')
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,14 @@ def validate(self):
"""
super().validate()

assert self.catalog is not None, "catalog must not be null"
assert self._catalog is not None, "catalog must not be null"
assert (
self.catalog.name() is not None
self._catalog.name() is not None
), "catalog 'name' must not be null and empty"
assert self.catalog.type() is not None, "catalog 'type' must not be null"
assert self.catalog.audit_info() is not None, "catalog 'audit' must not be null"
assert self._catalog.type() is not None, "catalog 'type' must not be null"
assert (
self._catalog.audit_info() is not None
), "catalog 'audit' must not be null"

def catalog(self) -> CatalogDTO:
return self._catalog
8 changes: 8 additions & 0 deletions clients/client-python/gravitino/exceptions/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,10 @@ class SchemaAlreadyExistsException(AlreadyExistsException):
"""An exception thrown when a schema already exists."""


class CatalogAlreadyExistsException(AlreadyExistsException):
"""An exception thrown when a resource already exists."""


class NotEmptyException(GravitinoRuntimeException):
"""Base class for all exceptions thrown when a resource is not empty."""

Expand All @@ -95,6 +99,10 @@ class UnknownError(RuntimeError):
"""An exception thrown when other unknown exception is thrown"""


class ConnectionFailedException(GravitinoRuntimeException):
"""An exception thrown when connect to catalog failed."""


class UnauthorizedException(GravitinoRuntimeException):
"""An exception thrown when a user is not authorized to perform an action."""

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
"""
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 gravitino.constants.error import ErrorConstants
from gravitino.dto.responses.error_response import ErrorResponse
from gravitino.exceptions.handlers.rest_error_handler import RestErrorHandler
from gravitino.exceptions.base import (
ConnectionFailedException,
NoSuchMetalakeException,
NoSuchCatalogException,
CatalogAlreadyExistsException,
)


class CatalogErrorHandler(RestErrorHandler):

def handle(self, error_response: ErrorResponse):

error_message = error_response.format_error_message()
code = error_response.code()
exception_type = error_response.type()

if code == ErrorConstants.CONNECTION_FAILED_CODE:
raise ConnectionFailedException(error_message)
if code == ErrorConstants.NOT_FOUND_CODE:
if exception_type == NoSuchMetalakeException.__name__:
raise NoSuchMetalakeException(error_message)
if exception_type == NoSuchCatalogException.__name__:
raise NoSuchCatalogException(error_message)
if code == ErrorConstants.ALREADY_EXISTS_CODE:
raise CatalogAlreadyExistsException(error_message)

super().handle(error_response)


CATALOG_ERROR_HANDLER = CatalogErrorHandler()
26 changes: 18 additions & 8 deletions clients/client-python/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,23 +24,33 @@
with open("README.md") as f:
long_description = f.read()
except FileNotFoundError:
long_description = "Gravitino Python client"
long_description = "Apache Gravitino Python client"

setup(
name="gravitino",
description="Python lib/client for Gravitino",
version="0.6.0.dev",
name="apache-gravitino",
description="Python lib/client for Apache Gravitino",
version="0.6.0.dev0",
long_description=long_description,
long_description_content_type="text/markdown",
url="https://github.com/apache/gravitino",
author="gravitino",
author="Apache Software Foundation",
author_email="[email protected]",
maintainer="Apache Gravitino Community",
maintainer_email="[email protected]",
license="Apache-2.0",
url="https://github.com/apache/gravitino",
python_requires=">=3.8",
keywords="Data, AI, metadata, catalog",
packages=find_packages(exclude=["tests*", "scripts*"]),
project_urls={
"Homepage": "https://gravitino.apache.org/",
"Source Code": "https://github.com/apache/gravitino",
"Documentation": "https://gravitino.apache.org/docs/overview",
"Bug Tracker": "https://github.com/apache/gravitino/issues",
"Slack Chat": "https://the-asf.slack.com/archives/C078RESTT19",
},
classifiers=[
"Development Status :: 3 - Alpha",
"Intended Audience :: Developers",
"License :: OSI Approved :: Apache Software License",
"Operating System :: OS Independent",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
Expand Down
Loading

0 comments on commit ccb5ed7

Please sign in to comment.