Skip to content

Commit dc2d6a6

Browse files
author
Dmitriy Kunitskiy
authored
chore: upgrade to marshmallow 3 (#963)
* chore: upgrade to marshmallow 3 and marshmallow3-annotations Signed-off-by: Dmitriy Kunitskiy <[email protected]> * typos Signed-off-by: Dmitriy Kunitskiy <[email protected]>
1 parent 33a681c commit dc2d6a6

15 files changed

+72
-76
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ build/
1616
.coverage
1717
.mypy_cache
1818
.pytest_cache
19+
.python-version
1920

2021

2122
npm-debug.log

amundsen_application/api/preview/v0.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
from flask import Response, jsonify, make_response, request, current_app as app
1111
from flask.blueprints import Blueprint
12+
from marshmallow import ValidationError
1213
from werkzeug.utils import import_string
1314

1415
from amundsen_application.models.preview_data import PreviewDataSchema
@@ -49,11 +50,11 @@ def get_table_preview() -> Response:
4950
preview_data = json.loads(response.data).get('preview_data')
5051
if status_code == HTTPStatus.OK:
5152
# validate the returned table preview data
52-
data, errors = PreviewDataSchema().load(preview_data)
53-
if not errors:
53+
try:
54+
data = PreviewDataSchema().load(preview_data)
5455
payload = jsonify({'previewData': data, 'msg': 'Success'})
55-
else:
56-
logging.error('Preview data dump returned errors: ' + str(errors))
56+
except ValidationError as err:
57+
logging.error('Preview data dump returned errors: ' + str(err.messages))
5758
raise Exception('The preview client did not return a valid PreviewData object')
5859
else:
5960
message = 'Encountered error: Preview client request failed with code ' + str(status_code)

amundsen_application/api/utils/metadata_utils.py

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import urllib.parse
66

77
from dataclasses import dataclass
8+
from marshmallow import EXCLUDE
89
from typing import Any, Dict, List
910

1011
from amundsen_common.models.dashboard import DashboardSummary, DashboardSummarySchema
@@ -46,10 +47,9 @@ def marshall_table_partial(table_dict: Dict) -> Dict:
4647
4748
TODO - Unify data format returned by search and metadata.
4849
"""
49-
schema = PopularTableSchema(strict=True)
50-
# TODO: consider migrating to validate() instead of roundtripping
51-
table: PopularTable = schema.load(table_dict).data
52-
results = schema.dump(table).data
50+
schema = PopularTableSchema()
51+
table: PopularTable = schema.load(table_dict, unknown=EXCLUDE)
52+
results = schema.dump(table)
5353
# TODO: fix popular tables to provide these? remove if we're not using them?
5454
# TODO: Add the 'key' or 'id' to the base PopularTableSchema
5555
results['key'] = f'{table.database}://{table.cluster}.{table.schema}/{table.name}'
@@ -104,10 +104,9 @@ def marshall_table_full(table_dict: Dict) -> Dict:
104104
:return: Table Dict with sanitized fields
105105
"""
106106

107-
schema = TableSchema(strict=True)
108-
# TODO: consider migrating to validate() instead of roundtripping
109-
table: Table = schema.load(table_dict).data
110-
results: Dict[str, Any] = schema.dump(table).data
107+
schema = TableSchema()
108+
table: Table = schema.load(table_dict)
109+
results: Dict[str, Any] = schema.dump(table)
111110

112111
is_editable = is_table_editable(results['schema'], results['name'])
113112
results['is_editable'] = is_editable
@@ -149,9 +148,9 @@ def marshall_dashboard_partial(dashboard_dict: Dict) -> Dict:
149148
:param dashboard_dict: Dict of partial dashboard metadata
150149
:return: partial dashboard Dict
151150
"""
152-
schema = DashboardSummarySchema(strict=True)
153-
dashboard: DashboardSummary = schema.load(dashboard_dict).data
154-
results = schema.dump(dashboard).data
151+
schema = DashboardSummarySchema(unknown=EXCLUDE)
152+
dashboard: DashboardSummary = schema.load(dashboard_dict)
153+
results = schema.dump(dashboard)
155154
results['type'] = 'dashboard'
156155
# TODO: Bookmark logic relies on key, opting to add this here to avoid messy logic in
157156
# React app and we have to clean up later.

amundsen_application/base/base_announcement_client.py

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
from http import HTTPStatus
88

99
from flask import jsonify, make_response, Response
10+
from marshmallow import ValidationError
1011

1112
from amundsen_application.models.announcements import Announcements, AnnouncementsSchema
1213

@@ -31,20 +32,16 @@ def _create_error_response(message: str) -> Response:
3132
return make_response(payload, HTTPStatus.INTERNAL_SERVER_ERROR)
3233

3334
try:
34-
try:
35-
announcements = self.get_posts()
36-
except Exception as e:
37-
message = 'Encountered exception getting posts: ' + str(e)
38-
return _create_error_response(message)
39-
40-
# validate the returned object
41-
data, errors = AnnouncementsSchema().dump(announcements)
42-
if not errors:
43-
payload = jsonify({'posts': data.get('posts'), 'msg': 'Success'})
44-
return make_response(payload, HTTPStatus.OK)
45-
else:
46-
message = 'Announcement data dump returned errors: ' + str(errors)
47-
return _create_error_response(message)
35+
announcements = self.get_posts()
4836
except Exception as e:
49-
message = 'Encountered exception: ' + str(e)
37+
message = 'Encountered exception getting posts: ' + str(e)
38+
return _create_error_response(message)
39+
40+
try:
41+
data = AnnouncementsSchema().dump(announcements)
42+
AnnouncementsSchema().load(data) # validate returned object
43+
payload = jsonify({'posts': data.get('posts'), 'msg': 'Success'})
44+
return make_response(payload, HTTPStatus.OK)
45+
except ValidationError as err:
46+
message = 'Announcement data dump returned errors: ' + str(err.messages)
5047
return _create_error_response(message)

amundsen_application/base/base_bigquery_preview_client.py

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
# SPDX-License-Identifier: Apache-2.0
33

44
from http import HTTPStatus
5+
import logging
56
from typing import Dict, List
67
from amundsen_application.base.base_preview_client import BasePreviewClient
78
from amundsen_application.models.preview_data import (
@@ -10,6 +11,7 @@
1011
PreviewDataSchema,
1112
)
1213
from flask import Response, make_response, jsonify
14+
from marshmallow import ValidationError
1315
from google.cloud import bigquery
1416

1517

@@ -60,13 +62,13 @@ def get_preview_data(self, params: Dict, optionalHeaders: Dict = None) -> Respon
6062
params["schema"],
6163
params["tableName"],
6264
)
63-
data = PreviewDataSchema().dump(preview_data)[0]
64-
errors = PreviewDataSchema().load(data)[1]
65-
payload = jsonify({"preview_data": data})
66-
67-
if not errors:
65+
try:
66+
data = PreviewDataSchema().dump(preview_data)
67+
PreviewDataSchema().load(data) # for validation only
6868
payload = jsonify({"preview_data": data})
6969
return make_response(payload, HTTPStatus.OK)
70-
return make_response(
71-
jsonify({"preview_data": {}}), HTTPStatus.INTERNAL_SERVER_ERROR
72-
)
70+
except ValidationError as err:
71+
logging.error("PreviewDataSchema serialization error + " + str(err.messages))
72+
return make_response(
73+
jsonify({"preview_data": {}}), HTTPStatus.INTERNAL_SERVER_ERROR
74+
)

amundsen_application/base/base_superset_preview_client.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,11 @@
22
# SPDX-License-Identifier: Apache-2.0
33

44
import abc
5+
import logging
56

67
from flask import Response as FlaskResponse, make_response, jsonify
78
from http import HTTPStatus
9+
from marshmallow import ValidationError
810
from requests import Response
911
from typing import Dict
1012

@@ -45,12 +47,13 @@ def get_preview_data(self, params: Dict, optionalHeaders: Dict = None) -> FlaskR
4547
response_dict = response.json()
4648
columns = [ColumnItem(c['name'], c['type']) for c in response_dict['columns']]
4749
preview_data = PreviewData(columns, response_dict['data'])
48-
data = PreviewDataSchema().dump(preview_data)[0]
49-
errors = PreviewDataSchema().load(data)[1]
50-
if not errors:
50+
try:
51+
data = PreviewDataSchema().dump(preview_data)
52+
PreviewDataSchema().load(data) # for validation only
5153
payload = jsonify({'preview_data': data})
5254
return make_response(payload, response.status_code)
53-
else:
55+
except ValidationError as err:
56+
logging.error("PreviewDataSchema serialization error " + str(err.messages))
5457
return make_response(jsonify({'preview_data': {}}), HTTPStatus.INTERNAL_SERVER_ERROR)
5558
except Exception:
5659
return make_response(jsonify({'preview_data': {}}), HTTPStatus.INTERNAL_SERVER_ERROR)

amundsen_application/base/examples/example_dremio_preview_client.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
from typing import Dict # noqa: F401
77

88
from flask import Response, jsonify, make_response, current_app as app
9+
from marshmallow import ValidationError
910
from pyarrow import flight
1011

1112
from amundsen_application.base.base_superset_preview_client import BasePreviewClient
@@ -79,16 +80,15 @@ def get_preview_data(self, params: Dict, optionalHeaders: Dict = None) -> Respon
7980
column_items = [ColumnItem(n, t) for n, t in zip(names, types)]
8081

8182
preview_data = PreviewData(column_items, rows)
82-
83-
data = PreviewDataSchema().dump(preview_data)[0]
84-
errors = PreviewDataSchema().load(data)[1]
85-
if errors:
86-
logging.error(f'Error(s) occurred while building preview data: {errors}')
87-
payload = jsonify({'preview_data': {}})
88-
return make_response(payload, HTTPStatus.INTERNAL_SERVER_ERROR)
89-
else:
83+
try:
84+
data = PreviewDataSchema().dump(preview_data)
85+
PreviewDataSchema().load(data) # for validation only
9086
payload = jsonify({'preview_data': data})
9187
return make_response(payload, HTTPStatus.OK)
88+
except ValidationError as err:
89+
logging.error(f'Error(s) occurred while building preview data: {err.messages}')
90+
payload = jsonify({'preview_data': {}})
91+
return make_response(payload, HTTPStatus.INTERNAL_SERVER_ERROR)
9292

9393
except Exception as e:
9494
logging.error(f'Encountered exception: {e}')

amundsen_application/models/announcements.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
from marshmallow import Schema, fields, post_dump
55
from marshmallow.exceptions import ValidationError
66

7-
from typing import Dict, List
7+
from typing import Dict, List, Any
88

99

1010
class Post:
@@ -29,10 +29,11 @@ class AnnouncementsSchema(Schema):
2929
posts = fields.Nested(PostSchema, many=True)
3030

3131
@post_dump
32-
def validate_data(self, data: Dict) -> None:
32+
def validate_data(self, data: Dict, **kwargs: Any) -> Dict:
3333
posts = data.get('posts', [])
3434
for post in posts:
3535
if post.get('date') is None:
3636
raise ValidationError('All posts must have a date')
3737
if post.get('title') is None:
3838
raise ValidationError('All posts must have a title')
39+
return data

amundsen_application/models/preview_data.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# Copyright Contributors to the Amundsen project.
22
# SPDX-License-Identifier: Apache-2.0
33

4-
from marshmallow import Schema, fields
4+
from marshmallow import Schema, fields, EXCLUDE
55
from typing import List
66

77

@@ -24,6 +24,6 @@ def __init__(self, columns: List = [], data: List = [], error_text: str = '') ->
2424

2525

2626
class PreviewDataSchema(Schema):
27-
columns = fields.Nested(ColumnItemSchema, many=True)
27+
columns = fields.Nested(ColumnItemSchema, many=True, unknown=EXCLUDE)
2828
data = fields.List(fields.Dict, many=True)
2929
error_text = fields.Str()

amundsen_application/models/user.py

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -28,16 +28,11 @@ def load_user(user_data: Dict) -> User:
2828
# in the user metadata.
2929
if _str_no_value(user_data.get('profile_url')) and app.config['GET_PROFILE_URL']:
3030
user_data['profile_url'] = app.config['GET_PROFILE_URL'](user_data['user_id'])
31-
data, errors = schema.load(user_data)
32-
return data
31+
return schema.load(user_data)
3332
except ValidationError as err:
3433
return err.messages
3534

3635

3736
def dump_user(user: User) -> Dict:
3837
schema = UserSchema()
39-
try:
40-
data, errors = schema.dump(user)
41-
return data
42-
except ValidationError as err:
43-
return err.messages
38+
return schema.dump(user)

0 commit comments

Comments
 (0)