diff --git a/superset/commands/report/execute.py b/superset/commands/report/execute.py index 637898a7a0..52c566f99d 100644 --- a/superset/commands/report/execute.py +++ b/superset/commands/report/execute.py @@ -21,6 +21,7 @@ from uuid import UUID import pandas as pd from celery.exceptions import SoftTimeLimitExceeded +from flask import current_app from superset import app, db, security_manager from superset.commands.base import BaseCommand @@ -44,6 +45,7 @@ from superset.commands.report.exceptions import ( ReportScheduleUnexpectedError, ReportScheduleWorkingTimeoutError, ) +from superset.commands.report.utils import remove_post_processed from superset.common.chart_data import ChartDataResultFormat, ChartDataResultType from superset.daos.report import ( REPORT_SCHEDULE_ERROR_NOTIFICATION_MARKER, @@ -251,6 +253,8 @@ class BaseReportState: def _get_csv_data(self) -> bytes: url = self._get_url(result_format=ChartDataResultFormat.CSV) + if not current_app.config["CSV_INDEX"]: + url = remove_post_processed(url) _, username = get_executor( executor_types=app.config["ALERT_REPORTS_EXECUTE_AS"], model=self._report_schedule, diff --git a/superset/commands/report/utils.py b/superset/commands/report/utils.py new file mode 100644 index 0000000000..cff4134271 --- /dev/null +++ b/superset/commands/report/utils.py @@ -0,0 +1,33 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + + +def remove_post_processed(url: str) -> str: + """Remove the type=post_processed parameter from the URL query string. + + Args: + url (str): The URL to process. + Returns: + str: The URL with the type=post_processed parameter removed.""" + if "?" not in url: + return url + base_url, query_string = url.split("?", 1) + params = query_string.split("&") + filtered_params = [param for param in params if param != "type=post_processed"] + filtered_query_string = "&".join(filtered_params) + filtered_url = f"{base_url}?{filtered_query_string}" + return filtered_url diff --git a/superset/config.py b/superset/config.py index 8256ca0dc0..2732359cb9 100644 --- a/superset/config.py +++ b/superset/config.py @@ -826,6 +826,9 @@ CSV_UPLOAD_MAX_SIZE = None # note: index option should not be overridden CSV_EXPORT = {"encoding": "utf-8"} +# Include the CSV index when sending reports +CSV_INDEX = True + # Excel Options: key/value pairs that will be passed as argument to DataFrame.to_excel # method. # note: index option should not be overridden diff --git a/tests/unit_tests/commands/report/test_report_utils.py b/tests/unit_tests/commands/report/test_report_utils.py new file mode 100644 index 0000000000..1313af047c --- /dev/null +++ b/tests/unit_tests/commands/report/test_report_utils.py @@ -0,0 +1,48 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +from superset.commands.report.utils import remove_post_processed + + +def test_remove_post_processed(): + url = "https://superset.com/?param1=value1&type=post_processed¶m2=value2" + expected = "https://superset.com/?param1=value1¶m2=value2" + assert remove_post_processed(url) == expected + + +def test_retain_other_parameters(): + url = "https://superset.com/?param1=value1¶m2=value2" + expected = "https://superset.com/?param1=value1¶m2=value2" + assert remove_post_processed(url) == expected + + +def test_no_post_processed_present(): + url = "https://superset.com/?param1=value1¶m2=value2" + expected = "https://superset.com/?param1=value1¶m2=value2" + assert remove_post_processed(url) == expected + + +def test_empty_query_string(): + url = "https://superset.com/?" + expected = "https://superset.com/?" + assert remove_post_processed(url) == expected + + +def test_no_query_string(): + url = "https://superset.com" + expected = "https://superset.com" + assert remove_post_processed(url) == expected