Unverified Commit bb1966af authored by Marcos Iglesias's avatar Marcos Iglesias Committed by GitHub

feat: Related Dashboards endpoint on Flask app (#467)

* Trying to create an endpoint

* Getting tests ready

* Fixes lint error

* Adding missing type

* Adjusting return to not use the results_dict
parent a87354bd
......@@ -634,3 +634,62 @@ def get_dashboard_metadata() -> Response:
message = 'Encountered exception: ' + str(e)
logging.exception(message)
return make_response(jsonify({'dashboard': {}, 'msg': message}), HTTPStatus.INTERNAL_SERVER_ERROR)
@metadata_blueprint.route('/table/<path:table_key>/dashboards', methods=['GET'])
def get_related_dashboard_metadata(table_key: str) -> Response:
"""
Call metadata service endpoint to fetch related dashboard metadata
:return:
"""
try:
url = f'{app.config["METADATASERVICE_BASE"]}{TABLE_ENDPOINT}/{table_key}/dashboard/'
results_dict = _get_related_dashboards_metadata(url=url)
return make_response(jsonify(results_dict), results_dict.get('status_code', HTTPStatus.INTERNAL_SERVER_ERROR))
except Exception as e:
message = 'Encountered exception: ' + str(e)
logging.exception(message)
return make_response(jsonify({'dashboards': [], 'msg': message}), HTTPStatus.INTERNAL_SERVER_ERROR)
@action_logging
def _get_related_dashboards_metadata(*, url: str) -> Dict[str, Any]:
results_dict = {
'dashboards': {},
'msg': '',
}
try:
response = request_metadata(url=url)
except ValueError as e:
# envoy client BadResponse is a subclass of ValueError
message = 'Encountered exception: ' + str(e)
results_dict['msg'] = message
results_dict['status_code'] = getattr(e, 'code', HTTPStatus.INTERNAL_SERVER_ERROR)
logging.exception(message)
return results_dict
status_code = response.status_code
results_dict['status_code'] = status_code
if status_code != HTTPStatus.OK:
message = 'Encountered error: Related Dashboard Metadata request failed'
results_dict['msg'] = message
logging.error(message)
return results_dict
try:
dashboard_data_raw = response.json().get('dashboards', [])
return {
'dashboards': [marshall_dashboard_partial(dashboard) for dashboard in dashboard_data_raw],
'msg': 'Success',
'status_code': status_code
}
except Exception as e:
message = 'Encountered exception: ' + str(e)
results_dict['msg'] = message
logging.exception(message)
# explicitly raise the exception which will trigger 500 api response
results_dict['status_code'] = getattr(e, 'code', HTTPStatus.INTERNAL_SERVER_ERROR)
return results_dict
......@@ -150,6 +150,39 @@ class MetadataTest(unittest.TestCase):
'is_editable': True,
'last_updated_timestamp': None
}
self.expected_related_dashboard_response = {
"dashboards": [{
"group_name": "Group Test One",
"description": None,
"cluster": "gold",
"group_url": "https://app.mode.com/companyName/spaces/123",
"uri": "mode_dashboard://gold.123/234rt78",
"last_successful_run_timestamp": 1590505846,
"name": "Test Dashboard One",
"product": "mode",
"url": "https://app.mode.com/companyName/reports/234rt78"
}, {
"group_name": "Group Test Two",
"description": None,
"cluster": "gold",
"group_url": "https://app.mode.com/companyName/spaces/334",
"uri": "mode_dashboard://gold.334/34thyu56",
"last_successful_run_timestamp": 1590519704,
"name": "Test Dashboard Two",
"product": "mode",
"url": "https://app.mode.com/companyName/reports/34thyu56"
}, {
"group_name": "Group Test Three",
"description": None,
"cluster": "gold",
"group_url": "https://app.mode.com/companyName/spaces/789",
"uri": "mode_dashboard://gold.789/12ed34",
"last_successful_run_timestamp": 1590538191,
"name": "Test Dashboard Three",
"product": "mode",
"url": "https://app.mode.com/companyName/reports/12ed34"
}]
}
self.expected_programmatic_descriptions_with_config = {
"programmatic_descriptions": [
......@@ -964,3 +997,47 @@ class MetadataTest(unittest.TestCase):
data = json.loads(response.data)
self.assertEqual(response.status_code, HTTPStatus.INTERNAL_SERVER_ERROR)
self.assertCountEqual(data.get('dashboard'), {})
@responses.activate
def test_get_related_dashboards_success(self) -> None:
"""
Test get_related_dashboards API success
:return:
"""
test_table = 'db://cluster.schema/table'
url = local_app.config['METADATASERVICE_BASE'] + TABLE_ENDPOINT + '/' + test_table + '/dashboard/'
responses.add(responses.GET, url, json=self.expected_related_dashboard_response, status=HTTPStatus.OK)
with local_app.test_client() as test:
response = test.get(
'/api/metadata/v0/table/{0}/dashboards'.format(test_table)
)
data = json.loads(response.data)
self.assertEqual(response.status_code, HTTPStatus.OK)
self.assertEqual(
len(data.get('dashboards')),
len(self.expected_related_dashboard_response.get('dashboards'))
)
@responses.activate
def test_get_related_dashboards_failure(self) -> None:
"""
Test get_related_dashboards API failure
:return:
"""
test_table = 'db://cluster.schema/table'
url = local_app.config['METADATASERVICE_BASE'] + TABLE_ENDPOINT + '/' + test_table + '/dashboard/'
responses.add(responses.GET, url, json=self.expected_related_dashboard_response, status=HTTPStatus.BAD_REQUEST)
with local_app.test_client() as test:
response = test.get(
'/api/metadata/v0/table/{0}/dashboards'.format(test_table)
)
self.assertEqual(response.status_code, HTTPStatus.BAD_REQUEST)
expected = {
'dashboards': {},
'msg': 'Encountered error: Related Dashboard Metadata request failed',
'status_code': 400
}
self.assertEqual(response.json, expected)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment