From fc92e6c1fa06dbcdcfbf1d100e4e5c9572584d43 Mon Sep 17 00:00:00 2001 From: EugeneTorap Date: Fri, 12 May 2023 08:18:51 +0300 Subject: [PATCH 1/2] Use new 'download_name' & 'max_age' params for send_file --- superset/charts/api.py | 2 +- superset/dashboards/api.py | 2 +- superset/databases/api.py | 2 +- superset/datasets/api.py | 2 +- superset/importexport/api.py | 2 +- superset/queries/saved_queries/api.py | 2 +- superset/views/base.py | 6 +++--- 7 files changed, 9 insertions(+), 9 deletions(-) diff --git a/superset/charts/api.py b/superset/charts/api.py index 8f9ecae8fb6b3..3235d3b0003eb 100644 --- a/superset/charts/api.py +++ b/superset/charts/api.py @@ -805,7 +805,7 @@ def export(self, **kwargs: Any) -> Response: buf, mimetype="application/zip", as_attachment=True, - attachment_filename=filename, + download_name=filename, ) if token: response.set_cookie(token, "done", max_age=600) diff --git a/superset/dashboards/api.py b/superset/dashboards/api.py index c197dabe3873c..cd481c241127b 100644 --- a/superset/dashboards/api.py +++ b/superset/dashboards/api.py @@ -819,7 +819,7 @@ def export(self, **kwargs: Any) -> Response: buf, mimetype="application/zip", as_attachment=True, - attachment_filename=filename, + download_name=filename, ) if token: response.set_cookie(token, "done", max_age=600) diff --git a/superset/databases/api.py b/superset/databases/api.py index 95b5089652fb5..4997edc0738f3 100644 --- a/superset/databases/api.py +++ b/superset/databases/api.py @@ -1058,7 +1058,7 @@ def export(self, **kwargs: Any) -> Response: buf, mimetype="application/zip", as_attachment=True, - attachment_filename=filename, + download_name=filename, ) if token: response.set_cookie(token, "done", max_age=600) diff --git a/superset/datasets/api.py b/superset/datasets/api.py index e2f1e51d7d7d5..c51be66f8f0cc 100644 --- a/superset/datasets/api.py +++ b/superset/datasets/api.py @@ -524,7 +524,7 @@ def export(self, **kwargs: Any) -> Response: buf, mimetype="application/zip", as_attachment=True, - attachment_filename=filename, + download_name=filename, ) if token: response.set_cookie(token, "done", max_age=600) diff --git a/superset/importexport/api.py b/superset/importexport/api.py index 3922a6e335c77..5fbf3747e8eb8 100644 --- a/superset/importexport/api.py +++ b/superset/importexport/api.py @@ -87,7 +87,7 @@ def export(self) -> Response: buf, mimetype="application/zip", as_attachment=True, - attachment_filename=filename, + download_name=filename, ) return response diff --git a/superset/queries/saved_queries/api.py b/superset/queries/saved_queries/api.py index f06220ca2b4cf..0c28e31a5296a 100644 --- a/superset/queries/saved_queries/api.py +++ b/superset/queries/saved_queries/api.py @@ -284,7 +284,7 @@ def export(self, **kwargs: Any) -> Response: buf, mimetype="application/zip", as_attachment=True, - attachment_filename=filename, + download_name=filename, ) if token: response.set_cookie(token, "done", max_age=600) diff --git a/superset/views/base.py b/superset/views/base.py index cc405adcfb11d..713772121b153 100644 --- a/superset/views/base.py +++ b/superset/views/base.py @@ -490,7 +490,7 @@ def show_http_exception(ex: HTTPException) -> FlaskResponse: and ex.code in {404, 500} ): path = resource_filename("superset", f"static/assets/{ex.code}.html") - return send_file(path, cache_timeout=0), ex.code + return send_file(path, max_age=0), ex.code return json_errors_response( errors=[ @@ -512,7 +512,7 @@ def show_command_errors(ex: CommandException) -> FlaskResponse: logger.warning("CommandException", exc_info=True) if "text/html" in request.accept_mimetypes and not config["DEBUG"]: path = resource_filename("superset", "static/assets/500.html") - return send_file(path, cache_timeout=0), 500 + return send_file(path, max_age=0), 500 extra = ex.normalized_messages() if isinstance(ex, CommandInvalidError) else {} return json_errors_response( @@ -534,7 +534,7 @@ def show_unexpected_exception(ex: Exception) -> FlaskResponse: logger.exception(ex) if "text/html" in request.accept_mimetypes and not config["DEBUG"]: path = resource_filename("superset", "static/assets/500.html") - return send_file(path, cache_timeout=0), 500 + return send_file(path, max_age=0), 500 return json_errors_response( errors=[ From 10d5f95c934b2bb0bda99489f3bbedd5b5163755 Mon Sep 17 00:00:00 2001 From: EugeneTorap Date: Fri, 12 May 2023 09:26:34 +0300 Subject: [PATCH 2/2] Bump mypy and explicit additional_dependencies for stubs --- .pre-commit-config.yaml | 16 ++++++++++++++-- superset/embedded/view.py | 2 ++ superset/extensions/__init__.py | 2 +- superset/initialization/__init__.py | 10 +++------- superset/jinja_context.py | 2 +- superset/result_set.py | 6 +++--- superset/sqllab/api.py | 4 ++-- superset/sqllab/query_render.py | 4 +--- superset/utils/encrypt.py | 2 +- superset/utils/pandas_postprocessing/boxplot.py | 4 ++-- superset/utils/url_map_converters.py | 2 +- superset/views/base.py | 2 +- superset/views/core.py | 6 ++++-- superset/views/utils.py | 4 ++-- .../integration_tests/reports/scheduler_tests.py | 2 +- tests/unit_tests/tasks/test_cron_util.py | 2 +- 16 files changed, 40 insertions(+), 30 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 562652aa15842..2ff79da9e96f0 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -20,11 +20,23 @@ repos: hooks: - id: isort - repo: https://github.com/pre-commit/mirrors-mypy - rev: v1.0.1 + rev: v1.3.0 hooks: - id: mypy args: [--check-untyped-defs] - additional_dependencies: [types-all] + additional_dependencies: + [ + types-simplejson, + types-python-dateutil, + types-requests, + types-redis, + types-pytz, + types-croniter, + types-PyYAML, + types-setuptools, + types-paramiko, + types-Markdown, + ] - repo: https://github.com/peterdemin/pip-compile-multi rev: v2.6.2 hooks: diff --git a/superset/embedded/view.py b/superset/embedded/view.py index 8dd383aadafec..b7062c0b5ee64 100644 --- a/superset/embedded/view.py +++ b/superset/embedded/view.py @@ -55,6 +55,8 @@ def embedded( if not embedded: abort(404) + assert embedded is not None + # validate request referrer in allowed domains is_referrer_allowed = not embedded.allowed_domains for domain in embedded.allowed_domains: diff --git a/superset/extensions/__init__.py b/superset/extensions/__init__.py index e2e5592e1edb9..f63338597284a 100644 --- a/superset/extensions/__init__.py +++ b/superset/extensions/__init__.py @@ -107,7 +107,7 @@ def __init__(self, interval: float = 1e-4) -> None: self.interval = interval def init_app(self, app: Flask) -> None: - app.wsgi_app = SupersetProfiler(app.wsgi_app, self.interval) # type: ignore + app.wsgi_app = SupersetProfiler(app.wsgi_app, self.interval) APP_DIR = os.path.join(os.path.dirname(__file__), os.path.pardir) diff --git a/superset/initialization/__init__.py b/superset/initialization/__init__.py index dd1c37f782534..90c1653d0b833 100644 --- a/superset/initialization/__init__.py +++ b/superset/initialization/__init__.py @@ -587,7 +587,7 @@ def configure_middlewares(self) -> None: CORS(self.superset_app, **self.config["CORS_OPTIONS"]) if self.config["ENABLE_PROXY_FIX"]: - self.superset_app.wsgi_app = ProxyFix( # type: ignore + self.superset_app.wsgi_app = ProxyFix( self.superset_app.wsgi_app, **self.config["PROXY_FIX_CONFIG"] ) @@ -606,9 +606,7 @@ def __call__( environ["wsgi.input_terminated"] = True return self.app(environ, start_response) - self.superset_app.wsgi_app = ChunkedEncodingFix( # type: ignore - self.superset_app.wsgi_app # type: ignore - ) + self.superset_app.wsgi_app = ChunkedEncodingFix(self.superset_app.wsgi_app) if self.config["UPLOAD_FOLDER"]: try: @@ -617,9 +615,7 @@ def __call__( pass for middleware in self.config["ADDITIONAL_MIDDLEWARE"]: - self.superset_app.wsgi_app = middleware( # type: ignore - self.superset_app.wsgi_app - ) + self.superset_app.wsgi_app = middleware(self.superset_app.wsgi_app) # Flask-Compress Compress(self.superset_app) diff --git a/superset/jinja_context.py b/superset/jinja_context.py index 45786856c6a66..360c4fc1f4517 100644 --- a/superset/jinja_context.py +++ b/superset/jinja_context.py @@ -189,7 +189,7 @@ def url_param( # pylint: disable=import-outside-toplevel from superset.views.utils import get_form_data - if has_request_context() and request.args.get(param): # type: ignore + if has_request_context() and request.args.get(param): return request.args.get(param, default) form_data, _ = get_form_data() diff --git a/superset/result_set.py b/superset/result_set.py index 1c4ae98dc9112..170de1869c830 100644 --- a/superset/result_set.py +++ b/superset/result_set.py @@ -70,14 +70,14 @@ def stringify_values(array: NDArray[Any]) -> NDArray[Any]: for obj in it: if na_obj := pd.isna(obj): # pandas type cannot be converted to string - obj[na_obj] = None # type: ignore + obj[na_obj] = None else: try: # for simple string conversions # this handles odd character types better - obj[...] = obj.astype(str) # type: ignore + obj[...] = obj.astype(str) except ValueError: - obj[...] = stringify(obj) # type: ignore + obj[...] = stringify(obj) return result diff --git a/superset/sqllab/api.py b/superset/sqllab/api.py index 70254359bbdfa..3c24bf1c26681 100644 --- a/superset/sqllab/api.py +++ b/superset/sqllab/api.py @@ -334,7 +334,7 @@ def _create_sql_json_command( ) execution_context_convertor = ExecutionContextConvertor() execution_context_convertor.set_max_row_in_display( - int(config.get("DISPLAY_MAX_ROW")) # type: ignore + int(config.get("DISPLAY_MAX_ROW")) ) return ExecuteSqlCommand( execution_context, @@ -359,7 +359,7 @@ def _create_sql_json_executor( sql_json_executor = SynchronousSqlJsonExecutor( query_dao, get_sql_results, - config.get("SQLLAB_TIMEOUT"), # type: ignore + config.get("SQLLAB_TIMEOUT"), is_feature_enabled("SQLLAB_BACKEND_PERSISTENCE"), ) return sql_json_executor diff --git a/superset/sqllab/query_render.py b/superset/sqllab/query_render.py index be7a50ed3a19b..1369e78db15de 100644 --- a/superset/sqllab/query_render.py +++ b/superset/sqllab/query_render.py @@ -75,9 +75,7 @@ def _validate( if is_feature_enabled("ENABLE_TEMPLATE_PROCESSING"): # pylint: disable=protected-access syntax_tree = sql_template_processor._env.parse(rendered_query) - undefined_parameters = find_undeclared_variables( # type: ignore - syntax_tree - ) + undefined_parameters = find_undeclared_variables(syntax_tree) if undefined_parameters: self._raise_undefined_parameter_exception( execution_context, undefined_parameters diff --git a/superset/utils/encrypt.py b/superset/utils/encrypt.py index 0c230c6cd9248..52b784bb23f88 100644 --- a/superset/utils/encrypt.py +++ b/superset/utils/encrypt.py @@ -60,7 +60,7 @@ def __init__(self) -> None: def init_app(self, app: Flask) -> None: self._config = app.config - self._concrete_type_adapter = self._config[ + self._concrete_type_adapter = self._config[ # type: ignore "SQLALCHEMY_ENCRYPTED_FIELD_TYPE_ADAPTER" ]() diff --git a/superset/utils/pandas_postprocessing/boxplot.py b/superset/utils/pandas_postprocessing/boxplot.py index d4c78bf15e8c8..399cf569fb25c 100644 --- a/superset/utils/pandas_postprocessing/boxplot.py +++ b/superset/utils/pandas_postprocessing/boxplot.py @@ -99,8 +99,8 @@ def whisker_low(series: Series) -> float: return np.nanpercentile(series, low) else: - whisker_high = np.max # type: ignore - whisker_low = np.min # type: ignore + whisker_high = np.max + whisker_low = np.min def outliers(series: Series) -> Set[float]: above = series[series > whisker_high(series)] diff --git a/superset/utils/url_map_converters.py b/superset/utils/url_map_converters.py index c5eaf3b359f06..fbd9c800b0a88 100644 --- a/superset/utils/url_map_converters.py +++ b/superset/utils/url_map_converters.py @@ -23,7 +23,7 @@ class RegexConverter(BaseConverter): def __init__(self, url_map: Map, *items: List[str]) -> None: - super().__init__(url_map) # type: ignore + super().__init__(url_map) self.regex = items[0] diff --git a/superset/views/base.py b/superset/views/base.py index 713772121b153..97d8da1d69e62 100644 --- a/superset/views/base.py +++ b/superset/views/base.py @@ -733,7 +733,7 @@ def apply_http_headers(response: Response) -> Response: """Applies the configuration's http headers to all responses""" # HTTP_HEADERS is deprecated, this provides backwards compatibility - response.headers.extend( # type: ignore + response.headers.extend( {**config["OVERRIDE_HTTP_HEADERS"], **config["HTTP_HEADERS"]} ) diff --git a/superset/views/core.py b/superset/views/core.py index dc0a247dcdfe7..b473172399cc5 100755 --- a/superset/views/core.py +++ b/superset/views/core.py @@ -1888,6 +1888,8 @@ def dashboard( if not dashboard: abort(404) + assert dashboard is not None + has_access_ = False for datasource in dashboard.datasources: datasource = DatasourceDAO.get_datasource( @@ -2419,7 +2421,7 @@ def _create_sql_json_command( ) execution_context_convertor = ExecutionContextConvertor() execution_context_convertor.set_max_row_in_display( - int(config.get("DISPLAY_MAX_ROW")) # type: ignore + int(config.get("DISPLAY_MAX_ROW")) ) return ExecuteSqlCommand( execution_context, @@ -2444,7 +2446,7 @@ def _create_sql_json_executor( sql_json_executor = SynchronousSqlJsonExecutor( query_dao, get_sql_results, - config.get("SQLLAB_TIMEOUT"), # type: ignore + config.get("SQLLAB_TIMEOUT"), is_feature_enabled("SQLLAB_BACKEND_PERSISTENCE"), ) return sql_json_executor diff --git a/superset/views/utils.py b/superset/views/utils.py index cd84d8e0a58dd..35a39fdc9c04d 100644 --- a/superset/views/utils.py +++ b/superset/views/utils.py @@ -153,7 +153,7 @@ def get_form_data( # pylint: disable=too-many-locals ) -> Tuple[Dict[str, Any], Optional[Slice]]: form_data: Dict[str, Any] = initial_form_data or {} - if has_request_context(): # type: ignore + if has_request_context(): # chart data API requests are JSON request_json_data = ( request.json["queries"][0] @@ -186,7 +186,7 @@ def get_form_data( # pylint: disable=too-many-locals json_data = form_data["queries"][0] if "queries" in form_data else {} form_data.update(json_data) - if has_request_context(): # type: ignore + if has_request_context(): url_id = request.args.get("r") if url_id: saved_url = db.session.query(models.Url).filter_by(id=url_id).first() diff --git a/tests/integration_tests/reports/scheduler_tests.py b/tests/integration_tests/reports/scheduler_tests.py index 15e945264d3fa..4b8968592b7e4 100644 --- a/tests/integration_tests/reports/scheduler_tests.py +++ b/tests/integration_tests/reports/scheduler_tests.py @@ -22,7 +22,7 @@ import pytest from flask_appbuilder.security.sqla.models import User from freezegun import freeze_time -from freezegun.api import FakeDatetime # type: ignore +from freezegun.api import FakeDatetime from superset.extensions import db from superset.reports.models import ReportScheduleType diff --git a/tests/unit_tests/tasks/test_cron_util.py b/tests/unit_tests/tasks/test_cron_util.py index d0f9ae21705e2..282dc99860f33 100644 --- a/tests/unit_tests/tasks/test_cron_util.py +++ b/tests/unit_tests/tasks/test_cron_util.py @@ -21,7 +21,7 @@ import pytz from dateutil import parser from freezegun import freeze_time -from freezegun.api import FakeDatetime # type: ignore +from freezegun.api import FakeDatetime from superset.tasks.cron_util import cron_schedule_window