Skip to content

Commit

Permalink
Adding Dashboard description API
Browse files Browse the repository at this point in the history
  • Loading branch information
jinhyukchang committed Mar 11, 2020
1 parent ea0a2d9 commit 8fe6168
Show file tree
Hide file tree
Showing 11 changed files with 324 additions and 36 deletions.
5 changes: 4 additions & 1 deletion metadata_service/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
from flask_restful import Api

from metadata_service.api.column import ColumnDescriptionAPI
from metadata_service.api.dashboard import DashboardDetailAPI
from metadata_service.api.dashboard import DashboardDetailAPI, DashboardDescriptionAPI
from metadata_service.api.healthcheck import healthcheck
from metadata_service.api.popular_tables import PopularTablesAPI
from metadata_service.api.system import Neo4jDetailAPI
Expand All @@ -22,6 +22,7 @@
UserFollowsAPI, UserOwnsAPI,
UserOwnAPI, UserReadsAPI)


# For customized flask use below arguments to override.
FLASK_APP_MODULE_NAME = os.getenv('FLASK_APP_MODULE_NAME')
FLASK_APP_CLASS_NAME = os.getenv('FLASK_APP_CLASS_NAME')
Expand Down Expand Up @@ -106,6 +107,8 @@ def create_app(*, config_module_class: str) -> Flask:
'/user/<path:user_id>/read/')
api.add_resource(DashboardDetailAPI,
'/dashboard/<path:id>')
api.add_resource(DashboardDescriptionAPI,
'/dashboard/<path:id>/description')
app.register_blueprint(api_bp)

if app.config.get('SWAGGER_ENABLED'):
Expand Down
42 changes: 42 additions & 0 deletions metadata_service/api/dashboard.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,12 @@

from flasgger import swag_from

from flask import request
import json

from metadata_service.api import BaseAPI
from metadata_service.entity.dashboard_detail import DashboardSchema
from metadata_service.entity.description import DescriptionSchema
from metadata_service.exception import NotFoundException
from metadata_service.proxy import get_proxy_client

