You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@superset.apache.org by yo...@apache.org on 2024/03/04 10:50:12 UTC

(superset) branch master updated: feat: support to fetch multiple date time in time_range endpoint (#27370)

This is an automated email from the ASF dual-hosted git repository.

yongjiezhao pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/superset.git


The following commit(s) were added to refs/heads/master by this push:
     new 2c00cc534c feat: support to fetch multiple date time in time_range endpoint (#27370)
2c00cc534c is described below

commit 2c00cc534c5906c6b4bcf7a1e22a87021d0b88d2
Author: Yongjie Zhao <yo...@gmail.com>
AuthorDate: Mon Mar 4 11:50:05 2024 +0100

    feat: support to fetch multiple date time in time_range endpoint (#27370)
    
    Co-authored-by: Yongjie Zhao <yo...@burda-forward.de>
---
 .../DateFilterControl/utils/dateFilterUtils.ts     |  4 +--
 superset/views/api.py                              | 33 ++++++++++++++++------
 tests/integration_tests/charts/api_tests.py        | 17 ++++++++++-
 3 files changed, 42 insertions(+), 12 deletions(-)

diff --git a/superset-frontend/src/explore/components/controls/DateFilterControl/utils/dateFilterUtils.ts b/superset-frontend/src/explore/components/controls/DateFilterControl/utils/dateFilterUtils.ts
index 08162cedf0..aad2f9984d 100644
--- a/superset-frontend/src/explore/components/controls/DateFilterControl/utils/dateFilterUtils.ts
+++ b/superset-frontend/src/explore/components/controls/DateFilterControl/utils/dateFilterUtils.ts
@@ -72,8 +72,8 @@ export const fetchTimeRange = async (
   try {
     const response = await SupersetClient.get({ endpoint });
     const timeRangeString = buildTimeRangeString(
-      response?.json?.result?.since || '',
-      response?.json?.result?.until || '',
+      response?.json?.result[0]?.since || '',
+      response?.json?.result[0]?.until || '',
     );
     return {
       value: formatTimeRange(timeRangeString, columnPlaceholder),
diff --git a/superset/views/api.py b/superset/views/api.py
index d7b1b8434e..2e3c3b9bdd 100644
--- a/superset/views/api.py
+++ b/superset/views/api.py
@@ -40,7 +40,15 @@ from superset.views.base import api, BaseSupersetView, handle_api_exception
 if TYPE_CHECKING:
     from superset.common.query_context_factory import QueryContextFactory
 
-get_time_range_schema = {"type": "string"}
+get_time_range_schema = {
+    "type": ["string", "array"],
+    "items": {
+        "type": "object",
+        "properties": {
+            "timeRange": {"type": "string"},
+        },
+    },
+}
 
 
 class Api(BaseSupersetView):
@@ -95,15 +103,22 @@ class Api(BaseSupersetView):
     @expose("/v1/time_range/", methods=("GET",))
     def time_range(self, **kwargs: Any) -> FlaskResponse:
         """Get actually time range from human-readable string or datetime expression."""
-        time_range = kwargs["rison"]
+        time_ranges = kwargs["rison"]
         try:
-            since, until = get_since_until(time_range)
-            result = {
-                "since": since.isoformat() if since else "",
-                "until": until.isoformat() if until else "",
-                "timeRange": time_range,
-            }
-            return self.json_response({"result": result})
+            if isinstance(time_ranges, str):
+                time_ranges = [{"timeRange": time_ranges}]
+
+            rv = []
+            for time_range in time_ranges:
+                since, until = get_since_until(time_range["timeRange"])
+                rv.append(
+                    {
+                        "since": since.isoformat() if since else "",
+                        "until": until.isoformat() if until else "",
+                        "timeRange": time_range["timeRange"],
+                    }
+                )
+            return self.json_response({"result": rv})
         except (ValueError, TimeRangeParseFailError, TimeRangeAmbiguousError) as error:
             error_msg = {"message": _("Unexpected time range: %(error)s", error=error)}
             return self.json_response(error_msg, 400)
diff --git a/tests/integration_tests/charts/api_tests.py b/tests/integration_tests/charts/api_tests.py
index d0985124e2..b5d935dd3d 100644
--- a/tests/integration_tests/charts/api_tests.py
+++ b/tests/integration_tests/charts/api_tests.py
@@ -1421,7 +1421,22 @@ class TestChartApi(ApiOwnersTestCaseMixin, InsertChartMixin, SupersetTestCase):
         rv = self.client.get(uri)
         data = json.loads(rv.data.decode("utf-8"))
         self.assertEqual(rv.status_code, 200)
-        self.assertEqual(len(data["result"]), 3)
+        assert "since" in data["result"][0]
+        assert "until" in data["result"][0]
+        assert "timeRange" in data["result"][0]
+
+        humanize_time_range = [
+            {"timeRange": "2021-01-01 : 2022-02-01"},
+            {"timeRange": "2022-01-01 : 2023-02-01"},
+        ]
+        uri = f"api/v1/time_range/?q={prison.dumps(humanize_time_range)}"
+        rv = self.client.get(uri)
+        data = json.loads(rv.data.decode("utf-8"))
+        assert rv.status_code == 200
+        assert len(data["result"]) == 2
+        assert "since" in data["result"][0]
+        assert "until" in data["result"][0]
+        assert "timeRange" in data["result"][0]
 
     def test_query_form_data(self):
         """