From 7d3f7d18072c307da640d80a34bca7a642c3af2d Mon Sep 17 00:00:00 2001 From: Daniel Gaspar Date: Mon, 8 May 2023 11:04:22 +0100 Subject: [PATCH 01/25] chore: bump werkzeug and Flask --- requirements/base.txt | 13 ++++++++----- requirements/integration.txt | 8 ++++---- setup.py | 2 +- 3 files changed, 13 insertions(+), 10 deletions(-) diff --git a/requirements/base.txt b/requirements/base.txt index 9a8b734e8d3e..603260bff435 100644 --- a/requirements/base.txt +++ b/requirements/base.txt @@ -25,6 +25,8 @@ bcrypt==4.0.1 # via paramiko billiard==3.6.4.0 # via celery +blinker==1.6.2 + # via flask brotli==1.0.9 # via flask-compress cachelib==0.4.1 @@ -35,7 +37,7 @@ cffi==1.15.1 # via # cryptography # pynacl -click==8.0.4 +click==8.1.3 # via # apache-superset # celery @@ -75,7 +77,7 @@ dnspython==2.1.0 # via email-validator email-validator==1.1.3 # via flask-appbuilder -flask==2.1.3 +flask==2.3.2 # via # apache-superset # flask-appbuilder @@ -142,11 +144,11 @@ importlib-resources==5.12.0 # via limits isodate==0.6.0 # via apache-superset -itsdangerous==2.1.1 +itsdangerous==2.1.2 # via # flask # flask-wtf -jinja2==3.0.3 +jinja2==3.1.2 # via # flask # flask-babel @@ -168,6 +170,7 @@ markupsafe==2.1.1 # via # jinja2 # mako + # werkzeug # wtforms marshmallow==3.13.0 # via @@ -309,7 +312,7 @@ vine==5.0.0 # kombu wcwidth==0.2.5 # via prompt-toolkit -werkzeug==2.1.2 +werkzeug==2.3.3 # via # flask # flask-jwt-extended diff --git a/requirements/integration.txt b/requirements/integration.txt index 3b44aba46dfe..29c43279f9eb 100644 --- a/requirements/integration.txt +++ b/requirements/integration.txt @@ -30,7 +30,7 @@ packaging==21.3 pep517==0.11.0 # via build pip-compile-multi==2.6.2 - # via -r integration.in + # via -r requirements/integration.in pip-tools==6.8.0 # via pip-compile-multi platformdirs==2.6.2 @@ -38,7 +38,7 @@ platformdirs==2.6.2 pluggy==0.13.1 # via tox pre-commit==3.3.1 - # via -r integration.in + # via -r requirements/integration.in py==1.10.0 # via tox pyparsing==3.0.6 @@ -50,11 +50,11 @@ six==1.16.0 toml==0.10.2 # via tox tomli==1.2.1 - # via pep517 + # via build toposort==1.6 # via pip-compile-multi tox==3.25.1 - # via -r integration.in + # via -r requirements/integration.in virtualenv==20.17.1 # via # pre-commit diff --git a/setup.py b/setup.py index 48991ed389ec..6f9b6f3d8cbc 100644 --- a/setup.py +++ b/setup.py @@ -82,7 +82,7 @@ def get_git_sha() -> str: "cron-descriptor", "cryptography>=39.0.1, <40", "deprecation>=2.1.0, <2.2.0", - "flask>=2.1.3, <2.2", + "flask>=2.2.5, <3.0.0", "flask-appbuilder>=4.3.0, <5.0.0", "flask-caching>=1.10.1, <1.11", "flask-compress>=1.13, <2.0", From 187aae19c19f4ec096e56b21cc355609cad881c6 Mon Sep 17 00:00:00 2001 From: Daniel Gaspar Date: Mon, 8 May 2023 11:13:23 +0100 Subject: [PATCH 02/25] fix --- requirements/integration.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements/integration.txt b/requirements/integration.txt index 29c43279f9eb..8b6915d1e5e4 100644 --- a/requirements/integration.txt +++ b/requirements/integration.txt @@ -9,7 +9,7 @@ build==0.8.0 # via pip-tools cfgv==3.3.0 # via pre-commit -click==8.0.4 +click==8.1.3 # via # pip-compile-multi # pip-tools From 7a76a3ef9215b18ba2b732e022214864859cc24b Mon Sep 17 00:00:00 2001 From: Daniel Gaspar Date: Mon, 8 May 2023 11:30:54 +0100 Subject: [PATCH 03/25] fix --- requirements/base.txt | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/requirements/base.txt b/requirements/base.txt index 603260bff435..b459cf4b9c89 100644 --- a/requirements/base.txt +++ b/requirements/base.txt @@ -25,8 +25,6 @@ bcrypt==4.0.1 # via paramiko billiard==3.6.4.0 # via celery -blinker==1.6.2 - # via flask brotli==1.0.9 # via flask-compress cachelib==0.4.1 @@ -77,7 +75,7 @@ dnspython==2.1.0 # via email-validator email-validator==1.1.3 # via flask-appbuilder -flask==2.3.2 +flask==2.2.5 # via # apache-superset # flask-appbuilder From 4e344938aa767123d6721f989daca8bd2fc7fdde Mon Sep 17 00:00:00 2001 From: Daniel Gaspar Date: Mon, 8 May 2023 13:30:39 +0100 Subject: [PATCH 04/25] debug --- tests/integration_tests/core_tests.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/integration_tests/core_tests.py b/tests/integration_tests/core_tests.py index f036f18bf6aa..5f21bcff6c5d 100644 --- a/tests/integration_tests/core_tests.py +++ b/tests/integration_tests/core_tests.py @@ -1088,6 +1088,7 @@ def test_explore_json_async(self): "groupby": ["gender"], "row_limit": 100, } + return async_query_manager.init_app(app) self.login(username="admin") rv = self.client.post( @@ -1119,6 +1120,7 @@ def test_explore_json_async_results_format(self): "groupby": ["gender"], "row_limit": 100, } + return async_query_manager.init_app(app) self.login(username="admin") rv = self.client.post( From 56c28f8e5ada7b43550bbe1573c67bdc90171578 Mon Sep 17 00:00:00 2001 From: Daniel Gaspar Date: Mon, 8 May 2023 13:43:36 +0100 Subject: [PATCH 05/25] fix test --- tests/integration_tests/datasource_tests.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/integration_tests/datasource_tests.py b/tests/integration_tests/datasource_tests.py index 52bd9ec244cc..2e42c32c8b19 100644 --- a/tests/integration_tests/datasource_tests.py +++ b/tests/integration_tests/datasource_tests.py @@ -543,7 +543,7 @@ def test_get_samples_with_filters(test_client, login_as_admin, virtual_dataset): f"/datasource/samples?datasource_id={virtual_dataset.id}&datasource_type=table" ) rv = test_client.post(uri, json=None) - assert rv.status_code == 400 + assert rv.status_code == 415 rv = test_client.post(uri, json={}) assert rv.status_code == 200 From f3ed08e2197c6b92dc91ba4b40f1b3dba81951ce Mon Sep 17 00:00:00 2001 From: Daniel Gaspar Date: Mon, 8 May 2023 13:59:07 +0100 Subject: [PATCH 06/25] fix 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 8f9ecae8fb6b..3235d3b0003e 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 c197dabe3873..cd481c241127 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 95b5089652fb..4997edc0738f 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 e2f1e51d7d7d..c51be66f8f0c 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 3922a6e335c7..5fbf3747e8eb 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 f06220ca2b4c..0c28e31a5296 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 cc405adcfb11..713772121b15 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 358b4b47223a013fcf24d843d71b30d12e0ffc05 Mon Sep 17 00:00:00 2001 From: Daniel Gaspar Date: Mon, 8 May 2023 14:12:07 +0100 Subject: [PATCH 07/25] fix test --- tests/integration_tests/async_events/api_tests.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/integration_tests/async_events/api_tests.py b/tests/integration_tests/async_events/api_tests.py index a63f540dd0f8..d94a06b4bedf 100644 --- a/tests/integration_tests/async_events/api_tests.py +++ b/tests/integration_tests/async_events/api_tests.py @@ -33,6 +33,7 @@ def fetch_events(self, last_id: Optional[str] = None): @mock.patch("uuid.uuid4", return_value=UUID) def test_events(self, mock_uuid4): + return async_query_manager.init_app(app) self.login(username="admin") with mock.patch.object(async_query_manager._redis, "xrange") as mock_xrange: @@ -46,6 +47,7 @@ def test_events(self, mock_uuid4): @mock.patch("uuid.uuid4", return_value=UUID) def test_events_last_id(self, mock_uuid4): + return async_query_manager.init_app(app) self.login(username="admin") with mock.patch.object(async_query_manager._redis, "xrange") as mock_xrange: @@ -59,6 +61,7 @@ def test_events_last_id(self, mock_uuid4): @mock.patch("uuid.uuid4", return_value=UUID) def test_events_results(self, mock_uuid4): + return async_query_manager.init_app(app) self.login(username="admin") with mock.patch.object(async_query_manager._redis, "xrange") as mock_xrange: @@ -107,6 +110,7 @@ def test_events_results(self, mock_uuid4): self.assertEqual(response, expected) def test_events_no_login(self): + return async_query_manager.init_app(app) rv = self.fetch_events() assert rv.status_code == 401 From ee743e1842d959c9ed213e9ead49383b3b054130 Mon Sep 17 00:00:00 2001 From: Daniel Gaspar Date: Mon, 8 May 2023 14:24:53 +0100 Subject: [PATCH 08/25] debug --- tests/integration_tests/charts/data/api_tests.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/integration_tests/charts/data/api_tests.py b/tests/integration_tests/charts/data/api_tests.py index 5315bbbaed70..058678b64cad 100644 --- a/tests/integration_tests/charts/data/api_tests.py +++ b/tests/integration_tests/charts/data/api_tests.py @@ -625,6 +625,7 @@ def test_when_where_parameter_is_template_and_query_result_type__query_is_templa @with_feature_flags(GLOBAL_ASYNC_QUERIES=True) @pytest.mark.usefixtures("load_birth_names_dashboard_with_slices") def test_chart_data_async(self): + return self.logout() async_query_manager.init_app(app) self.login("admin") @@ -643,6 +644,7 @@ def test_chart_data_async_cached_sync_response(self): Chart data API: Test chart data query returns results synchronously when results are already cached. """ + return async_query_manager.init_app(app) class QueryContext: @@ -672,6 +674,7 @@ def test_chart_data_async_results_type(self): """ Chart data API: Test chart data query non-JSON format (async) """ + return async_query_manager.init_app(app) self.query_context_payload["result_type"] = "results" rv = self.post_assert_metric(CHART_DATA_URI, self.query_context_payload, "data") @@ -683,6 +686,7 @@ def test_chart_data_async_invalid_token(self): """ Chart data API: Test chart data query (async) """ + return async_query_manager.init_app(app) test_client.set_cookie( "localhost", app.config["GLOBAL_ASYNC_QUERIES_JWT_COOKIE_NAME"], "foo" From da866ce4e7d981637e90d1be50bc0d627c4b257d Mon Sep 17 00:00:00 2001 From: Daniel Gaspar Date: Mon, 8 May 2023 14:47:59 +0100 Subject: [PATCH 09/25] debug --- tests/integration_tests/charts/data/api_tests.py | 4 ++++ tests/integration_tests/tasks/async_queries_tests.py | 6 ++++++ 2 files changed, 10 insertions(+) diff --git a/tests/integration_tests/charts/data/api_tests.py b/tests/integration_tests/charts/data/api_tests.py index 058678b64cad..b77ed299e8ed 100644 --- a/tests/integration_tests/charts/data/api_tests.py +++ b/tests/integration_tests/charts/data/api_tests.py @@ -1002,6 +1002,7 @@ def test_chart_data_cache(self, cache_loader): """ Chart data cache API: Test chart data async cache request """ + return async_query_manager.init_app(app) cache_loader.load.return_value = self.query_context_payload orig_run = ChartDataCommand.run @@ -1028,6 +1029,7 @@ def test_chart_data_cache_run_failed(self, cache_loader): """ Chart data cache API: Test chart data async cache request with run failure """ + return async_query_manager.init_app(app) cache_loader.load.return_value = self.query_context_payload rv = self.get_assert_metric( @@ -1045,6 +1047,7 @@ def test_chart_data_cache_no_login(self, cache_loader): """ Chart data cache API: Test chart data async cache request (no login) """ + return self.logout() async_query_manager.init_app(app) cache_loader.load.return_value = self.query_context_payload @@ -1067,6 +1070,7 @@ def test_chart_data_cache_key_error(self): """ Chart data cache API: Test chart data async cache request with invalid cache key """ + return async_query_manager.init_app(app) rv = self.get_assert_metric( f"{CHART_DATA_URI}/test-cache-key", "data_from_cache" diff --git a/tests/integration_tests/tasks/async_queries_tests.py b/tests/integration_tests/tasks/async_queries_tests.py index 9e5c9657cf93..af1710e4943d 100644 --- a/tests/integration_tests/tasks/async_queries_tests.py +++ b/tests/integration_tests/tasks/async_queries_tests.py @@ -47,6 +47,7 @@ class TestAsyncQueries(SupersetTestCase): @mock.patch.object(async_query_manager, "update_job") @mock.patch.object(async_queries, "set_form_data") def test_load_chart_data_into_cache(self, mock_set_form_data, mock_update_job): + return async_query_manager.init_app(app) query_context = get_query_context("birth_names") user = security_manager.find_user("gamma") @@ -69,6 +70,7 @@ def test_load_chart_data_into_cache(self, mock_set_form_data, mock_update_job): ) @mock.patch.object(async_query_manager, "update_job") def test_load_chart_data_into_cache_error(self, mock_update_job, mock_run_command): + return async_query_manager.init_app(app) query_context = get_query_context("birth_names") user = security_manager.find_user("gamma") @@ -91,6 +93,7 @@ def test_load_chart_data_into_cache_error(self, mock_update_job, mock_run_comman def test_soft_timeout_load_chart_data_into_cache( self, mock_update_job, mock_run_command ): + return async_query_manager.init_app(app) user = security_manager.find_user("gamma") form_data = {} @@ -115,6 +118,7 @@ def test_soft_timeout_load_chart_data_into_cache( @pytest.mark.usefixtures("load_birth_names_dashboard_with_slices") @mock.patch.object(async_query_manager, "update_job") def test_load_explore_json_into_cache(self, mock_update_job): + return async_query_manager.init_app(app) table = self.get_table(name="birth_names") user = security_manager.find_user("gamma") @@ -146,6 +150,7 @@ def test_load_explore_json_into_cache(self, mock_update_job): def test_load_explore_json_into_cache_error( self, mock_set_form_data, mock_update_job ): + return async_query_manager.init_app(app) user = security_manager.find_user("gamma") form_data = {} @@ -169,6 +174,7 @@ def test_load_explore_json_into_cache_error( def test_soft_timeout_load_explore_json_into_cache( self, mock_update_job, mock_run_command ): + return async_query_manager.init_app(app) user = security_manager.find_user("gamma") form_data = {} From a80523639bc6fd2e64124c9dbef6f1b8f831d5f7 Mon Sep 17 00:00:00 2001 From: Daniel Gaspar Date: Mon, 8 May 2023 15:22:28 +0100 Subject: [PATCH 10/25] debug --- tests/integration_tests/tasks/async_queries_tests.py | 6 ------ 1 file changed, 6 deletions(-) diff --git a/tests/integration_tests/tasks/async_queries_tests.py b/tests/integration_tests/tasks/async_queries_tests.py index af1710e4943d..9e5c9657cf93 100644 --- a/tests/integration_tests/tasks/async_queries_tests.py +++ b/tests/integration_tests/tasks/async_queries_tests.py @@ -47,7 +47,6 @@ class TestAsyncQueries(SupersetTestCase): @mock.patch.object(async_query_manager, "update_job") @mock.patch.object(async_queries, "set_form_data") def test_load_chart_data_into_cache(self, mock_set_form_data, mock_update_job): - return async_query_manager.init_app(app) query_context = get_query_context("birth_names") user = security_manager.find_user("gamma") @@ -70,7 +69,6 @@ def test_load_chart_data_into_cache(self, mock_set_form_data, mock_update_job): ) @mock.patch.object(async_query_manager, "update_job") def test_load_chart_data_into_cache_error(self, mock_update_job, mock_run_command): - return async_query_manager.init_app(app) query_context = get_query_context("birth_names") user = security_manager.find_user("gamma") @@ -93,7 +91,6 @@ def test_load_chart_data_into_cache_error(self, mock_update_job, mock_run_comman def test_soft_timeout_load_chart_data_into_cache( self, mock_update_job, mock_run_command ): - return async_query_manager.init_app(app) user = security_manager.find_user("gamma") form_data = {} @@ -118,7 +115,6 @@ def test_soft_timeout_load_chart_data_into_cache( @pytest.mark.usefixtures("load_birth_names_dashboard_with_slices") @mock.patch.object(async_query_manager, "update_job") def test_load_explore_json_into_cache(self, mock_update_job): - return async_query_manager.init_app(app) table = self.get_table(name="birth_names") user = security_manager.find_user("gamma") @@ -150,7 +146,6 @@ def test_load_explore_json_into_cache(self, mock_update_job): def test_load_explore_json_into_cache_error( self, mock_set_form_data, mock_update_job ): - return async_query_manager.init_app(app) user = security_manager.find_user("gamma") form_data = {} @@ -174,7 +169,6 @@ def test_load_explore_json_into_cache_error( def test_soft_timeout_load_explore_json_into_cache( self, mock_update_job, mock_run_command ): - return async_query_manager.init_app(app) user = security_manager.find_user("gamma") form_data = {} From 93db41422fd03b52cc568f81e6116781f1bb56e6 Mon Sep 17 00:00:00 2001 From: Daniel Gaspar Date: Tue, 9 May 2023 12:00:43 +0100 Subject: [PATCH 11/25] fix test --- tests/integration_tests/charts/data/api_tests.py | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/tests/integration_tests/charts/data/api_tests.py b/tests/integration_tests/charts/data/api_tests.py index b77ed299e8ed..7392250ef6d2 100644 --- a/tests/integration_tests/charts/data/api_tests.py +++ b/tests/integration_tests/charts/data/api_tests.py @@ -28,10 +28,7 @@ from flask import Response from tests.integration_tests.conftest import with_feature_flags from superset.models.sql_lab import Query -from tests.integration_tests.base_tests import ( - SupersetTestCase, - test_client, -) +from tests.integration_tests.base_tests import SupersetTestCase, test_client from tests.integration_tests.annotation_layers.fixtures import create_annotation_layers from tests.integration_tests.fixtures.birth_names_dashboard import ( load_birth_names_dashboard_with_slices, @@ -1196,10 +1193,10 @@ def test_data_cache_default_timeout( def test_chart_cache_timeout( + load_energy_table_with_slice: List[Slice], test_client, login_as_admin, physical_query_context, - load_energy_table_with_slice: List[Slice], ): # should override datasource cache timeout @@ -1218,7 +1215,6 @@ def test_chart_cache_timeout( db.session.commit() physical_query_context["form_data"] = {"slice_id": slice_with_cache_timeout.id} - rv = test_client.post(CHART_DATA_URI, json=physical_query_context) assert rv.json["result"][0]["cache_timeout"] == 20 From cd953b00e5ff713662e84c1eeb065a666c752af9 Mon Sep 17 00:00:00 2001 From: Daniel Gaspar Date: Tue, 9 May 2023 12:53:52 +0100 Subject: [PATCH 12/25] fix test --- tests/integration_tests/dashboards/permalink/api_tests.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/integration_tests/dashboards/permalink/api_tests.py b/tests/integration_tests/dashboards/permalink/api_tests.py index 2323b56d6155..b20112334d1d 100644 --- a/tests/integration_tests/dashboards/permalink/api_tests.py +++ b/tests/integration_tests/dashboards/permalink/api_tests.py @@ -66,7 +66,7 @@ def permalink_salt() -> Iterator[str]: def test_post( - test_client, login_as_admin, dashboard_id: int, permalink_salt: str + dashboard_id: int, permalink_salt: str, test_client, login_as_admin ) -> None: resp = test_client.post(f"api/v1/dashboard/{dashboard_id}/permalink", json=STATE) assert resp.status_code == 201 @@ -93,14 +93,14 @@ def test_post_access_denied(test_client, login_as, dashboard_id: int): assert resp.status_code == 404 -def test_post_invalid_schema(test_client, login_as_admin, dashboard_id: int): +def test_post_invalid_schema(dashboard_id: int, test_client, login_as_admin): resp = test_client.post( f"api/v1/dashboard/{dashboard_id}/permalink", json={"foo": "bar"} ) assert resp.status_code == 400 -def test_get(test_client, login_as_admin, dashboard_id: int, permalink_salt: str): +def test_get(dashboard_id: int, permalink_salt: str, test_client, login_as_admin): key = test_client.post( f"api/v1/dashboard/{dashboard_id}/permalink", json=STATE ).json["key"] From eeb0ef25d56b9ea72e06a9d754ddd5801b509d72 Mon Sep 17 00:00:00 2001 From: Daniel Gaspar Date: Tue, 9 May 2023 14:21:39 +0100 Subject: [PATCH 13/25] fix test --- .../db_engine_specs/base_engine_spec_tests.py | 22 ++++++++++--------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/tests/integration_tests/db_engine_specs/base_engine_spec_tests.py b/tests/integration_tests/db_engine_specs/base_engine_spec_tests.py index 188fc94946a9..b53b57be0e34 100644 --- a/tests/integration_tests/db_engine_specs/base_engine_spec_tests.py +++ b/tests/integration_tests/db_engine_specs/base_engine_spec_tests.py @@ -447,17 +447,19 @@ def test_validate_parameters_missing(): "query": {}, } } - errors = BasicParametersMixin.validate_parameters(properties) - assert errors == [ - SupersetError( - message=( - "One or more parameters are missing: " "database, host, port, username" + with app.app_context(): + errors = BasicParametersMixin.validate_parameters(properties) + assert errors == [ + SupersetError( + message=( + "One or more parameters are missing: " + "database, host, port, username" + ), + error_type=SupersetErrorType.CONNECTION_MISSING_PARAMETERS_ERROR, + level=ErrorLevel.WARNING, + extra={"missing": ["database", "host", "port", "username"]}, ), - error_type=SupersetErrorType.CONNECTION_MISSING_PARAMETERS_ERROR, - level=ErrorLevel.WARNING, - extra={"missing": ["database", "host", "port", "username"]}, - ), - ] + ] @mock.patch("superset.db_engine_specs.base.is_hostname_valid") From 443473b0c5ed7690c744c34c594cb34b03359fc0 Mon Sep 17 00:00:00 2001 From: Daniel Gaspar Date: Tue, 9 May 2023 14:54:27 +0100 Subject: [PATCH 14/25] fix test --- .../db_engine_specs/base_engine_spec_tests.py | 60 ++++++++++--------- 1 file changed, 31 insertions(+), 29 deletions(-) diff --git a/tests/integration_tests/db_engine_specs/base_engine_spec_tests.py b/tests/integration_tests/db_engine_specs/base_engine_spec_tests.py index b53b57be0e34..15465d8a79c7 100644 --- a/tests/integration_tests/db_engine_specs/base_engine_spec_tests.py +++ b/tests/integration_tests/db_engine_specs/base_engine_spec_tests.py @@ -476,21 +476,22 @@ def test_validate_parameters_invalid_host(is_hostname_valid): "query": {"sslmode": "verify-full"}, } } - errors = BasicParametersMixin.validate_parameters(properties) - assert errors == [ - SupersetError( - message="One or more parameters are missing: port", - error_type=SupersetErrorType.CONNECTION_MISSING_PARAMETERS_ERROR, - level=ErrorLevel.WARNING, - extra={"missing": ["port"]}, - ), - SupersetError( - message="The hostname provided can't be resolved.", - error_type=SupersetErrorType.CONNECTION_INVALID_HOSTNAME_ERROR, - level=ErrorLevel.ERROR, - extra={"invalid": ["host"]}, - ), - ] + with app.app_context(): + errors = BasicParametersMixin.validate_parameters(properties) + assert errors == [ + SupersetError( + message="One or more parameters are missing: port", + error_type=SupersetErrorType.CONNECTION_MISSING_PARAMETERS_ERROR, + level=ErrorLevel.WARNING, + extra={"missing": ["port"]}, + ), + SupersetError( + message="The hostname provided can't be resolved.", + error_type=SupersetErrorType.CONNECTION_INVALID_HOSTNAME_ERROR, + level=ErrorLevel.ERROR, + extra={"invalid": ["host"]}, + ), + ] @mock.patch("superset.db_engine_specs.base.is_hostname_valid") @@ -509,20 +510,21 @@ def test_validate_parameters_port_closed(is_port_open, is_hostname_valid): "query": {"sslmode": "verify-full"}, } } - errors = BasicParametersMixin.validate_parameters(properties) - assert errors == [ - SupersetError( - message="The port is closed.", - error_type=SupersetErrorType.CONNECTION_PORT_CLOSED_ERROR, - level=ErrorLevel.ERROR, - extra={ - "invalid": ["port"], - "issue_codes": [ - {"code": 1008, "message": "Issue 1008 - The port is closed."} - ], - }, - ) - ] + with app.app_context(): + errors = BasicParametersMixin.validate_parameters(properties) + assert errors == [ + SupersetError( + message="The port is closed.", + error_type=SupersetErrorType.CONNECTION_PORT_CLOSED_ERROR, + level=ErrorLevel.ERROR, + extra={ + "invalid": ["port"], + "issue_codes": [ + {"code": 1008, "message": "Issue 1008 - The port is closed."} + ], + }, + ) + ] def test_get_indexes(): From 493c07879408bea2fdc4de8c1de57533e533978f Mon Sep 17 00:00:00 2001 From: Daniel Gaspar Date: Tue, 9 May 2023 15:57:16 +0100 Subject: [PATCH 15/25] fix tests --- tests/integration_tests/async_events/api_tests.py | 9 ++++----- tests/integration_tests/explore/permalink/api_tests.py | 8 ++++---- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/tests/integration_tests/async_events/api_tests.py b/tests/integration_tests/async_events/api_tests.py index d94a06b4bedf..ca308fda9a02 100644 --- a/tests/integration_tests/async_events/api_tests.py +++ b/tests/integration_tests/async_events/api_tests.py @@ -33,7 +33,7 @@ def fetch_events(self, last_id: Optional[str] = None): @mock.patch("uuid.uuid4", return_value=UUID) def test_events(self, mock_uuid4): - return + app._got_first_request = False async_query_manager.init_app(app) self.login(username="admin") with mock.patch.object(async_query_manager._redis, "xrange") as mock_xrange: @@ -47,7 +47,7 @@ def test_events(self, mock_uuid4): @mock.patch("uuid.uuid4", return_value=UUID) def test_events_last_id(self, mock_uuid4): - return + app._got_first_request = False async_query_manager.init_app(app) self.login(username="admin") with mock.patch.object(async_query_manager._redis, "xrange") as mock_xrange: @@ -61,7 +61,7 @@ def test_events_last_id(self, mock_uuid4): @mock.patch("uuid.uuid4", return_value=UUID) def test_events_results(self, mock_uuid4): - return + app._got_first_request = False async_query_manager.init_app(app) self.login(username="admin") with mock.patch.object(async_query_manager._redis, "xrange") as mock_xrange: @@ -110,8 +110,7 @@ def test_events_results(self, mock_uuid4): self.assertEqual(response, expected) def test_events_no_login(self): - return - async_query_manager.init_app(app) + # async_query_manager.init_app(app) rv = self.fetch_events() assert rv.status_code == 401 diff --git a/tests/integration_tests/explore/permalink/api_tests.py b/tests/integration_tests/explore/permalink/api_tests.py index 4c6a3c12ddfd..29a39f0d4ac0 100644 --- a/tests/integration_tests/explore/permalink/api_tests.py +++ b/tests/integration_tests/explore/permalink/api_tests.py @@ -67,7 +67,7 @@ def permalink_salt() -> Iterator[str]: def test_post( - test_client, login_as_admin, form_data: Dict[str, Any], permalink_salt: str + form_data: Dict[str, Any], permalink_salt: str, test_client, login_as_admin ): resp = test_client.post(f"api/v1/explore/permalink", json={"formData": form_data}) assert resp.status_code == 201 @@ -80,14 +80,14 @@ def test_post( db.session.commit() -def test_post_access_denied(test_client, login_as, form_data): +def test_post_access_denied(form_data, test_client, login_as): login_as("gamma") resp = test_client.post(f"api/v1/explore/permalink", json={"formData": form_data}) assert resp.status_code == 403 def test_get_missing_chart( - test_client, login_as_admin, chart, permalink_salt: str + chart, permalink_salt: str, test_client, login_as_admin ) -> None: from superset.key_value.models import KeyValueEntry @@ -121,7 +121,7 @@ def test_post_invalid_schema(test_client, login_as_admin) -> None: def test_get( - test_client, login_as_admin, form_data: Dict[str, Any], permalink_salt: str + form_data: Dict[str, Any], permalink_salt: str, test_client, login_as_admin ) -> None: resp = test_client.post(f"api/v1/explore/permalink", json={"formData": form_data}) data = json.loads(resp.data.decode("utf-8")) From 848bd5c2e2b2aeaa0109a4e6d70b6e5188f614a1 Mon Sep 17 00:00:00 2001 From: Daniel Gaspar Date: Tue, 9 May 2023 16:16:23 +0100 Subject: [PATCH 16/25] fix tests --- .../integration_tests/async_events/api_tests.py | 3 ++- tests/integration_tests/charts/data/api_tests.py | 16 ++++++++-------- tests/integration_tests/core_tests.py | 4 ++-- 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/tests/integration_tests/async_events/api_tests.py b/tests/integration_tests/async_events/api_tests.py index ca308fda9a02..5c12b29af49c 100644 --- a/tests/integration_tests/async_events/api_tests.py +++ b/tests/integration_tests/async_events/api_tests.py @@ -110,7 +110,8 @@ def test_events_results(self, mock_uuid4): self.assertEqual(response, expected) def test_events_no_login(self): - # async_query_manager.init_app(app) + app._got_first_request = False + async_query_manager.init_app(app) rv = self.fetch_events() assert rv.status_code == 401 diff --git a/tests/integration_tests/charts/data/api_tests.py b/tests/integration_tests/charts/data/api_tests.py index 7392250ef6d2..223a847a2c77 100644 --- a/tests/integration_tests/charts/data/api_tests.py +++ b/tests/integration_tests/charts/data/api_tests.py @@ -622,8 +622,8 @@ def test_when_where_parameter_is_template_and_query_result_type__query_is_templa @with_feature_flags(GLOBAL_ASYNC_QUERIES=True) @pytest.mark.usefixtures("load_birth_names_dashboard_with_slices") def test_chart_data_async(self): - return self.logout() + app._got_first_request = False async_query_manager.init_app(app) self.login("admin") rv = self.post_assert_metric(CHART_DATA_URI, self.query_context_payload, "data") @@ -641,7 +641,7 @@ def test_chart_data_async_cached_sync_response(self): Chart data API: Test chart data query returns results synchronously when results are already cached. """ - return + app._got_first_request = False async_query_manager.init_app(app) class QueryContext: @@ -671,7 +671,7 @@ def test_chart_data_async_results_type(self): """ Chart data API: Test chart data query non-JSON format (async) """ - return + app._got_first_request = False async_query_manager.init_app(app) self.query_context_payload["result_type"] = "results" rv = self.post_assert_metric(CHART_DATA_URI, self.query_context_payload, "data") @@ -683,7 +683,7 @@ def test_chart_data_async_invalid_token(self): """ Chart data API: Test chart data query (async) """ - return + app._got_first_request = False async_query_manager.init_app(app) test_client.set_cookie( "localhost", app.config["GLOBAL_ASYNC_QUERIES_JWT_COOKIE_NAME"], "foo" @@ -999,7 +999,7 @@ def test_chart_data_cache(self, cache_loader): """ Chart data cache API: Test chart data async cache request """ - return + app._got_first_request = False async_query_manager.init_app(app) cache_loader.load.return_value = self.query_context_payload orig_run = ChartDataCommand.run @@ -1026,7 +1026,7 @@ def test_chart_data_cache_run_failed(self, cache_loader): """ Chart data cache API: Test chart data async cache request with run failure """ - return + app._got_first_request = False async_query_manager.init_app(app) cache_loader.load.return_value = self.query_context_payload rv = self.get_assert_metric( @@ -1044,7 +1044,7 @@ def test_chart_data_cache_no_login(self, cache_loader): """ Chart data cache API: Test chart data async cache request (no login) """ - return + app._got_first_request = False self.logout() async_query_manager.init_app(app) cache_loader.load.return_value = self.query_context_payload @@ -1067,7 +1067,7 @@ def test_chart_data_cache_key_error(self): """ Chart data cache API: Test chart data async cache request with invalid cache key """ - return + app._got_first_request = False async_query_manager.init_app(app) rv = self.get_assert_metric( f"{CHART_DATA_URI}/test-cache-key", "data_from_cache" diff --git a/tests/integration_tests/core_tests.py b/tests/integration_tests/core_tests.py index 5f21bcff6c5d..2e9e28762041 100644 --- a/tests/integration_tests/core_tests.py +++ b/tests/integration_tests/core_tests.py @@ -1088,7 +1088,7 @@ def test_explore_json_async(self): "groupby": ["gender"], "row_limit": 100, } - return + app._got_first_request = False async_query_manager.init_app(app) self.login(username="admin") rv = self.client.post( @@ -1120,7 +1120,7 @@ def test_explore_json_async_results_format(self): "groupby": ["gender"], "row_limit": 100, } - return + app._got_first_request = False async_query_manager.init_app(app) self.login(username="admin") rv = self.client.post( From 8c7e4a41485c85f2b07c51a5c5b72f25af695702 Mon Sep 17 00:00:00 2001 From: Daniel Gaspar Date: Tue, 9 May 2023 16:31:45 +0100 Subject: [PATCH 17/25] fix tests --- tests/integration_tests/charts/data/api_tests.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/integration_tests/charts/data/api_tests.py b/tests/integration_tests/charts/data/api_tests.py index 223a847a2c77..2dd25b884407 100644 --- a/tests/integration_tests/charts/data/api_tests.py +++ b/tests/integration_tests/charts/data/api_tests.py @@ -1045,8 +1045,8 @@ def test_chart_data_cache_no_login(self, cache_loader): Chart data cache API: Test chart data async cache request (no login) """ app._got_first_request = False - self.logout() async_query_manager.init_app(app) + self.logout() cache_loader.load.return_value = self.query_context_payload orig_run = ChartDataCommand.run From 832da2c57700bf47ee0876cf39af7c57aacf6f16 Mon Sep 17 00:00:00 2001 From: Daniel Gaspar Date: Wed, 10 May 2023 13:15:41 +0100 Subject: [PATCH 18/25] fix tests --- tests/integration_tests/reports/commands_tests.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/tests/integration_tests/reports/commands_tests.py b/tests/integration_tests/reports/commands_tests.py index cad6a75a5d25..9be3738ea2ee 100644 --- a/tests/integration_tests/reports/commands_tests.py +++ b/tests/integration_tests/reports/commands_tests.py @@ -659,13 +659,13 @@ def test_email_chart_report_schedule( ) # assert that the link sent is correct assert ( - 'Explore in Superset' in email_mock.call_args[0][2] ) # Assert the email smtp address assert email_mock.call_args[0][0] == notification_targets[0] - # Assert the email inline screenshot + # Assert the email inline screenshotq smtp_images = email_mock.call_args[1]["images"] assert smtp_images[list(smtp_images.keys())[0]] == SCREENSHOT_FILE # Assert logs are correct @@ -714,7 +714,7 @@ def _screenshot_side_effect(user: User) -> Optional[bytes]: # assert that the link sent is correct assert ( - 'Explore in Superset' in email_mock.call_args[0][2] ) @@ -759,7 +759,7 @@ def test_email_chart_report_schedule_force_screenshot( ) # assert that the link sent is correct assert ( - 'Explore in Superset' in email_mock.call_args[0][2] ) @@ -796,7 +796,7 @@ def test_email_chart_alert_schedule( notification_targets = get_target_from_report_schedule(create_alert_email_chart) # assert that the link sent is correct assert ( - 'Explore in Superset' in email_mock.call_args[0][2] ) @@ -868,7 +868,7 @@ def test_email_chart_report_schedule_with_csv( ) # assert that the link sent is correct assert ( - 'Explore in Superset' in email_mock.call_args[0][2] ) @@ -1202,7 +1202,7 @@ def test_slack_chart_report_schedule_with_errors( error_logs = get_error_logs_query(create_report_slack_chart) # check that we have two logs for each error - assert error_logs.count() == (len(slack_errors) + notification_logs_count) * 2 + assert error_logs.count() == (len(slack_errors) + notification_logs_count) # check that each error has a message assert len([log.error_message for log in error_logs]) == error_logs.count() From debbb4874a45cc99c083e40410eea0f29f9997ab Mon Sep 17 00:00:00 2001 From: Daniel Gaspar Date: Wed, 10 May 2023 13:41:16 +0100 Subject: [PATCH 19/25] fix tests --- tests/integration_tests/reports/commands_tests.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/integration_tests/reports/commands_tests.py b/tests/integration_tests/reports/commands_tests.py index 9be3738ea2ee..4768f9471dce 100644 --- a/tests/integration_tests/reports/commands_tests.py +++ b/tests/integration_tests/reports/commands_tests.py @@ -1202,7 +1202,7 @@ def test_slack_chart_report_schedule_with_errors( error_logs = get_error_logs_query(create_report_slack_chart) # check that we have two logs for each error - assert error_logs.count() == (len(slack_errors) + notification_logs_count) + assert error_logs.count() == (len(slack_errors) + notification_logs_count) * 2 # check that each error has a message assert len([log.error_message for log in error_logs]) == error_logs.count() From e84b6a7620a3b5e03a92e98893788a89ac467556 Mon Sep 17 00:00:00 2001 From: Daniel Gaspar Date: Wed, 10 May 2023 14:22:29 +0100 Subject: [PATCH 20/25] fix tests --- tests/integration_tests/reports/commands_tests.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/integration_tests/reports/commands_tests.py b/tests/integration_tests/reports/commands_tests.py index 4768f9471dce..8dd3b1a50fc3 100644 --- a/tests/integration_tests/reports/commands_tests.py +++ b/tests/integration_tests/reports/commands_tests.py @@ -1296,7 +1296,7 @@ def test_slack_chart_report_schedule_with_text( | 1 | c21 | c22 | c23 |""" assert table_markdown in post_message_mock.call_args[1]["text"] assert ( - f"" + f"" in post_message_mock.call_args[1]["text"] ) From 7e4403331c0b13ddbb52062fcac0fb214fccc41e Mon Sep 17 00:00:00 2001 From: Daniel Gaspar Date: Wed, 10 May 2023 16:01:18 +0100 Subject: [PATCH 21/25] final fix? --- .../security/analytics_db_safety_tests.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/tests/integration_tests/security/analytics_db_safety_tests.py b/tests/integration_tests/security/analytics_db_safety_tests.py index 7e36268e3028..9c40050c0ad9 100644 --- a/tests/integration_tests/security/analytics_db_safety_tests.py +++ b/tests/integration_tests/security/analytics_db_safety_tests.py @@ -21,6 +21,7 @@ from superset.exceptions import SupersetSecurityException from superset.security.analytics_db_safety import check_sqlalchemy_uri +from tests.integration_tests.test_app import app @pytest.mark.parametrize( @@ -83,9 +84,10 @@ def test_check_sqlalchemy_uri( sqlalchemy_uri: str, error: bool, error_message: Optional[str] ): - if error: - with pytest.raises(SupersetSecurityException) as excinfo: + with app.app_context(): + if error: + with pytest.raises(SupersetSecurityException) as excinfo: + check_sqlalchemy_uri(make_url(sqlalchemy_uri)) + assert str(excinfo.value) == error_message + else: check_sqlalchemy_uri(make_url(sqlalchemy_uri)) - assert str(excinfo.value) == error_message - else: - check_sqlalchemy_uri(make_url(sqlalchemy_uri)) From ebfcd83bd416345b20b559e5cd045ca0d4815ae7 Mon Sep 17 00:00:00 2001 From: Daniel Gaspar Date: Thu, 11 May 2023 09:12:00 +0100 Subject: [PATCH 22/25] fix test --- tests/integration_tests/tasks/async_queries_tests.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/integration_tests/tasks/async_queries_tests.py b/tests/integration_tests/tasks/async_queries_tests.py index 9e5c9657cf93..50806ee67739 100644 --- a/tests/integration_tests/tasks/async_queries_tests.py +++ b/tests/integration_tests/tasks/async_queries_tests.py @@ -47,6 +47,7 @@ class TestAsyncQueries(SupersetTestCase): @mock.patch.object(async_query_manager, "update_job") @mock.patch.object(async_queries, "set_form_data") def test_load_chart_data_into_cache(self, mock_set_form_data, mock_update_job): + app._got_first_request = False async_query_manager.init_app(app) query_context = get_query_context("birth_names") user = security_manager.find_user("gamma") @@ -69,6 +70,7 @@ def test_load_chart_data_into_cache(self, mock_set_form_data, mock_update_job): ) @mock.patch.object(async_query_manager, "update_job") def test_load_chart_data_into_cache_error(self, mock_update_job, mock_run_command): + app._got_first_request = False async_query_manager.init_app(app) query_context = get_query_context("birth_names") user = security_manager.find_user("gamma") @@ -91,6 +93,7 @@ def test_load_chart_data_into_cache_error(self, mock_update_job, mock_run_comman def test_soft_timeout_load_chart_data_into_cache( self, mock_update_job, mock_run_command ): + app._got_first_request = False async_query_manager.init_app(app) user = security_manager.find_user("gamma") form_data = {} @@ -115,6 +118,7 @@ def test_soft_timeout_load_chart_data_into_cache( @pytest.mark.usefixtures("load_birth_names_dashboard_with_slices") @mock.patch.object(async_query_manager, "update_job") def test_load_explore_json_into_cache(self, mock_update_job): + app._got_first_request = False async_query_manager.init_app(app) table = self.get_table(name="birth_names") user = security_manager.find_user("gamma") @@ -146,6 +150,7 @@ def test_load_explore_json_into_cache(self, mock_update_job): def test_load_explore_json_into_cache_error( self, mock_set_form_data, mock_update_job ): + app._got_first_request = False async_query_manager.init_app(app) user = security_manager.find_user("gamma") form_data = {} @@ -169,6 +174,7 @@ def test_load_explore_json_into_cache_error( def test_soft_timeout_load_explore_json_into_cache( self, mock_update_job, mock_run_command ): + app._got_first_request = False async_query_manager.init_app(app) user = security_manager.find_user("gamma") form_data = {} From e928a035713652e0a39bf26c90982f0bb443e1f9 Mon Sep 17 00:00:00 2001 From: Daniel Gaspar Date: Thu, 11 May 2023 15:13:04 +0100 Subject: [PATCH 23/25] fix test --- tests/integration_tests/utils/core_tests.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/integration_tests/utils/core_tests.py b/tests/integration_tests/utils/core_tests.py index 29b94d6d37ee..1a2fa6a5218c 100644 --- a/tests/integration_tests/utils/core_tests.py +++ b/tests/integration_tests/utils/core_tests.py @@ -17,6 +17,7 @@ import pytest from superset.utils.core import form_data_to_adhoc, simple_filter_to_adhoc +from tests.integration_tests.test_app import app def test_simple_filter_to_adhoc_generates_deterministic_values(): @@ -81,4 +82,5 @@ def test_form_data_to_adhoc_incorrect_clause_type(): form_data = {"where": "1 = 1", "having": "count(*) > 1"} with pytest.raises(ValueError): - form_data_to_adhoc(form_data, "foobar") + with app.app_context(): + form_data_to_adhoc(form_data, "foobar") From 8ec67386c127fe022a183d4ddc57e6f7eaf5b4c7 Mon Sep 17 00:00:00 2001 From: Daniel Gaspar Date: Thu, 11 May 2023 16:26:20 +0100 Subject: [PATCH 24/25] disable mypy on flask 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 +++--- tests/integration_tests/reports/commands_tests.py | 2 +- 8 files changed, 10 insertions(+), 10 deletions(-) diff --git a/superset/charts/api.py b/superset/charts/api.py index 3235d3b0003e..d87f0ed37de6 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, - download_name=filename, + download_name=filename, # type: ignore[call-arg] ) if token: response.set_cookie(token, "done", max_age=600) diff --git a/superset/dashboards/api.py b/superset/dashboards/api.py index cd481c241127..c5b2e90356b2 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, - download_name=filename, + download_name=filename, # type: ignore[call-arg] ) if token: response.set_cookie(token, "done", max_age=600) diff --git a/superset/databases/api.py b/superset/databases/api.py index 4997edc0738f..9cda96834846 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, - download_name=filename, + download_name=filename, # type: ignore[call-arg] ) if token: response.set_cookie(token, "done", max_age=600) diff --git a/superset/datasets/api.py b/superset/datasets/api.py index c51be66f8f0c..1d0f1c72ba64 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, - download_name=filename, + download_name=filename, # type: ignore[call-arg] ) if token: response.set_cookie(token, "done", max_age=600) diff --git a/superset/importexport/api.py b/superset/importexport/api.py index 5fbf3747e8eb..c382508d41c1 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, - download_name=filename, + download_name=filename, # type: ignore[call-arg] ) return response diff --git a/superset/queries/saved_queries/api.py b/superset/queries/saved_queries/api.py index 0c28e31a5296..35b088599354 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, - download_name=filename, + download_name=filename, # type: ignore[call-arg] ) if token: response.set_cookie(token, "done", max_age=600) diff --git a/superset/views/base.py b/superset/views/base.py index 713772121b15..0a3ccab91e39 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, max_age=0), ex.code + return send_file(path, max_age=0), ex.code # type: ignore[call-arg] 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, max_age=0), 500 + return send_file(path, max_age=0), 500 # type: ignore[call-arg] 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, max_age=0), 500 + return send_file(path, max_age=0), 500 # type: ignore[call-arg] return json_errors_response( errors=[ diff --git a/tests/integration_tests/reports/commands_tests.py b/tests/integration_tests/reports/commands_tests.py index 8dd3b1a50fc3..a81bc6fa66ad 100644 --- a/tests/integration_tests/reports/commands_tests.py +++ b/tests/integration_tests/reports/commands_tests.py @@ -665,7 +665,7 @@ def test_email_chart_report_schedule( ) # Assert the email smtp address assert email_mock.call_args[0][0] == notification_targets[0] - # Assert the email inline screenshotq + # Assert the email inline screenshot smtp_images = email_mock.call_args[1]["images"] assert smtp_images[list(smtp_images.keys())[0]] == SCREENSHOT_FILE # Assert logs are correct From 5f80dcf1f6a2e3de2570e42e44858e6c0b264a81 Mon Sep 17 00:00:00 2001 From: Daniel Gaspar Date: Fri, 12 May 2023 10:25:04 +0100 Subject: [PATCH 25/25] new pip-compile-multi --- requirements/base.txt | 3 +-- requirements/docker.txt | 4 ++++ requirements/integration.txt | 12 ++++++------ requirements/testing.txt | 2 ++ 4 files changed, 13 insertions(+), 8 deletions(-) diff --git a/requirements/base.txt b/requirements/base.txt index 3e645769c406..4ffcc24b1bc1 100644 --- a/requirements/base.txt +++ b/requirements/base.txt @@ -122,8 +122,6 @@ geographiclib==1.52 # via geopy geopy==2.2.0 # via apache-superset -greenlet==2.0.2 - # via sqlalchemy gunicorn==20.1.0 # via apache-superset hashids==1.3.1 @@ -308,6 +306,7 @@ wcwidth==0.2.5 # via prompt-toolkit werkzeug==2.3.3 # via + # apache-superset # flask # flask-jwt-extended # flask-login diff --git a/requirements/docker.txt b/requirements/docker.txt index cd2a6e175c58..64d3e46ec26d 100644 --- a/requirements/docker.txt +++ b/requirements/docker.txt @@ -12,6 +12,10 @@ # -r requirements/docker.in gevent==22.10.2 # via -r requirements/docker.in +greenlet==2.0.2 + # via + # -r requirements/docker.in + # gevent psycopg2-binary==2.9.6 # via apache-superset zope-event==4.5.0 diff --git a/requirements/integration.txt b/requirements/integration.txt index 7d5a0d3cb2b1..b9fdb03e0c22 100644 --- a/requirements/integration.txt +++ b/requirements/integration.txt @@ -11,6 +11,8 @@ cachetools==5.3.0 # via tox cfgv==3.3.1 # via pre-commit +chardet==5.1.0 + # via tox click==8.1.3 # via # pip-compile-multi @@ -44,19 +46,17 @@ pluggy==1.0.0 # via tox pre-commit==3.3.1 # via -r requirements/integration.in -py==1.10.0 pyproject-api==1.5.1 # via tox pyproject-hooks==1.0.0 # via build pyyaml==5.4.1 # via pre-commit -six==1.16.0 - # via tox -toml==0.10.2 - # via tox tomli==2.0.1 - # via build + # via + # build + # pyproject-api + # tox toposort==1.10 # via pip-compile-multi tox==4.5.1 diff --git a/requirements/testing.txt b/requirements/testing.txt index 1e5471354683..a4fd3f2731d7 100644 --- a/requirements/testing.txt +++ b/requirements/testing.txt @@ -107,6 +107,8 @@ pydata-google-auth==1.7.0 # via pandas-gbq pyfakefs==5.2.2 # via -r requirements/testing.in +pyhive[presto]==0.6.5 + # via apache-superset pytest==7.3.1 # via # -r requirements/testing.in