Expand All @@ -24,3 +28,41 @@ def get(self, *, id: Optional[str] = None) -> Iterable[Union[Mapping, int, None]
return super().get(id=id)
except NotFoundException:
return {'message': 'dashboard_id {} does not exist'.format(id)}, HTTPStatus.NOT_FOUND


class DashboardDescriptionAPI(BaseAPI):
"""
DashboardDescriptionAPI supports PUT and GET operation to upsert table description
"""
def __init__(self) -> None:
self.client = get_proxy_client()
super().__init__(DescriptionSchema, 'dashboard_description', self.client)

@swag_from('swagger_doc/common/description_get.yml')
def get(self, *, id: Optional[str] = None) -> Iterable[Union[Mapping, int, None]]:
"""
Returns description
"""
try:
return super().get(id=id)

except NotFoundException:
return {'message': 'Dashboard {} does not exist'.format(id)}, HTTPStatus.NOT_FOUND

except Exception:
return {'message': 'Internal server error!'}, HTTPStatus.INTERNAL_SERVER_ERROR

@swag_from('swagger_doc/common/description_put.yml')
def put(self, id: str) -> Iterable[Union[Mapping, int, None]]:
"""
Updates Dashboard description (passed as a request body)
:param id:
:return:
"""
try:
description = json.loads(request.data).get('description')
self.client.put_dashboard_description(id=id, description=description)
return None, HTTPStatus.OK

except NotFoundException:
return {'message': 'id {} does not exist'.format(id)}, HTTPStatus.NOT_FOUND
33 changes: 33 additions & 0 deletions metadata_service/api/swagger_doc/common/description_get.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
Gets the description of a resource
---
tags:
- 'table'
- 'description'
parameters:
- name: id
in: path
type: string
schema:
type: string
required: true
example: 'dynamo://gold.test_schema/test_table2'
responses:
200:
description: 'Table description'
content:
application/json:
schema:
$ref: '#/components/schemas/Description'
description: 'Resource description'
404:
description: 'Resource not found'
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
500:
description: 'Internal server error'
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
33 changes: 33 additions & 0 deletions metadata_service/api/swagger_doc/common/description_put.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
Upserts description of a resource
---
tags:
- 'table'
- 'dashboard'
parameters:
- name: id
in: path
type: string
schema:
type: string
required: true
example: 'dynamo://gold.test_schema/test_table2'
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/Description'
description: Resource description
required: true
responses:
200:
description: 'Empty response'
content:
application/json:
schema:
$ref: '#/components/schemas/EmptyResponse'
404:
description: 'Resource not found'
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
13 changes: 13 additions & 0 deletions metadata_service/entity/description.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import attr
from marshmallow_annotations.ext.attrs import AttrsSchema


@attr.s(auto_attribs=True, kw_only=True)
class Description:
description: str = attr.ib()


class DescriptionSchema(AttrsSchema):
class Meta:
target = Description
register_as_scheme = True
6 changes: 6 additions & 0 deletions metadata_service/entity/resource_type.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
from enum import Enum, auto


class ResourceType(Enum):
Table = auto()
Dashboard = auto()
10 changes: 10 additions & 0 deletions metadata_service/proxy/atlas_proxy.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
from flask import current_app as app

from metadata_service.entity.dashboard_detail import DashboardDetail as DashboardDetailEntity
from metadata_service.entity.description import Description
from metadata_service.entity.tag_detail import TagDetail
from metadata_service.exception import NotFoundException
from metadata_service.proxy import BaseProxy
Expand Down Expand Up @@ -583,3 +584,12 @@ def get_dashboard(self,
dashboard_uri: str,
) -> DashboardDetailEntity:
pass

def get_dashboard_description(self, *,
id: str) -> Description:
pass

def put_dashboard_description(self, *,
id: str,
description: str) -> None:
pass
15 changes: 14 additions & 1 deletion metadata_service/proxy/base_proxy.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@
from amundsen_common.models.popular_table import PopularTable
from amundsen_common.models.table import Table
from amundsen_common.models.user import User as UserEntity
from metadata_service.entity.dashboard_detail import DashboardDetail as DashboardDetailEntity

from metadata_service.entity.dashboard_detail import DashboardDetail as DashboardDetailEntity
from metadata_service.entity.description import Description
from metadata_service.util import UserResourceRel


Expand All @@ -14,6 +15,7 @@ class BaseProxy(metaclass=ABCMeta):
Base Proxy, which behaves like an interface for all
the proxy clients available in the amundsen metadata service
"""

@abstractmethod
def get_user(self, *, id: str) -> Union[UserEntity, None]:
pass
Expand Down Expand Up @@ -106,3 +108,14 @@ def get_dashboard(self,
dashboard_uri: str,
) -> DashboardDetailEntity:
pass

@abstractmethod
def get_dashboard_description(self, *,
id: str) -> Description:
pass

@abstractmethod
def put_dashboard_description(self, *,
id: str,
description: str) -> None:
pass
10 changes: 10 additions & 0 deletions metadata_service/proxy/gremlin_proxy.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
from gremlin_python.process.graph_traversal import GraphTraversalSource

from metadata_service.entity.dashboard_detail import DashboardDetail as DashboardDetailEntity
from metadata_service.entity.description import Description
from metadata_service.proxy import BaseProxy
from metadata_service.util import UserResourceRel

Expand Down Expand Up @@ -160,6 +161,15 @@ def get_dashboard(self,
) -> DashboardDetailEntity:
pass

def get_dashboard_description(self, *,
id: str) -> Description:
pass

def put_dashboard_description(self, *,
id: str,
description: str) -> None:
pass


class GenericGremlinProxy(AbstractGremlinProxy):
"""
Expand Down
Loading

0 comments on commit 8fe6168

Please sign in to comment.