[charts] feat: add statsd to charts api (#9571)

* add statsd to charts api

* update test for charts api

* [charts] add statsd asserts wrapper

* [charts] update api test

* removed white space
This commit is contained in:
Lily Kuang 2020-04-21 11:57:42 -07:00 committed by GitHub
parent ba691d3a27
commit 7cefc89c64
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 73 additions and 62 deletions

View File

@ -56,7 +56,11 @@ from superset.models.slice import Slice
from superset.tasks.thumbnails import cache_chart_thumbnail
from superset.utils.core import json_int_dttm_ser
from superset.utils.screenshots import ChartScreenshot
from superset.views.base_api import BaseSupersetModelRestApi, RelatedFieldFilter
from superset.views.base_api import (
BaseSupersetModelRestApi,
RelatedFieldFilter,
statsd_metrics,
)
from superset.views.filters import FilterRelatedOwners
logger = logging.getLogger(__name__)
@ -147,6 +151,7 @@ class ChartRestApi(BaseSupersetModelRestApi):
@expose("/", methods=["POST"])
@protect()
@safe
@statsd_metrics
def post(self) -> Response:
"""Creates a new Chart
---
@ -199,6 +204,7 @@ class ChartRestApi(BaseSupersetModelRestApi):
@expose("/<pk>", methods=["PUT"])
@protect()
@safe
@statsd_metrics
def put( # pylint: disable=too-many-return-statements, arguments-differ
self, pk: int
) -> Response:
@ -266,6 +272,7 @@ class ChartRestApi(BaseSupersetModelRestApi):
@expose("/<pk>", methods=["DELETE"])
@protect()
@safe
@statsd_metrics
def delete(self, pk: int) -> Response: # pylint: disable=arguments-differ
"""Deletes a Chart
---
@ -312,6 +319,7 @@ class ChartRestApi(BaseSupersetModelRestApi):
@expose("/", methods=["DELETE"])
@protect()
@safe
@statsd_metrics
@rison(get_delete_ids_schema)
def bulk_delete(
self, **kwargs: Any
@ -373,6 +381,7 @@ class ChartRestApi(BaseSupersetModelRestApi):
@event_logger.log_this
@protect()
@safe
@statsd_metrics
def data(self) -> Response:
"""
Takes a query context constructed in the client and returns payload
@ -429,6 +438,7 @@ class ChartRestApi(BaseSupersetModelRestApi):
@protect()
@rison(thumbnail_query_schema)
@safe
@statsd_metrics
def thumbnail(
self, pk: int, digest: str, **kwargs: Dict[str, bool]
) -> WerkzeugResponse:

View File

@ -103,7 +103,7 @@ class ChartApiTests(SupersetTestCase, ApiOwnersTestCaseMixin):
chart_id = self.insert_chart("name", [admin_id], 1).id
self.login(username="admin")
uri = f"api/v1/chart/{chart_id}"
rv = self.client.delete(uri)
rv = self.delete_assert_metric(uri, "delete")
self.assertEqual(rv.status_code, 200)
model = db.session.query(Slice).get(chart_id)
self.assertEqual(model, None)
@ -122,7 +122,7 @@ class ChartApiTests(SupersetTestCase, ApiOwnersTestCaseMixin):
self.login(username="admin")
argument = chart_ids
uri = f"api/v1/chart/?q={prison.dumps(argument)}"
rv = self.client.delete(uri)
rv = self.delete_assert_metric(uri, "bulk_delete")
self.assertEqual(rv.status_code, 200)
response = json.loads(rv.data.decode("utf-8"))
expected_response = {"message": f"Deleted {chart_count} charts"}
@ -139,7 +139,7 @@ class ChartApiTests(SupersetTestCase, ApiOwnersTestCaseMixin):
self.login(username="admin")
argument = chart_ids
uri = f"api/v1/chart/?q={prison.dumps(argument)}"
rv = self.client.delete(uri)
rv = self.delete_assert_metric(uri, "bulk_delete")
self.assertEqual(rv.status_code, 400)
def test_delete_not_found_chart(self):
@ -149,7 +149,7 @@ class ChartApiTests(SupersetTestCase, ApiOwnersTestCaseMixin):
self.login(username="admin")
chart_id = 1000
uri = f"api/v1/chart/{chart_id}"
rv = self.client.delete(uri)
rv = self.delete_assert_metric(uri, "delete")
self.assertEqual(rv.status_code, 404)
def test_delete_bulk_charts_not_found(self):
@ -161,7 +161,7 @@ class ChartApiTests(SupersetTestCase, ApiOwnersTestCaseMixin):
self.login(username="admin")
argument = chart_ids
uri = f"api/v1/chart/?q={prison.dumps(argument)}"
rv = self.client.delete(uri)
rv = self.delete_assert_metric(uri, "bulk_delete")
self.assertEqual(rv.status_code, 404)
def test_delete_chart_admin_not_owned(self):
@ -173,7 +173,7 @@ class ChartApiTests(SupersetTestCase, ApiOwnersTestCaseMixin):
self.login(username="admin")
uri = f"api/v1/chart/{chart_id}"
rv = self.client.delete(uri)
rv = self.delete_assert_metric(uri, "delete")
self.assertEqual(rv.status_code, 200)
model = db.session.query(Slice).get(chart_id)
self.assertEqual(model, None)
@ -193,7 +193,7 @@ class ChartApiTests(SupersetTestCase, ApiOwnersTestCaseMixin):
self.login(username="admin")
argument = chart_ids
uri = f"api/v1/chart/?q={prison.dumps(argument)}"
rv = self.client.delete(uri)
rv = self.delete_assert_metric(uri, "bulk_delete")
response = json.loads(rv.data.decode("utf-8"))
self.assertEqual(rv.status_code, 200)
expected_response = {"message": f"Deleted {chart_count} charts"}
@ -216,7 +216,7 @@ class ChartApiTests(SupersetTestCase, ApiOwnersTestCaseMixin):
chart = self.insert_chart("title", [user_alpha1.id], 1)
self.login(username="alpha2", password="password")
uri = f"api/v1/chart/{chart.id}"
rv = self.client.delete(uri)
rv = self.delete_assert_metric(uri, "delete")
self.assertEqual(rv.status_code, 403)
db.session.delete(chart)
db.session.delete(user_alpha1)
@ -248,7 +248,7 @@ class ChartApiTests(SupersetTestCase, ApiOwnersTestCaseMixin):
# verify we can't delete not owned charts
arguments = [chart.id for chart in charts]
uri = f"api/v1/chart/?q={prison.dumps(arguments)}"
rv = self.client.delete(uri)
rv = self.delete_assert_metric(uri, "bulk_delete")
self.assertEqual(rv.status_code, 403)
response = json.loads(rv.data.decode("utf-8"))
expected_response = {"message": "Forbidden"}
@ -257,7 +257,7 @@ class ChartApiTests(SupersetTestCase, ApiOwnersTestCaseMixin):
# # nothing is deleted in bulk with a list of owned and not owned charts
arguments = [chart.id for chart in charts] + [owned_chart.id]
uri = f"api/v1/chart/?q={prison.dumps(arguments)}"
rv = self.client.delete(uri)
rv = self.delete_assert_metric(uri, "bulk_delete")
self.assertEqual(rv.status_code, 403)
response = json.loads(rv.data.decode("utf-8"))
expected_response = {"message": "Forbidden"}
@ -288,7 +288,7 @@ class ChartApiTests(SupersetTestCase, ApiOwnersTestCaseMixin):
}
self.login(username="admin")
uri = f"api/v1/chart/"
rv = self.client.post(uri, json=chart_data)
rv = self.post_assert_metric(uri, chart_data, "post")
self.assertEqual(rv.status_code, 201)
data = json.loads(rv.data.decode("utf-8"))
model = db.session.query(Slice).get(data.get("id"))
@ -306,7 +306,7 @@ class ChartApiTests(SupersetTestCase, ApiOwnersTestCaseMixin):
}
self.login(username="admin")
uri = f"api/v1/chart/"
rv = self.client.post(uri, json=chart_data)
rv = self.post_assert_metric(uri, chart_data, "post")
self.assertEqual(rv.status_code, 201)
data = json.loads(rv.data.decode("utf-8"))
model = db.session.query(Slice).get(data.get("id"))
@ -325,7 +325,7 @@ class ChartApiTests(SupersetTestCase, ApiOwnersTestCaseMixin):
}
self.login(username="admin")
uri = f"api/v1/chart/"
rv = self.client.post(uri, json=chart_data)
rv = self.post_assert_metric(uri, chart_data, "post")
self.assertEqual(rv.status_code, 422)
response = json.loads(rv.data.decode("utf-8"))
expected_response = {"message": {"owners": ["Owners are invalid"]}}
@ -343,7 +343,7 @@ class ChartApiTests(SupersetTestCase, ApiOwnersTestCaseMixin):
}
self.login(username="admin")
uri = f"api/v1/chart/"
rv = self.client.post(uri, json=chart_data)
rv = self.post_assert_metric(uri, chart_data, "post")
self.assertEqual(rv.status_code, 400)
def test_create_chart_validate_datasource(self):
@ -357,7 +357,7 @@ class ChartApiTests(SupersetTestCase, ApiOwnersTestCaseMixin):
"datasource_type": "unknown",
}
uri = f"api/v1/chart/"
rv = self.client.post(uri, json=chart_data)
rv = self.post_assert_metric(uri, chart_data, "post")
self.assertEqual(rv.status_code, 422)
response = json.loads(rv.data.decode("utf-8"))
self.assertEqual(
@ -369,7 +369,7 @@ class ChartApiTests(SupersetTestCase, ApiOwnersTestCaseMixin):
"datasource_type": "table",
}
uri = f"api/v1/chart/"
rv = self.client.post(uri, json=chart_data)
rv = self.post_assert_metric(uri, chart_data, "post")
self.assertEqual(rv.status_code, 422)
response = json.loads(rv.data.decode("utf-8"))
self.assertEqual(
@ -397,7 +397,7 @@ class ChartApiTests(SupersetTestCase, ApiOwnersTestCaseMixin):
}
self.login(username="admin")
uri = f"api/v1/chart/{chart_id}"
rv = self.client.put(uri, json=chart_data)
rv = self.put_assert_metric(uri, chart_data, "put")
self.assertEqual(rv.status_code, 200)
model = db.session.query(Slice).get(chart_id)
related_dashboard = db.session.query(Dashboard).get(1)
@ -425,7 +425,7 @@ class ChartApiTests(SupersetTestCase, ApiOwnersTestCaseMixin):
chart_data = {"slice_name": "title1_changed"}
self.login(username="admin")
uri = f"api/v1/chart/{chart_id}"
rv = self.client.put(uri, json=chart_data)
rv = self.put_assert_metric(uri, chart_data, "put")
self.assertEqual(rv.status_code, 200)
model = db.session.query(Slice).get(chart_id)
self.assertIn(admin, model.owners)
@ -447,7 +447,7 @@ class ChartApiTests(SupersetTestCase, ApiOwnersTestCaseMixin):
self.login(username="alpha2", password="password")
chart_data = {"slice_name": "title1_changed"}
uri = f"api/v1/chart/{chart.id}"
rv = self.client.put(uri, json=chart_data)
rv = self.put_assert_metric(uri, chart_data, "put")
self.assertEqual(rv.status_code, 403)
db.session.delete(chart)
db.session.delete(user_alpha1)
@ -463,7 +463,7 @@ class ChartApiTests(SupersetTestCase, ApiOwnersTestCaseMixin):
self.login(username="admin")
chart_data = {"datasource_id": 1, "datasource_type": "unknown"}
uri = f"api/v1/chart/{chart.id}"
rv = self.client.put(uri, json=chart_data)
rv = self.put_assert_metric(uri, chart_data, "put")
self.assertEqual(rv.status_code, 422)
response = json.loads(rv.data.decode("utf-8"))
self.assertEqual(
@ -471,7 +471,7 @@ class ChartApiTests(SupersetTestCase, ApiOwnersTestCaseMixin):
)
chart_data = {"datasource_id": 0, "datasource_type": "table"}
uri = f"api/v1/chart/{chart.id}"
rv = self.client.put(uri, json=chart_data)
rv = self.put_assert_metric(uri, chart_data, "put")
self.assertEqual(rv.status_code, 422)
response = json.loads(rv.data.decode("utf-8"))
self.assertEqual(
@ -506,7 +506,7 @@ class ChartApiTests(SupersetTestCase, ApiOwnersTestCaseMixin):
chart = self.insert_chart("title", [admin.id], 1)
self.login(username="admin")
uri = f"api/v1/chart/{chart.id}"
rv = self.client.get(uri)
rv = self.get_assert_metric(uri, "get")
self.assertEqual(rv.status_code, 200)
expected_result = {
"cache_timeout": None,
@ -536,7 +536,7 @@ class ChartApiTests(SupersetTestCase, ApiOwnersTestCaseMixin):
chart_id = 1000
self.login(username="admin")
uri = f"api/v1/chart/{chart_id}"
rv = self.client.get(uri)
rv = self.get_assert_metric(uri, "get")
self.assertEqual(rv.status_code, 404)
def test_get_chart_no_data_access(self):
@ -559,7 +559,7 @@ class ChartApiTests(SupersetTestCase, ApiOwnersTestCaseMixin):
"""
self.login(username="admin")
uri = f"api/v1/chart/"
rv = self.client.get(uri)
rv = self.get_assert_metric(uri, "get_list")
self.assertEqual(rv.status_code, 200)
data = json.loads(rv.data.decode("utf-8"))
self.assertEqual(data["count"], 33)
@ -571,7 +571,7 @@ class ChartApiTests(SupersetTestCase, ApiOwnersTestCaseMixin):
self.login(username="admin")
arguments = {"filters": [{"col": "slice_name", "opr": "sw", "value": "G"}]}
uri = f"api/v1/chart/?q={prison.dumps(arguments)}"
rv = self.client.get(uri)
rv = self.get_assert_metric(uri, "get_list")
self.assertEqual(rv.status_code, 200)
data = json.loads(rv.data.decode("utf-8"))
self.assertEqual(data["count"], 5)
@ -595,7 +595,7 @@ class ChartApiTests(SupersetTestCase, ApiOwnersTestCaseMixin):
}
self.login(username="admin")
uri = f"api/v1/chart/?q={prison.dumps(arguments)}"
rv = self.client.get(uri)
rv = self.get_assert_metric(uri, "get_list")
self.assertEqual(rv.status_code, 200)
data = json.loads(rv.data.decode("utf-8"))
self.assertEqual(data["count"], 3)
@ -614,7 +614,7 @@ class ChartApiTests(SupersetTestCase, ApiOwnersTestCaseMixin):
self.logout()
self.login(username="gamma")
uri = f"api/v1/chart/?q={prison.dumps(arguments)}"
rv = self.client.get(uri)
rv = self.get_assert_metric(uri, "get_list")
self.assertEqual(rv.status_code, 200)
data = json.loads(rv.data.decode("utf-8"))
self.assertEqual(data["count"], 0)
@ -641,7 +641,7 @@ class ChartApiTests(SupersetTestCase, ApiOwnersTestCaseMixin):
arguments = {"page_size": 10, "page": 3}
uri = f"api/v1/chart/?q={prison.dumps(arguments)}"
rv = self.client.get(uri)
rv = self.get_assert_metric(uri, "get_list")
self.assertEqual(rv.status_code, 200)
data = json.loads(rv.data.decode("utf-8"))
self.assertEqual(len(data["result"]), 3)
@ -652,7 +652,7 @@ class ChartApiTests(SupersetTestCase, ApiOwnersTestCaseMixin):
"""
self.login(username="gamma")
uri = f"api/v1/chart/"
rv = self.client.get(uri)
rv = self.get_assert_metric(uri, "get_list")
self.assertEqual(rv.status_code, 200)
data = json.loads(rv.data.decode("utf-8"))
self.assertEqual(data["count"], 0)
@ -664,13 +664,14 @@ class ChartApiTests(SupersetTestCase, ApiOwnersTestCaseMixin):
self.login(username="admin")
query_context = self._get_query_context()
uri = "api/v1/chart/data"
rv = self.client.post(uri, json=query_context)
rv = self.post_assert_metric(uri, query_context, "data")
self.assertEqual(rv.status_code, 200)
data = json.loads(rv.data.decode("utf-8"))
self.assertEqual(data["result"][0]["rowcount"], 100)
def test_invalid_chart_data(self):
"""Query API: Test chart data query with invalid schema
"""
Query API: Test chart data query with invalid schema
"""
self.login(username="admin")
query_context = self._get_query_context()
@ -686,5 +687,5 @@ class ChartApiTests(SupersetTestCase, ApiOwnersTestCaseMixin):
self.login(username="gamma")
query_context = self._get_query_context()
uri = "api/v1/chart/data"
rv = self.client.post(uri, json=query_context)
rv = self.post_assert_metric(uri, query_context, "data")
self.assertEqual(rv.status_code, 401)