Skip to content

Commit d00ba15

Browse files
authored
chore: add statsd support to base API and refactor (#22887)
1 parent bed10a0 commit d00ba15

File tree

18 files changed

+167
-138
lines changed

18 files changed

+167
-138
lines changed

superset/advanced_data_type/api.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818

1919
from flask import current_app as app
2020
from flask.wrappers import Response
21-
from flask_appbuilder.api import BaseApi, expose, permission_name, protect, rison, safe
21+
from flask_appbuilder.api import expose, permission_name, protect, rison, safe
2222
from flask_babel import lazy_gettext as _
2323

2424
from superset.advanced_data_type.schemas import (
@@ -27,12 +27,13 @@
2727
)
2828
from superset.advanced_data_type.types import AdvancedDataTypeResponse
2929
from superset.extensions import event_logger
30+
from superset.views.base_api import BaseSupersetApi
3031

3132
config = app.config
3233
ADVANCED_DATA_TYPES = config["ADVANCED_DATA_TYPES"]
3334

3435

35-
class AdvancedDataTypeRestApi(BaseApi):
36+
class AdvancedDataTypeRestApi(BaseSupersetApi):
3637
"""
3738
Advanced Data Type Rest API
3839
-Will return available AdvancedDataTypes when the /types endpoint is accessed
@@ -41,7 +42,6 @@ class AdvancedDataTypeRestApi(BaseApi):
4142
"""
4243

4344
allow_browser_login = True
44-
include_route_methods = {"get", "get_types"}
4545
resource_name = "advanced_data_type"
4646
class_permission_name = "AdvancedDataType"
4747

superset/async_events/api.py

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,21 +18,19 @@
1818

1919
from flask import request, Response
2020
from flask_appbuilder import expose
21-
from flask_appbuilder.api import BaseApi, safe
21+
from flask_appbuilder.api import safe
2222
from flask_appbuilder.security.decorators import permission_name, protect
2323

2424
from superset.extensions import async_query_manager, event_logger
2525
from superset.utils.async_query_manager import AsyncQueryTokenException
26+
from superset.views.base_api import BaseSupersetApi
2627

2728
logger = logging.getLogger(__name__)
2829

2930

30-
class AsyncEventsRestApi(BaseApi):
31+
class AsyncEventsRestApi(BaseSupersetApi):
3132
resource_name = "async_event"
3233
allow_browser_login = True
33-
include_route_methods = {
34-
"events",
35-
}
3634

3735
@expose("/", methods=["GET"])
3836
@event_logger.log_this

superset/available_domains/api.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,21 +17,21 @@
1717
import logging
1818

1919
from flask import Response
20-
from flask_appbuilder.api import BaseApi, expose, protect, safe
20+
from flask_appbuilder.api import expose, protect, safe
2121

2222
from superset import conf
2323
from superset.available_domains.schemas import AvailableDomainsSchema
24-
from superset.constants import MODEL_API_RW_METHOD_PERMISSION_MAP, RouteMethod
24+
from superset.constants import MODEL_API_RW_METHOD_PERMISSION_MAP
2525
from superset.extensions import event_logger
26+
from superset.views.base_api import BaseSupersetApi, statsd_metrics
2627

2728
logger = logging.getLogger(__name__)
2829

2930

30-
class AvailableDomainsRestApi(BaseApi):
31+
class AvailableDomainsRestApi(BaseSupersetApi):
3132
available_domains_schema = AvailableDomainsSchema()
3233

3334
method_permission_name = MODEL_API_RW_METHOD_PERMISSION_MAP
34-
include_route_methods = {RouteMethod.GET}
3535
allow_browser_login = True
3636
class_permission_name = "AvailableDomains"
3737
resource_name = "available_domains"
@@ -41,6 +41,7 @@ class AvailableDomainsRestApi(BaseApi):
4141
@expose("/", methods=["GET"])
4242
@protect()
4343
@safe
44+
@statsd_metrics
4445
@event_logger.log_this_with_context(
4546
action=lambda self, *args, **kwargs: f"{self.__class__.__name__}.get",
4647
log_to_statsd=True,

superset/cachekeys/api.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626

2727
from superset.cachekeys.schemas import CacheInvalidationRequestSchema
2828
from superset.connectors.sqla.models import SqlaTable
29-
from superset.extensions import cache_manager, db, event_logger
29+
from superset.extensions import cache_manager, db, event_logger, stats_logger_manager
3030
from superset.models.cache import CacheKey
3131
from superset.views.base_api import BaseSupersetModelRestApi, statsd_metrics
3232

@@ -117,7 +117,9 @@ def invalidate(self) -> Response:
117117
)
118118
db.session.execute(delete_stmt)
119119
db.session.commit()
120-
self.stats_logger.gauge("invalidated_cache", len(cache_keys))
120+
stats_logger_manager.instance.gauge(
121+
"invalidated_cache", len(cache_keys)
122+
)
121123
logger.info(
122124
"Invalidated %s cache records for %s datasources",
123125
len(cache_keys),

superset/dashboards/permalink/api.py

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,10 @@
1717
import logging
1818

1919
from flask import request, Response
20-
from flask_appbuilder.api import BaseApi, expose, protect, safe
20+
from flask_appbuilder.api import expose, protect, safe
2121
from marshmallow import ValidationError
2222

23-
from superset.constants import MODEL_API_RW_METHOD_PERMISSION_MAP, RouteMethod
23+
from superset.constants import MODEL_API_RW_METHOD_PERMISSION_MAP
2424
from superset.dashboards.commands.exceptions import (
2525
DashboardAccessDeniedError,
2626
DashboardNotFoundError,
@@ -33,20 +33,14 @@
3333
from superset.dashboards.permalink.schemas import DashboardPermalinkPostSchema
3434
from superset.extensions import event_logger
3535
from superset.key_value.exceptions import KeyValueAccessDeniedError
36-
from superset.views.base_api import requires_json
36+
from superset.views.base_api import BaseSupersetApi, requires_json
3737

3838
logger = logging.getLogger(__name__)
3939

4040

41-
class DashboardPermalinkRestApi(BaseApi):
41+
class DashboardPermalinkRestApi(BaseSupersetApi):
4242
add_model_schema = DashboardPermalinkPostSchema()
4343
method_permission_name = MODEL_API_RW_METHOD_PERMISSION_MAP
44-
include_route_methods = {
45-
RouteMethod.POST,
46-
RouteMethod.PUT,
47-
RouteMethod.GET,
48-
RouteMethod.DELETE,
49-
}
5044
allow_browser_login = True
5145
class_permission_name = "DashboardPermalinkRestApi"
5246
resource_name = "dashboard"

superset/databases/decorators.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
from flask import g
2222
from flask_babel import lazy_gettext as _
2323

24+
from superset.extensions import stats_logger_manager
2425
from superset.models.core import Database
2526
from superset.sql_parse import Table
2627
from superset.utils.core import parse_js_uri_path_item
@@ -46,14 +47,14 @@ def wraps(
4647
return self.response_422(message=_("Table name undefined"))
4748
database: Database = self.datamodel.get(pk)
4849
if not database:
49-
self.stats_logger.incr(
50+
stats_logger_manager.instance.incr(
5051
f"database_not_found_{self.__class__.__name__}.select_star"
5152
)
5253
return self.response_404()
5354
if not self.appbuilder.sm.can_access_table(
5455
database, Table(table_name_parsed, schema_name_parsed)
5556
):
56-
self.stats_logger.incr(
57+
stats_logger_manager.instance.incr(
5758
f"permisssion_denied_{self.__class__.__name__}.select_star"
5859
)
5960
logger.warning(

superset/explore/api.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,10 @@
1717
import logging
1818

1919
from flask import g, request, Response
20-
from flask_appbuilder.api import BaseApi, expose, protect, safe
20+
from flask_appbuilder.api import expose, protect, safe
2121

2222
from superset.charts.commands.exceptions import ChartNotFoundError
23-
from superset.constants import MODEL_API_RW_METHOD_PERMISSION_MAP, RouteMethod
23+
from superset.constants import MODEL_API_RW_METHOD_PERMISSION_MAP
2424
from superset.explore.commands.get import GetExploreCommand
2525
from superset.explore.commands.parameters import CommandParameters
2626
from superset.explore.exceptions import DatasetAccessDeniedError, WrongEndpointError
@@ -31,13 +31,13 @@
3131
TemporaryCacheAccessDeniedError,
3232
TemporaryCacheResourceNotFoundError,
3333
)
34+
from superset.views.base_api import BaseSupersetApi, statsd_metrics
3435

3536
logger = logging.getLogger(__name__)
3637

3738

38-
class ExploreRestApi(BaseApi):
39+
class ExploreRestApi(BaseSupersetApi):
3940
method_permission_name = MODEL_API_RW_METHOD_PERMISSION_MAP
40-
include_route_methods = {RouteMethod.GET}
4141
allow_browser_login = True
4242
class_permission_name = "Explore"
4343
resource_name = "explore"
@@ -47,6 +47,7 @@ class ExploreRestApi(BaseApi):
4747
@expose("/", methods=["GET"])
4848
@protect()
4949
@safe
50+
@statsd_metrics
5051
@event_logger.log_this_with_context(
5152
action=lambda self, *args, **kwargs: f"{self.__class__.__name__}.get",
5253
log_to_statsd=True,

superset/explore/form_data/api.py

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,10 @@
1717
import logging
1818

1919
from flask import request, Response
20-
from flask_appbuilder.api import BaseApi, expose, protect, safe
20+
from flask_appbuilder.api import expose, protect, safe
2121
from marshmallow import ValidationError
2222

23-
from superset.constants import MODEL_API_RW_METHOD_PERMISSION_MAP, RouteMethod
23+
from superset.constants import MODEL_API_RW_METHOD_PERMISSION_MAP
2424
from superset.explore.form_data.commands.create import CreateFormDataCommand
2525
from superset.explore.form_data.commands.delete import DeleteFormDataCommand
2626
from superset.explore.form_data.commands.get import GetFormDataCommand
@@ -32,21 +32,15 @@
3232
TemporaryCacheAccessDeniedError,
3333
TemporaryCacheResourceNotFoundError,
3434
)
35-
from superset.views.base_api import requires_json
35+
from superset.views.base_api import BaseSupersetApi, requires_json, statsd_metrics
3636

3737
logger = logging.getLogger(__name__)
3838

3939

40-
class ExploreFormDataRestApi(BaseApi):
40+
class ExploreFormDataRestApi(BaseSupersetApi):
4141
add_model_schema = FormDataPostSchema()
4242
edit_model_schema = FormDataPutSchema()
4343
method_permission_name = MODEL_API_RW_METHOD_PERMISSION_MAP
44-
include_route_methods = {
45-
RouteMethod.POST,
46-
RouteMethod.PUT,
47-
RouteMethod.GET,
48-
RouteMethod.DELETE,
49-
}
5044
allow_browser_login = True
5145
class_permission_name = "ExploreFormDataRestApi"
5246
resource_name = "explore"
@@ -56,6 +50,7 @@ class ExploreFormDataRestApi(BaseApi):
5650
@expose("/form_data", methods=["POST"])
5751
@protect()
5852
@safe
53+
@statsd_metrics
5954
@event_logger.log_this_with_context(
6055
action=lambda self, *args, **kwargs: f"{self.__class__.__name__}.post",
6156
log_to_statsd=False,
@@ -120,6 +115,7 @@ def post(self) -> Response:
120115
@expose("/form_data/<string:key>", methods=["PUT"])
121116
@protect()
122117
@safe
118+
@statsd_metrics
123119
@event_logger.log_this_with_context(
124120
action=lambda self, *args, **kwargs: f"{self.__class__.__name__}.put",
125121
log_to_statsd=True,
@@ -193,6 +189,7 @@ def put(self, key: str) -> Response:
193189
@expose("/form_data/<string:key>", methods=["GET"])
194190
@protect()
195191
@safe
192+
@statsd_metrics
196193
@event_logger.log_this_with_context(
197194
action=lambda self, *args, **kwargs: f"{self.__class__.__name__}.get",
198195
log_to_statsd=True,
@@ -244,6 +241,7 @@ def get(self, key: str) -> Response:
244241
@expose("/form_data/<string:key>", methods=["DELETE"])
245242
@protect()
246243
@safe
244+
@statsd_metrics
247245
@event_logger.log_this_with_context(
248246
action=lambda self, *args, **kwargs: f"{self.__class__.__name__}.delete",
249247
log_to_statsd=True,

superset/explore/permalink/api.py

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,14 @@
1717
import logging
1818

1919
from flask import request, Response
20-
from flask_appbuilder.api import BaseApi, expose, protect, safe
20+
from flask_appbuilder.api import expose, protect, safe
2121
from marshmallow import ValidationError
2222

2323
from superset.charts.commands.exceptions import (
2424
ChartAccessDeniedError,
2525
ChartNotFoundError,
2626
)
27-
from superset.constants import MODEL_API_RW_METHOD_PERMISSION_MAP, RouteMethod
27+
from superset.constants import MODEL_API_RW_METHOD_PERMISSION_MAP
2828
from superset.datasets.commands.exceptions import (
2929
DatasetAccessDeniedError,
3030
DatasetNotFoundError,
@@ -35,20 +35,14 @@
3535
from superset.explore.permalink.schemas import ExplorePermalinkPostSchema
3636
from superset.extensions import event_logger
3737
from superset.key_value.exceptions import KeyValueAccessDeniedError
38-
from superset.views.base_api import requires_json
38+
from superset.views.base_api import BaseSupersetApi, requires_json, statsd_metrics
3939

4040
logger = logging.getLogger(__name__)
4141

4242

43-
class ExplorePermalinkRestApi(BaseApi):
43+
class ExplorePermalinkRestApi(BaseSupersetApi):
4444
add_model_schema = ExplorePermalinkPostSchema()
4545
method_permission_name = MODEL_API_RW_METHOD_PERMISSION_MAP
46-
include_route_methods = {
47-
RouteMethod.POST,
48-
RouteMethod.PUT,
49-
RouteMethod.GET,
50-
RouteMethod.DELETE,
51-
}
5246
allow_browser_login = True
5347
class_permission_name = "ExplorePermalinkRestApi"
5448
resource_name = "explore"
@@ -58,6 +52,7 @@ class ExplorePermalinkRestApi(BaseApi):
5852
@expose("/permalink", methods=["POST"])
5953
@protect()
6054
@safe
55+
@statsd_metrics
6156
@event_logger.log_this_with_context(
6257
action=lambda self, *args, **kwargs: f"{self.__class__.__name__}.post",
6358
log_to_statsd=False,
@@ -118,6 +113,7 @@ def post(self) -> Response:
118113
@expose("/permalink/<string:key>", methods=["GET"])
119114
@protect()
120115
@safe
116+
@statsd_metrics
121117
@event_logger.log_this_with_context(
122118
action=lambda self, *args, **kwargs: f"{self.__class__.__name__}.get",
123119
log_to_statsd=False,

superset/extensions/__init__.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
# under the License.
1717
import json
1818
import os
19-
from pathlib import Path
2019
from typing import Any, Callable, Dict, List, Optional
2120

2221
import celery
@@ -29,6 +28,7 @@
2928
from werkzeug.local import LocalProxy
3029

3130
from superset.extensions.ssh import SSHManagerFactory
31+
from superset.extensions.stats_logger import BaseStatsLoggerManager
3232
from superset.utils.async_query_manager import AsyncQueryManager
3333
from superset.utils.cache_manager import CacheManager
3434
from superset.utils.encrypt import EncryptedFieldFactory
@@ -127,5 +127,6 @@ def init_app(self, app: Flask) -> None:
127127
profiling = ProfilingExtension()
128128
results_backend_manager = ResultsBackendManager()
129129
security_manager = LocalProxy(lambda: appbuilder.sm)
130-
talisman = Talisman()
131130
ssh_manager_factory = SSHManagerFactory()
131+
stats_logger_manager = BaseStatsLoggerManager()
132+
talisman = Talisman()

0 commit comments

Comments
 (0)