You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@superset.apache.org by dp...@apache.org on 2023/01/16 14:08:05 UTC

[superset] branch master updated: chore: Migrate /superset/stop_query/ to API v1 (#22624)

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

dpgaspar 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 3ed288d4ee chore: Migrate /superset/stop_query/ to API v1 (#22624)
3ed288d4ee is described below

commit 3ed288d4ee96fd0a8a40dc1f7804de6a07c34447
Author: Diego Medina <di...@gmail.com>
AuthorDate: Mon Jan 16 11:07:52 2023 -0300

    chore: Migrate /superset/stop_query/ to API v1 (#22624)
---
 docs/static/resources/openapi.json                 | 1258 +++++++++++++-------
 superset-frontend/src/SqlLab/actions/sqlLab.js     |    6 +-
 .../src/SqlLab/actions/sqlLab.test.js              |   11 +-
 superset/constants.py                              |    1 +
 superset/exceptions.py                             |    4 +
 superset/queries/api.py                            |   78 +-
 superset/queries/dao.py                            |   27 +
 superset/queries/schemas.py                        |    8 +
 superset/views/core.py                             |    1 +
 tests/integration_tests/queries/api_tests.py       |   52 +
 tests/unit_tests/dao/queries_test.py               |  165 ++-
 11 files changed, 1177 insertions(+), 434 deletions(-)

diff --git a/docs/static/resources/openapi.json b/docs/static/resources/openapi.json
index 62153bac51..8279811b53 100644
--- a/docs/static/resources/openapi.json
+++ b/docs/static/resources/openapi.json
@@ -257,7 +257,7 @@
       "AnnotationLayerRestApi.get_list": {
         "properties": {
           "changed_by": {
-            "$ref": "#/components/schemas/AnnotationLayerRestApi.get_list.User1"
+            "$ref": "#/components/schemas/AnnotationLayerRestApi.get_list.User"
           },
           "changed_on": {
             "format": "date-time",
@@ -268,7 +268,7 @@
             "readOnly": true
           },
           "created_by": {
-            "$ref": "#/components/schemas/AnnotationLayerRestApi.get_list.User"
+            "$ref": "#/components/schemas/AnnotationLayerRestApi.get_list.User1"
           },
           "created_on": {
             "format": "date-time",
@@ -414,13 +414,13 @@
       "AnnotationRestApi.get_list": {
         "properties": {
           "changed_by": {
-            "$ref": "#/components/schemas/AnnotationRestApi.get_list.User1"
+            "$ref": "#/components/schemas/AnnotationRestApi.get_list.User"
           },
           "changed_on_delta_humanized": {
             "readOnly": true
           },
           "created_by": {
-            "$ref": "#/components/schemas/AnnotationRestApi.get_list.User"
+            "$ref": "#/components/schemas/AnnotationRestApi.get_list.User1"
           },
           "end_dttm": {
             "format": "date-time",
@@ -547,6 +547,17 @@
         },
         "type": "object"
       },
+      "AvailableDomainsSchema": {
+        "properties": {
+          "domains": {
+            "items": {
+              "type": "string"
+            },
+            "type": "array"
+          }
+        },
+        "type": "object"
+      },
       "CacheInvalidationRequestSchema": {
         "properties": {
           "datasource_uids": {
@@ -822,17 +833,12 @@
       },
       "ChartDataExtras": {
         "properties": {
-          "druid_time_origin": {
-            "description": "Starting point for time grain counting on legacy Druid datasources. Used to change e.g. Monday/Sunday first-day-of-week.",
-            "nullable": true,
-            "type": "string"
-          },
           "having": {
             "description": "HAVING clause to be added to aggregate queries using AND operator.",
             "type": "string"
           },
           "having_druid": {
-            "description": "HAVING filters to be added to legacy Druid datasource queries.",
+            "description": "HAVING filters to be added to legacy Druid datasource queries. This field is deprecated",
             "items": {
               "$ref": "#/components/schemas/ChartDataFilter"
             },
@@ -920,18 +926,20 @@
               "NOT IN",
               "REGEX",
               "IS TRUE",
-              "IS FALSE"
+              "IS FALSE",
+              "TEMPORAL_RANGE"
             ],
             "example": "IN",
             "type": "string"
           },
           "val": {
-            "description": "The value or values to compare against. Can be a string, integer, decimal or list, depending on the operator.",
+            "description": "The value or values to compare against. Can be a string, integer, decimal, None or list, depending on the operator.",
             "example": [
               "China",
               "France",
               "Japan"
-            ]
+            ],
+            "nullable": true
           }
         },
         "required": [
@@ -1060,13 +1068,13 @@
           "operation": {
             "description": "Post processing operation type",
             "enum": [
-              "_flatten_column_after_pivot",
               "aggregate",
               "boxplot",
               "compare",
               "contribution",
               "cum",
               "diff",
+              "escape_separator",
               "flatten",
               "geodetic_parse",
               "geohash_decode",
@@ -1077,7 +1085,8 @@
               "resample",
               "rolling",
               "select",
-              "sort"
+              "sort",
+              "unescape_separator"
             ],
             "example": "aggregate",
             "type": "string"
@@ -1174,11 +1183,18 @@
       },
       "ChartDataQueryContextSchema": {
         "properties": {
+          "custom_cache_timeout": {
+            "description": "Override the default cache timeout",
+            "format": "int32",
+            "nullable": true,
+            "type": "integer"
+          },
           "datasource": {
             "$ref": "#/components/schemas/ChartDataDatasource"
           },
           "force": {
             "description": "Should the queries be forced to load from the source. Default: `false`",
+            "nullable": true,
             "type": "boolean"
           },
           "form_data": {
@@ -1436,7 +1452,7 @@
             "type": "string"
           },
           "cache_timeout": {
-            "description": "Cache timeout in following order: custom timeout, datasource timeout, default config timeout.",
+            "description": "Cache timeout in following order: custom timeout, datasource timeout, cache default timeout, config default cache timeout.",
             "format": "int32",
             "nullable": true,
             "type": "integer"
@@ -1557,6 +1573,9 @@
             "nullable": true,
             "type": "string"
           },
+          "changed_on_delta_humanized": {
+            "readOnly": true
+          },
           "dashboards": {
             "$ref": "#/components/schemas/ChartDataRestApi.get.Dashboard"
           },
@@ -1564,6 +1583,10 @@
             "nullable": true,
             "type": "string"
           },
+          "id": {
+            "format": "int32",
+            "type": "integer"
+          },
           "is_managed_externally": {
             "type": "boolean"
           },
@@ -1583,6 +1606,12 @@
             "nullable": true,
             "type": "string"
           },
+          "thumbnail_url": {
+            "readOnly": true
+          },
+          "url": {
+            "readOnly": true
+          },
           "viz_type": {
             "maxLength": 250,
             "nullable": true,
@@ -1651,7 +1680,7 @@
             "type": "string"
           },
           "changed_by": {
-            "$ref": "#/components/schemas/ChartDataRestApi.get_list.User"
+            "$ref": "#/components/schemas/ChartDataRestApi.get_list.User1"
           },
           "changed_by_name": {
             "readOnly": true
@@ -1666,7 +1695,13 @@
             "readOnly": true
           },
           "created_by": {
-            "$ref": "#/components/schemas/ChartDataRestApi.get_list.User1"
+            "$ref": "#/components/schemas/ChartDataRestApi.get_list.User3"
+          },
+          "created_on_delta_humanized": {
+            "readOnly": true
+          },
+          "dashboards": {
+            "$ref": "#/components/schemas/ChartDataRestApi.get_list.Dashboard"
           },
           "datasource_id": {
             "format": "int32",
@@ -1707,10 +1742,10 @@
             "type": "string"
           },
           "last_saved_by": {
-            "$ref": "#/components/schemas/ChartDataRestApi.get_list.User2"
+            "$ref": "#/components/schemas/ChartDataRestApi.get_list.User"
           },
           "owners": {
-            "$ref": "#/components/schemas/ChartDataRestApi.get_list.User1"
+            "$ref": "#/components/schemas/ChartDataRestApi.get_list.User2"
           },
           "params": {
             "nullable": true,
@@ -1738,6 +1773,20 @@
         },
         "type": "object"
       },
+      "ChartDataRestApi.get_list.Dashboard": {
+        "properties": {
+          "dashboard_title": {
+            "maxLength": 500,
+            "nullable": true,
+            "type": "string"
+          },
+          "id": {
+            "format": "int32",
+            "type": "integer"
+          }
+        },
+        "type": "object"
+      },
       "ChartDataRestApi.get_list.SqlaTable": {
         "properties": {
           "default_endpoint": {
@@ -1760,6 +1809,10 @@
             "maxLength": 64,
             "type": "string"
           },
+          "id": {
+            "format": "int32",
+            "type": "integer"
+          },
           "last_name": {
             "maxLength": 64,
             "type": "string"
@@ -1777,23 +1830,14 @@
             "maxLength": 64,
             "type": "string"
           },
-          "id": {
-            "format": "int32",
-            "type": "integer"
-          },
           "last_name": {
             "maxLength": 64,
             "type": "string"
-          },
-          "username": {
-            "maxLength": 64,
-            "type": "string"
           }
         },
         "required": [
           "first_name",
-          "last_name",
-          "username"
+          "last_name"
         ],
         "type": "object"
       },
@@ -1810,11 +1854,16 @@
           "last_name": {
             "maxLength": 64,
             "type": "string"
+          },
+          "username": {
+            "maxLength": 64,
+            "type": "string"
           }
         },
         "required": [
           "first_name",
-          "last_name"
+          "last_name",
+          "username"
         ],
         "type": "object"
       },
@@ -2231,7 +2280,8 @@
             "description": "Form data from the Explore controls used to form the chart's data query.",
             "type": "object"
           },
-          "slice_id": {
+          "id": {
+            "description": "The id of the chart.",
             "format": "int32",
             "type": "integer"
           },
@@ -2315,6 +2365,9 @@
             "nullable": true,
             "type": "string"
           },
+          "changed_on_delta_humanized": {
+            "readOnly": true
+          },
           "dashboards": {
             "$ref": "#/components/schemas/ChartRestApi.get.Dashboard"
           },
@@ -2322,6 +2375,10 @@
             "nullable": true,
             "type": "string"
           },
+          "id": {
+            "format": "int32",
+            "type": "integer"
+          },
           "is_managed_externally": {
             "type": "boolean"
           },
@@ -2341,6 +2398,12 @@
             "nullable": true,
             "type": "string"
           },
+          "thumbnail_url": {
+            "readOnly": true
+          },
+          "url": {
+            "readOnly": true
+          },
           "viz_type": {
             "maxLength": 250,
             "nullable": true,
@@ -2409,7 +2472,7 @@
             "type": "string"
           },
           "changed_by": {
-            "$ref": "#/components/schemas/ChartRestApi.get_list.User"
+            "$ref": "#/components/schemas/ChartRestApi.get_list.User1"
           },
           "changed_by_name": {
             "readOnly": true
@@ -2424,7 +2487,13 @@
             "readOnly": true
           },
           "created_by": {
-            "$ref": "#/components/schemas/ChartRestApi.get_list.User1"
+            "$ref": "#/components/schemas/ChartRestApi.get_list.User3"
+          },
+          "created_on_delta_humanized": {
+            "readOnly": true
+          },
+          "dashboards": {
+            "$ref": "#/components/schemas/ChartRestApi.get_list.Dashboard"
           },
           "datasource_id": {
             "format": "int32",
@@ -2465,10 +2534,10 @@
             "type": "string"
           },
           "last_saved_by": {
-            "$ref": "#/components/schemas/ChartRestApi.get_list.User2"
+            "$ref": "#/components/schemas/ChartRestApi.get_list.User"
           },
           "owners": {
-            "$ref": "#/components/schemas/ChartRestApi.get_list.User1"
+            "$ref": "#/components/schemas/ChartRestApi.get_list.User2"
           },
           "params": {
             "nullable": true,
@@ -2496,6 +2565,20 @@
         },
         "type": "object"
       },
+      "ChartRestApi.get_list.Dashboard": {
+        "properties": {
+          "dashboard_title": {
+            "maxLength": 500,
+            "nullable": true,
+            "type": "string"
+          },
+          "id": {
+            "format": "int32",
+            "type": "integer"
+          }
+        },
+        "type": "object"
+      },
       "ChartRestApi.get_list.SqlaTable": {
         "properties": {
           "default_endpoint": {
@@ -2518,6 +2601,10 @@
             "maxLength": 64,
             "type": "string"
           },
+          "id": {
+            "format": "int32",
+            "type": "integer"
+          },
           "last_name": {
             "maxLength": 64,
             "type": "string"
@@ -2535,23 +2622,14 @@
             "maxLength": 64,
             "type": "string"
           },
-          "id": {
-            "format": "int32",
-            "type": "integer"
-          },
           "last_name": {
             "maxLength": 64,
             "type": "string"
-          },
-          "username": {
-            "maxLength": 64,
-            "type": "string"
           }
         },
         "required": [
           "first_name",
-          "last_name",
-          "username"
+          "last_name"
         ],
         "type": "object"
       },
@@ -2568,11 +2646,16 @@
           "last_name": {
             "maxLength": 64,
             "type": "string"
+          },
+          "username": {
+            "maxLength": 64,
+            "type": "string"
           }
         },
         "required": [
           "first_name",
-          "last_name"
+          "last_name",
+          "username"
         ],
         "type": "object"
       },
@@ -2856,13 +2939,13 @@
       "CssTemplateRestApi.get_list": {
         "properties": {
           "changed_by": {
-            "$ref": "#/components/schemas/CssTemplateRestApi.get_list.User1"
+            "$ref": "#/components/schemas/CssTemplateRestApi.get_list.User"
           },
           "changed_on_delta_humanized": {
             "readOnly": true
           },
           "created_by": {
-            "$ref": "#/components/schemas/CssTemplateRestApi.get_list.User"
+            "$ref": "#/components/schemas/CssTemplateRestApi.get_list.User1"
           },
           "created_on": {
             "format": "date-time",
@@ -3044,8 +3127,7 @@
           },
           "owners": {
             "items": {
-              "format": "int32",
-              "type": "integer"
+              "type": "object"
             },
             "type": "array"
           },
@@ -3180,16 +3262,24 @@
       },
       "DashboardPermalinkPostSchema": {
         "properties": {
-          "filterState": {
-            "description": "Native filter state",
+          "activeTabs": {
+            "description": "Current active dashboard tabs",
+            "items": {
+              "type": "string"
+            },
             "nullable": true,
-            "type": "object"
+            "type": "array"
           },
-          "hash": {
-            "description": "Optional anchor link",
+          "anchor": {
+            "description": "Optional anchor link added to url hash",
             "nullable": true,
             "type": "string"
           },
+          "dataMask": {
+            "description": "Data mask used for native filter state",
+            "nullable": true,
+            "type": "object"
+          },
           "urlParams": {
             "description": "URL Parameters",
             "items": {
@@ -3242,9 +3332,6 @@
           "created_on_delta_humanized": {
             "readOnly": true
           },
-          "created_on_delta_humanized": {
-            "readOnly": true
-          },
           "css": {
             "nullable": true,
             "type": "string"
@@ -3266,7 +3353,7 @@
             "type": "string"
           },
           "owners": {
-            "$ref": "#/components/schemas/DashboardRestApi.get_list.User2"
+            "$ref": "#/components/schemas/DashboardRestApi.get_list.User1"
           },
           "position_json": {
             "nullable": true,
@@ -3560,17 +3647,6 @@
           },
           "name": {
             "type": "string"
-          },
-          "engine_information": {
-            "type": "object"
-          }
-        },
-        "type": "object"
-      },
-      "Database1": {
-        "properties": {
-          "database_name": {
-            "type": "string"
           }
         },
         "type": "object"
@@ -3711,9 +3787,11 @@
             "maxLength": 250,
             "type": "string"
           },
-          "encrypted_extra": {
-            "nullable": true,
-            "type": "string"
+          "driver": {
+            "readOnly": true
+          },
+          "engine_information": {
+            "readOnly": true
           },
           "expose_in_sqllab": {
             "nullable": true,
@@ -3739,6 +3817,9 @@
           "is_managed_externally": {
             "type": "boolean"
           },
+          "masked_encrypted_extra": {
+            "readOnly": true
+          },
           "parameters": {
             "readOnly": true
           },
@@ -3753,8 +3834,10 @@
             "maxLength": 1024,
             "type": "string"
           },
-          "engine_information": {
-            "readOnly": true
+          "uuid": {
+            "format": "uuid",
+            "nullable": true,
+            "type": "string"
           }
         },
         "required": [
@@ -3815,6 +3898,9 @@
           "disable_data_preview": {
             "readOnly": true
           },
+          "engine_information": {
+            "readOnly": true
+          },
           "explore_database_id": {
             "readOnly": true
           },
@@ -3835,8 +3921,10 @@
             "format": "int32",
             "type": "integer"
           },
-          "engine_information": {
-            "readOnly": true
+          "uuid": {
+            "format": "uuid",
+            "nullable": true,
+            "type": "string"
           }
         },
         "required": [
@@ -3899,8 +3987,8 @@
             "minLength": 1,
             "type": "string"
           },
-          "encrypted_extra": {
-            "description": "<p>JSON string containing additional connection configuration.<br>This is used to provide connection information for systems like Hive, Presto, and BigQuery, which do not conform to the username:password syntax normally used by SQLAlchemy.</p>",
+          "driver": {
+            "description": "SQLAlchemy driver to use",
             "nullable": true,
             "type": "string"
           },
@@ -3936,6 +4024,11 @@
             "nullable": true,
             "type": "boolean"
           },
+          "masked_encrypted_extra": {
+            "description": "<p>JSON string containing additional connection configuration.<br>This is used to provide connection information for systems like Hive, Presto, and BigQuery, which do not conform to the username:password syntax normally used by SQLAlchemy.</p>",
+            "nullable": true,
+            "type": "string"
+          },
           "parameters": {
             "additionalProperties": {},
             "description": "DB-specific parameters for configuration",
@@ -3951,6 +4044,17 @@
             "maxLength": 1024,
             "minLength": 1,
             "type": "string"
+          },
+          "ssh_tunnel": {
+            "allOf": [
+              {
+                "$ref": "#/components/schemas/DatabaseSSHTunnel"
+              }
+            ],
+            "nullable": true
+          },
+          "uuid": {
+            "type": "string"
           }
         },
         "required": [
@@ -3997,8 +4101,8 @@
             "nullable": true,
             "type": "string"
           },
-          "encrypted_extra": {
-            "description": "<p>JSON string containing additional connection configuration.<br>This is used to provide connection information for systems like Hive, Presto, and BigQuery, which do not conform to the username:password syntax normally used by SQLAlchemy.</p>",
+          "driver": {
+            "description": "SQLAlchemy driver to use",
             "nullable": true,
             "type": "string"
           },
@@ -4034,6 +4138,11 @@
             "nullable": true,
             "type": "boolean"
           },
+          "masked_encrypted_extra": {
+            "description": "<p>JSON string containing additional connection configuration.<br>This is used to provide connection information for systems like Hive, Presto, and BigQuery, which do not conform to the username:password syntax normally used by SQLAlchemy.</p>",
+            "nullable": true,
+            "type": "string"
+          },
           "parameters": {
             "additionalProperties": {},
             "description": "DB-specific parameters for configuration",
@@ -4049,6 +4158,38 @@
             "maxLength": 1024,
             "minLength": 0,
             "type": "string"
+          },
+          "ssh_tunnel": {
+            "allOf": [
+              {
+                "$ref": "#/components/schemas/DatabaseSSHTunnel"
+              }
+            ],
+            "nullable": true
+          }
+        },
+        "type": "object"
+      },
+      "DatabaseSSHTunnel": {
+        "properties": {
+          "password": {
+            "type": "string"
+          },
+          "private_key": {
+            "type": "string"
+          },
+          "private_key_password": {
+            "type": "string"
+          },
+          "server_address": {
+            "type": "string"
+          },
+          "server_port": {
+            "format": "int32",
+            "type": "integer"
+          },
+          "username": {
+            "type": "string"
           }
         },
         "type": "object"
@@ -4066,8 +4207,8 @@
             "nullable": true,
             "type": "string"
           },
-          "encrypted_extra": {
-            "description": "<p>JSON string containing additional connection configuration.<br>This is used to provide connection information for systems like Hive, Presto, and BigQuery, which do not conform to the username:password syntax normally used by SQLAlchemy.</p>",
+          "driver": {
+            "description": "SQLAlchemy driver to use",
             "nullable": true,
             "type": "string"
           },
@@ -4084,6 +4225,11 @@
             "description": "If Presto, all the queries in SQL Lab are going to be executed as the currently logged on user who must have permission to run them.<br/>If Hive and hive.server2.enable.doAs is enabled, will run the queries as service account, but impersonate the currently logged on user via hive.server2.proxy.user property.",
             "type": "boolean"
           },
+          "masked_encrypted_extra": {
+            "description": "<p>JSON string containing additional connection configuration.<br>This is used to provide connection information for systems like Hive, Presto, and BigQuery, which do not conform to the username:password syntax normally used by SQLAlchemy.</p>",
+            "nullable": true,
+            "type": "string"
+          },
           "parameters": {
             "additionalProperties": {},
             "description": "DB-specific parameters for configuration",
@@ -4099,12 +4245,27 @@
             "maxLength": 1024,
             "minLength": 1,
             "type": "string"
-          }
-        },
-        "type": "object"
-      },
+          },
+          "ssh_tunnel": {
+            "allOf": [
+              {
+                "$ref": "#/components/schemas/DatabaseSSHTunnel"
+              }
+            ],
+            "nullable": true
+          }
+        },
+        "type": "object"
+      },
       "DatabaseValidateParametersSchema": {
         "properties": {
+          "catalog": {
+            "additionalProperties": {
+              "nullable": true
+            },
+            "description": "Gsheets specific column for managing label to sheet urls",
+            "type": "object"
+          },
           "configuration_method": {
             "description": "Configuration_method is used on the frontend to inform the backend whether to explode parameters or to provide only a sqlalchemy_uri."
           },
@@ -4115,8 +4276,8 @@
             "nullable": true,
             "type": "string"
           },
-          "encrypted_extra": {
-            "description": "<p>JSON string containing additional connection configuration.<br>This is used to provide connection information for systems like Hive, Presto, and BigQuery, which do not conform to the username:password syntax normally used by SQLAlchemy.</p>",
+          "driver": {
+            "description": "SQLAlchemy driver to use",
             "nullable": true,
             "type": "string"
           },
@@ -4128,10 +4289,21 @@
             "description": "<p>JSON string containing extra configuration elements.<br>1. The <code>engine_params</code> object gets unpacked into the <a href=\"https://docs.sqlalchemy.org/en/latest/core/engines.html#sqlalchemy.create_engine\">sqlalchemy.create_engine</a> call, while the <code>metadata_params</code> gets unpacked into the <a href=\"https://docs.sqlalchemy.org/en/rel_1_0/core/metadata.html#sqlalchemy.schema.MetaData\">sqlalchemy.MetaData</a> call.<br>2. The <code>metadata [...]
             "type": "string"
           },
+          "id": {
+            "description": "Database ID (for updates)",
+            "format": "int32",
+            "nullable": true,
+            "type": "integer"
+          },
           "impersonate_user": {
             "description": "If Presto, all the queries in SQL Lab are going to be executed as the currently logged on user who must have permission to run them.<br/>If Hive and hive.server2.enable.doAs is enabled, will run the queries as service account, but impersonate the currently logged on user via hive.server2.proxy.user property.",
             "type": "boolean"
           },
+          "masked_encrypted_extra": {
+            "description": "<p>JSON string containing additional connection configuration.<br>This is used to provide connection information for systems like Hive, Presto, and BigQuery, which do not conform to the username:password syntax normally used by SQLAlchemy.</p>",
+            "nullable": true,
+            "type": "string"
+          },
           "parameters": {
             "additionalProperties": {
               "nullable": true
@@ -4151,6 +4323,174 @@
         ],
         "type": "object"
       },
+      "Dataset": {
+        "properties": {
+          "cache_timeout": {
+            "description": "Duration (in seconds) of the caching timeout for this dataset.",
+            "format": "int32",
+            "type": "integer"
+          },
+          "column_formats": {
+            "description": "Column formats.",
+            "type": "object"
+          },
+          "columns": {
+            "description": "Columns metadata.",
+            "items": {
+              "type": "object"
+            },
+            "type": "array"
+          },
+          "database": {
+            "description": "Database associated with the dataset.",
+            "type": "object"
+          },
+          "datasource_name": {
+            "description": "Dataset name.",
+            "type": "string"
+          },
+          "default_endpoint": {
+            "description": "Default endpoint for the dataset.",
+            "type": "string"
+          },
+          "description": {
+            "description": "Dataset description.",
+            "type": "string"
+          },
+          "edit_url": {
+            "description": "The URL for editing the dataset.",
+            "type": "string"
+          },
+          "extra": {
+            "description": "JSON string containing extra configuration elements.",
+            "type": "object"
+          },
+          "fetch_values_predicate": {
+            "description": "Predicate used when fetching values from the dataset.",
+            "type": "string"
+          },
+          "filter_select": {
+            "description": "SELECT filter applied to the dataset.",
+            "type": "boolean"
+          },
+          "filter_select_enabled": {
+            "description": "If the SELECT filter is enabled.",
+            "type": "boolean"
+          },
+          "granularity_sqla": {
+            "description": "Name of temporal column used for time filtering for SQL datasources. This field is deprecated, use `granularity` instead.",
+            "items": {
+              "items": {
+                "type": "object"
+              },
+              "type": "array"
+            },
+            "type": "array"
+          },
+          "health_check_message": {
+            "description": "Health check message.",
+            "type": "string"
+          },
+          "id": {
+            "description": "Dataset ID.",
+            "format": "int32",
+            "type": "integer"
+          },
+          "is_sqllab_view": {
+            "description": "If the dataset is a SQL Lab view.",
+            "type": "boolean"
+          },
+          "main_dttm_col": {
+            "description": "The main temporal column.",
+            "type": "string"
+          },
+          "metrics": {
+            "description": "Dataset metrics.",
+            "items": {
+              "type": "object"
+            },
+            "type": "array"
+          },
+          "name": {
+            "description": "Dataset name.",
+            "type": "string"
+          },
+          "offset": {
+            "description": "Dataset offset.",
+            "format": "int32",
+            "type": "integer"
+          },
+          "order_by_choices": {
+            "description": "List of order by columns.",
+            "items": {
+              "items": {
+                "type": "string"
+              },
+              "type": "array"
+            },
+            "type": "array"
+          },
+          "owners": {
+            "description": "List of owners identifiers",
+            "items": {
+              "format": "int32",
+              "type": "integer"
+            },
+            "type": "array"
+          },
+          "params": {
+            "description": "Extra params for the dataset.",
+            "type": "object"
+          },
+          "perm": {
+            "description": "Permission expression.",
+            "type": "string"
+          },
+          "schema": {
+            "description": "Dataset schema.",
+            "type": "string"
+          },
+          "select_star": {
+            "description": "Select all clause.",
+            "type": "string"
+          },
+          "sql": {
+            "description": "A SQL statement that defines the dataset.",
+            "type": "string"
+          },
+          "table_name": {
+            "description": "The name of the table associated with the dataset.",
+            "type": "string"
+          },
+          "template_params": {
+            "description": "Table template params.",
+            "type": "object"
+          },
+          "time_grain_sqla": {
+            "description": "List of temporal granularities supported by the dataset.",
+            "items": {
+              "items": {
+                "type": "string"
+              },
+              "type": "array"
+            },
+            "type": "array"
+          },
+          "type": {
+            "description": "Dataset type.",
+            "type": "string"
+          },
+          "uid": {
+            "description": "Dataset unique identifier.",
+            "type": "string"
+          },
+          "verbose_map": {
+            "description": "Mapping from raw name to verbose name.",
+            "type": "object"
+          }
+        },
+        "type": "object"
+      },
       "DatasetColumnsPut": {
         "properties": {
           "advanced_data_type": {
@@ -4446,9 +4786,31 @@
             "nullable": true,
             "type": "integer"
           },
+          "changed_by": {
+            "$ref": "#/components/schemas/DatasetRestApi.get.User"
+          },
+          "changed_on": {
+            "format": "date-time",
+            "nullable": true,
+            "type": "string"
+          },
+          "changed_on_humanized": {
+            "readOnly": true
+          },
           "columns": {
             "$ref": "#/components/schemas/DatasetRestApi.get.TableColumn"
           },
+          "created_by": {
+            "$ref": "#/components/schemas/DatasetRestApi.get.User2"
+          },
+          "created_on": {
+            "format": "date-time",
+            "nullable": true,
+            "type": "string"
+          },
+          "created_on_humanized": {
+            "readOnly": true
+          },
           "database": {
             "$ref": "#/components/schemas/DatasetRestApi.get.Database"
           },
@@ -4503,13 +4865,16 @@
             "type": "integer"
           },
           "owners": {
-            "$ref": "#/components/schemas/DatasetRestApi.get.User"
+            "$ref": "#/components/schemas/DatasetRestApi.get.User1"
           },
           "schema": {
             "maxLength": 255,
             "nullable": true,
             "type": "string"
           },
+          "select_star": {
+            "readOnly": true
+          },
           "sql": {
             "nullable": true,
             "type": "string"
@@ -4594,11 +4959,6 @@
             "nullable": true,
             "type": "string"
           },
-          "uuid": {
-            "format": "uuid",
-            "nullable": true,
-            "type": "string"
-          },
           "verbose_name": {
             "maxLength": 1024,
             "nullable": true,
@@ -4697,6 +5057,23 @@
         "type": "object"
       },
       "DatasetRestApi.get.User": {
+        "properties": {
+          "first_name": {
+            "maxLength": 64,
+            "type": "string"
+          },
+          "last_name": {
+            "maxLength": 64,
+            "type": "string"
+          }
+        },
+        "required": [
+          "first_name",
+          "last_name"
+        ],
+        "type": "object"
+      },
+      "DatasetRestApi.get.User1": {
         "properties": {
           "first_name": {
             "maxLength": 64,
@@ -4722,6 +5099,23 @@
         ],
         "type": "object"
       },
+      "DatasetRestApi.get.User2": {
+        "properties": {
+          "first_name": {
+            "maxLength": 64,
+            "type": "string"
+          },
+          "last_name": {
+            "maxLength": 64,
+            "type": "string"
+          }
+        },
+        "required": [
+          "first_name",
+          "last_name"
+        ],
+        "type": "object"
+      },
       "DatasetRestApi.get_list": {
         "properties": {
           "changed_by": {
@@ -4875,6 +5269,10 @@
             "minLength": 0,
             "type": "string"
           },
+          "sql": {
+            "nullable": true,
+            "type": "string"
+          },
           "table_name": {
             "maxLength": 250,
             "minLength": 1,
@@ -5006,115 +5404,41 @@
             "type": "string"
           },
           "schema": {
-            "description": "Datasource schema",
-            "type": "string"
-          }
-        },
-        "required": [
-          "datasource_type"
-        ],
-        "type": "object"
-      },
-      "DistincResponseSchema": {
-        "properties": {
-          "count": {
-            "description": "The total number of distinct values",
-            "format": "int32",
-            "type": "integer"
-          },
-          "result": {
-            "items": {
-              "$ref": "#/components/schemas/DistinctResultResponse"
-            },
-            "type": "array"
-          }
-        },
-        "type": "object"
-      },
-      "DistinctResultResponse": {
-        "properties": {
-          "text": {
-            "description": "The distinct item",
-            "type": "string"
-          }
-        },
-        "type": "object"
-      },
-      "EmbeddedDashboardConfig": {
-        "properties": {
-          "allowed_domains": {
-            "items": {
-              "type": "string"
-            },
-            "type": "array"
-          }
-        },
-        "required": [
-          "allowed_domains"
-        ],
-        "type": "object"
-      },
-      "EmbeddedDashboardResponseSchema": {
-        "properties": {
-          "allowed_domains": {
-            "items": {
-              "type": "string"
-            },
-            "type": "array"
-          },
-          "changed_by": {
-            "$ref": "#/components/schemas/User"
-          },
-          "changed_on": {
-            "format": "date-time",
-            "type": "string"
-          },
-          "dashboard_id": {
-            "type": "string"
-          },
-          "uuid": {
-            "type": "string"
-          }
-        },
-        "type": "object"
-      },
-      "EmbeddedDashboardRestApi.get": {
-        "properties": {
-          "uuid": {
-            "format": "uuid",
-            "type": "string"
-          }
-        },
-        "type": "object"
-      },
-      "EmbeddedDashboardRestApi.get_list": {
-        "properties": {
-          "uuid": {
-            "format": "uuid",
+            "description": "Datasource schema",
             "type": "string"
           }
         },
+        "required": [
+          "datasource_type"
+        ],
         "type": "object"
       },
-      "EmbeddedDashboardRestApi.post": {
+      "DistincResponseSchema": {
         "properties": {
-          "uuid": {
-            "format": "uuid",
-            "type": "string"
+          "count": {
+            "description": "The total number of distinct values",
+            "format": "int32",
+            "type": "integer"
+          },
+          "result": {
+            "items": {
+              "$ref": "#/components/schemas/DistinctResultResponse"
+            },
+            "type": "array"
           }
         },
         "type": "object"
       },
-      "EmbeddedDashboardRestApi.put": {
+      "DistinctResultResponse": {
         "properties": {
-          "uuid": {
-            "format": "uuid",
+          "text": {
+            "description": "The distinct item",
             "type": "string"
           }
         },
         "type": "object"
       },
-      "ExplorePermalinkPostSchema": {
+      "EmbeddedDashboardConfig": {
         "properties": {
           "allowed_domains": {
             "items": {
@@ -5188,6 +5512,25 @@
         },
         "type": "object"
       },
+      "ExploreContextSchema": {
+        "properties": {
+          "dataset": {
+            "$ref": "#/components/schemas/Dataset"
+          },
+          "form_data": {
+            "description": "Form data from the Explore controls used to form the chart's data query.",
+            "type": "object"
+          },
+          "message": {
+            "description": "Any message related to the processed request.",
+            "type": "string"
+          },
+          "slice": {
+            "$ref": "#/components/schemas/Slice"
+          }
+        },
+        "type": "object"
+      },
       "ExplorePermalinkPostSchema": {
         "properties": {
           "formData": {
@@ -5730,8 +6073,7 @@
             "type": "string"
           },
           "tracking_url": {
-            "nullable": true,
-            "type": "string"
+            "readOnly": true
           }
         },
         "required": [
@@ -5840,6 +6182,10 @@
       },
       "RelatedResultResponse": {
         "properties": {
+          "extra": {
+            "description": "The extra metadata for related item",
+            "type": "object"
+          },
           "text": {
             "description": "The related item string representation",
             "type": "string"
@@ -6027,6 +6373,9 @@
             "nullable": true,
             "type": "string"
           },
+          "extra": {
+            "readOnly": true
+          },
           "force_screenshot": {
             "nullable": true,
             "type": "boolean"
@@ -6255,6 +6604,9 @@
             "nullable": true,
             "type": "string"
           },
+          "extra": {
+            "readOnly": true
+          },
           "id": {
             "format": "int32",
             "type": "integer"
@@ -7143,6 +7495,9 @@
             "nullable": true,
             "type": "string"
           },
+          "extra": {
+            "type": "object"
+          },
           "force_screenshot": {
             "type": "boolean"
           },
@@ -7867,6 +8222,9 @@
       },
       "SavedQueryRestApi.get": {
         "properties": {
+          "changed_on_delta_humanized": {
+            "readOnly": true
+          },
           "created_by": {
             "$ref": "#/components/schemas/SavedQueryRestApi.get.User"
           },
@@ -7897,6 +8255,10 @@
           },
           "sql_tables": {
             "readOnly": true
+          },
+          "template_parameters": {
+            "nullable": true,
+            "type": "string"
           }
         },
         "type": "object"
@@ -8059,6 +8421,10 @@
           "sql": {
             "nullable": true,
             "type": "string"
+          },
+          "template_parameters": {
+            "nullable": true,
+            "type": "string"
           }
         },
         "type": "object"
@@ -8087,6 +8453,10 @@
           "sql": {
             "nullable": true,
             "type": "string"
+          },
+          "template_parameters": {
+            "nullable": true,
+            "type": "string"
           }
         },
         "type": "object"
@@ -8112,6 +8482,93 @@
         },
         "type": "object"
       },
+      "Slice": {
+        "properties": {
+          "cache_timeout": {
+            "description": "Duration (in seconds) of the caching timeout for this chart.",
+            "format": "int32",
+            "type": "integer"
+          },
+          "certification_details": {
+            "description": "Details of the certification.",
+            "type": "string"
+          },
+          "certified_by": {
+            "description": "Person or group that has certified this dashboard.",
+            "type": "string"
+          },
+          "changed_on": {
+            "description": "Timestamp of the last modification.",
+            "type": "string"
+          },
+          "changed_on_humanized": {
+            "description": "Timestamp of the last modification in human readable form.",
+            "type": "string"
+          },
+          "datasource": {
+            "description": "Datasource identifier.",
+            "type": "string"
+          },
+          "description": {
+            "description": "Slice description.",
+            "type": "string"
+          },
+          "description_markeddown": {
+            "description": "Sanitized HTML version of the chart description.",
+            "type": "string"
+          },
+          "edit_url": {
+            "description": "The URL for editing the slice.",
+            "type": "string"
+          },
+          "form_data": {
+            "description": "Form data associated with the slice.",
+            "type": "object"
+          },
+          "is_managed_externally": {
+            "description": "If the chart is managed outside externally.",
+            "type": "boolean"
+          },
+          "modified": {
+            "description": "Last modification in human readable form.",
+            "type": "string"
+          },
+          "owners": {
+            "description": "Owners identifiers.",
+            "items": {
+              "format": "int32",
+              "type": "integer"
+            },
+            "type": "array"
+          },
+          "query_context": {
+            "description": "The context associated with the query.",
+            "type": "object"
+          },
+          "slice_id": {
+            "description": "The slice ID.",
+            "format": "int32",
+            "type": "integer"
+          },
+          "slice_name": {
+            "description": "The slice name.",
+            "type": "string"
+          },
+          "slice_url": {
+            "description": "The slice URL.",
+            "type": "string"
+          }
+        },
+        "type": "object"
+      },
+      "StopQuerySchema": {
+        "properties": {
+          "client_id": {
+            "type": "string"
+          }
+        },
+        "type": "object"
+      },
       "TableExtraMetadataResponseSchema": {
         "properties": {
           "clustering": {
@@ -8767,99 +9224,6 @@
         ]
       }
     },
-    "/api/v1/annotation_layer/": {
-      "delete": {
-        "description": "Deletes multiple annotation layers in a bulk operation.",
-        "parameters": [
-          {
-            "content": {
-              "application/json": {
-                "schema": {
-                  "$ref": "#/components/schemas/advanced_data_type_convert_schema"
-                }
-              }
-            },
-            "in": "query",
-            "name": "q"
-          }
-        ],
-        "responses": {
-          "200": {
-            "content": {
-              "application/json": {
-                "schema": {
-                  "$ref": "#/components/schemas/AdvancedDataTypeSchema"
-                }
-              }
-            },
-            "description": "AdvancedDataTypeResponse object has been returned."
-          },
-          "400": {
-            "$ref": "#/components/responses/400"
-          },
-          "401": {
-            "$ref": "#/components/responses/401"
-          },
-          "404": {
-            "$ref": "#/components/responses/404"
-          },
-          "500": {
-            "$ref": "#/components/responses/500"
-          }
-        },
-        "security": [
-          {
-            "jwt": []
-          }
-        ],
-        "summary": "Returns a AdvancedDataTypeResponse object populated with the passed in args.",
-        "tags": [
-          "Advanced Data Type"
-        ]
-      }
-    },
-    "/api/v1/advanced_data_type/types": {
-      "get": {
-        "description": "Returns a list of available advanced data types.",
-        "responses": {
-          "200": {
-            "content": {
-              "application/json": {
-                "schema": {
-                  "properties": {
-                    "result": {
-                      "items": {
-                        "type": "string"
-                      },
-                      "type": "array"
-                    }
-                  },
-                  "type": "object"
-                }
-              }
-            },
-            "description": "a successful return of the available advanced data types has taken place."
-          },
-          "401": {
-            "$ref": "#/components/responses/401"
-          },
-          "404": {
-            "$ref": "#/components/responses/404"
-          },
-          "500": {
-            "$ref": "#/components/responses/500"
-          }
-        },
-        "security": [
-          {
-            "jwt": []
-          }
-        ],
-        "tags": [
-          "Advanced Data Type"
-        ]
-      }
-    },
     "/api/v1/annotation_layer/": {
       "delete": {
         "description": "Deletes multiple annotation layers in a bulk operation.",
@@ -10004,13 +10368,49 @@
                 }
               }
             },
-            "description": "Async event results"
+            "description": "Async event results"
+          },
+          "401": {
+            "$ref": "#/components/responses/401"
+          },
+          "500": {
+            "$ref": "#/components/responses/500"
+          }
+        },
+        "security": [
+          {
+            "jwt": []
+          }
+        ],
+        "tags": [
+          "AsyncEventsRestApi"
+        ]
+      }
+    },
+    "/api/v1/available_domains/": {
+      "get": {
+        "description": "Get all available domains",
+        "responses": {
+          "200": {
+            "content": {
+              "application/json": {
+                "schema": {
+                  "properties": {
+                    "result": {
+                      "$ref": "#/components/schemas/AvailableDomainsSchema"
+                    }
+                  },
+                  "type": "object"
+                }
+              }
+            },
+            "description": "a list of available domains"
           },
           "401": {
             "$ref": "#/components/responses/401"
           },
-          "500": {
-            "$ref": "#/components/responses/500"
+          "403": {
+            "$ref": "#/components/responses/403"
           }
         },
         "security": [
@@ -10019,7 +10419,7 @@
           }
         ],
         "tags": [
-          "AsyncEventsRestApi"
+          "Available Domains"
         ]
       }
     },
@@ -11004,6 +11404,14 @@
             "schema": {
               "type": "string"
             }
+          },
+          {
+            "description": "Should the queries be forced to load from the source",
+            "in": "query",
+            "name": "force",
+            "schema": {
+              "type": "boolean"
+            }
           }
         ],
         "responses": {
@@ -13806,6 +14214,16 @@
                         "description": "Name of the SQLAlchemy engine",
                         "type": "string"
                       },
+                      "engine_information": {
+                        "description": "Dict with public properties form the DB Engine",
+                        "properties": {
+                          "supports_file_upload": {
+                            "description": "Whether the engine supports file uploads",
+                            "type": "boolean"
+                          }
+                        },
+                        "type": "object"
+                      },
                       "name": {
                         "description": "Name of the database",
                         "type": "string"
@@ -13821,10 +14239,6 @@
                       "sqlalchemy_uri_placeholder": {
                         "description": "Example placeholder for the SQLAlchemy URI",
                         "type": "string"
-                      },
-                      "engine_information": {
-                        "description": "Object with properties we want to expose from our DB engine",
-                        "type": "object"
                       }
                     },
                     "type": "object"
@@ -14121,26 +14535,16 @@
         ]
       },
       "get": {
-        "description": "Get an item model",
+        "description": "Get a database",
         "parameters": [
           {
+            "description": "The database id",
             "in": "path",
             "name": "pk",
             "required": true,
             "schema": {
               "type": "integer"
             }
-          },
-          {
-            "content": {
-              "application/json": {
-                "schema": {
-                  "$ref": "#/components/schemas/get_item_schema"
-                }
-              }
-            },
-            "in": "query",
-            "name": "q"
           }
         ],
         "responses": {
@@ -14148,52 +14552,11 @@
             "content": {
               "application/json": {
                 "schema": {
-                  "properties": {
-                    "description_columns": {
-                      "properties": {
-                        "column_name": {
-                          "description": "The description for the column name. Will be translated by babel",
-                          "example": "A Nice description for the column",
-                          "type": "string"
-                        }
-                      },
-                      "type": "object"
-                    },
-                    "id": {
-                      "description": "The item id",
-                      "type": "string"
-                    },
-                    "label_columns": {
-                      "properties": {
-                        "column_name": {
-                          "description": "The label for the column name. Will be translated by babel",
-                          "example": "A Nice label for the column",
-                          "type": "string"
-                        }
-                      },
-                      "type": "object"
-                    },
-                    "result": {
-                      "$ref": "#/components/schemas/DatabaseRestApi.get"
-                    },
-                    "show_columns": {
-                      "description": "A list of columns",
-                      "items": {
-                        "type": "string"
-                      },
-                      "type": "array"
-                    },
-                    "show_title": {
-                      "description": "A title to render. Will be translated by babel",
-                      "example": "Show Item Details",
-                      "type": "string"
-                    }
-                  },
                   "type": "object"
                 }
               }
             },
-            "description": "Item from Model"
+            "description": "Database"
           },
           "400": {
             "$ref": "#/components/responses/400"
@@ -14201,9 +14564,6 @@
           "401": {
             "$ref": "#/components/responses/401"
           },
-          "404": {
-            "$ref": "#/components/responses/404"
-          },
           "422": {
             "$ref": "#/components/responses/422"
           },
@@ -14576,36 +14936,17 @@
         ]
       }
     },
-    "/api/v1/database/{pk}/select_star/{table_name}/{schema_name}/": {
-      "get": {
-        "description": "Get database select star for table",
+    "/api/v1/database/{pk}/ssh_tunnel/": {
+      "delete": {
+        "description": "Deletes a SSH Tunnel.",
         "parameters": [
           {
-            "description": "The database id",
             "in": "path",
             "name": "pk",
             "required": true,
             "schema": {
               "type": "integer"
             }
-          },
-          {
-            "description": "Table name",
-            "in": "path",
-            "name": "table_name",
-            "required": true,
-            "schema": {
-              "type": "string"
-            }
-          },
-          {
-            "description": "Table schema",
-            "in": "path",
-            "name": "schema_name",
-            "required": true,
-            "schema": {
-              "type": "string"
-            }
           }
         ],
         "responses": {
@@ -14613,18 +14954,23 @@
             "content": {
               "application/json": {
                 "schema": {
-                  "$ref": "#/components/schemas/SelectStarResponseSchema"
+                  "properties": {
+                    "message": {
+                      "type": "string"
+                    }
+                  },
+                  "type": "object"
                 }
               }
             },
-            "description": "SQL statement for a select star for table"
-          },
-          "400": {
-            "$ref": "#/components/responses/400"
+            "description": "SSH Tunnel deleted"
           },
           "401": {
             "$ref": "#/components/responses/401"
           },
+          "403": {
+            "$ref": "#/components/responses/403"
+          },
           "404": {
             "$ref": "#/components/responses/404"
           },
@@ -14784,7 +15130,7 @@
         ]
       }
     },
-    "/api/v1/database/{pk}/validate_sql": {
+    "/api/v1/database/{pk}/validate_sql/": {
       "post": {
         "description": "Validates arbitrary SQL.",
         "parameters": [
@@ -15220,16 +15566,6 @@
     "/api/v1/dataset/duplicate": {
       "post": {
         "description": "Duplicates a Dataset",
-        "parameters": [
-          {
-            "in": "path",
-            "name": "pk",
-            "required": true,
-            "schema": {
-              "type": "integer"
-            }
-          }
-        ],
         "requestBody": {
           "content": {
             "application/json": {
@@ -15242,20 +15578,23 @@
           "required": true
         },
         "responses": {
-          "200": {
+          "201": {
             "content": {
               "application/json": {
                 "schema": {
                   "properties": {
-                    "message": {
-                      "type": "string"
+                    "id": {
+                      "type": "number"
+                    },
+                    "result": {
+                      "$ref": "#/components/schemas/DatasetDuplicateSchema"
                     }
                   },
                   "type": "object"
                 }
               }
             },
-            "description": "Dataset duplicate"
+            "description": "Dataset duplicated"
           },
           "400": {
             "$ref": "#/components/responses/400"
@@ -15928,23 +16267,17 @@
         ]
       }
     },
-    "/api/v1/dataset/{pk}/samples": {
+    "/api/v1/embedded_dashboard/{uuid}": {
       "get": {
-        "description": "get samples from a Dataset",
+        "description": "Get a report schedule log",
         "parameters": [
           {
+            "description": "The embedded configuration uuid",
             "in": "path",
-            "name": "pk",
+            "name": "uuid",
             "required": true,
             "schema": {
-              "type": "integer"
-            }
-          },
-          {
-            "in": "query",
-            "name": "force",
-            "schema": {
-              "type": "boolean"
+              "type": "string"
             }
           }
         ],
@@ -15955,27 +16288,21 @@
                 "schema": {
                   "properties": {
                     "result": {
-                      "$ref": "#/components/schemas/ChartDataResponseResult"
+                      "$ref": "#/components/schemas/EmbeddedDashboardResponseSchema"
                     }
                   },
                   "type": "object"
                 }
               }
             },
-            "description": "Dataset samples"
+            "description": "Result contains the embedded dashboard configuration"
           },
           "401": {
             "$ref": "#/components/responses/401"
           },
-          "403": {
-            "$ref": "#/components/responses/403"
-          },
           "404": {
             "$ref": "#/components/responses/404"
           },
-          "422": {
-            "$ref": "#/components/responses/422"
-          },
           "500": {
             "$ref": "#/components/responses/500"
           }
@@ -15986,19 +16313,45 @@
           }
         ],
         "tags": [
-          "Datasets"
+          "Embedded Dashboard"
         ]
       }
     },
-    "/api/v1/embedded_dashboard/{uuid}": {
+    "/api/v1/explore/": {
       "get": {
-        "description": "Get a report schedule log",
+        "description": "Assembles Explore related information (form_data, slice, dataset)\\n in a single endpoint.<br/><br/>\\nThe information can be assembled from:<br/> - The cache using a form_data_key<br/> - The metadata database using a permalink_key<br/> - Build from scratch using dataset or slice identifiers.",
         "parameters": [
           {
-            "description": "The embedded configuration uuid",
-            "in": "path",
-            "name": "uuid",
-            "required": true,
+            "in": "query",
+            "name": "form_data_key",
+            "schema": {
+              "type": "string"
+            }
+          },
+          {
+            "in": "query",
+            "name": "permalink_key",
+            "schema": {
+              "type": "string"
+            }
+          },
+          {
+            "in": "query",
+            "name": "slice_id",
+            "schema": {
+              "type": "integer"
+            }
+          },
+          {
+            "in": "query",
+            "name": "datasource_id",
+            "schema": {
+              "type": "integer"
+            }
+          },
+          {
+            "in": "query",
+            "name": "datasource_type",
             "schema": {
               "type": "string"
             }
@@ -16009,16 +16362,14 @@
             "content": {
               "application/json": {
                 "schema": {
-                  "properties": {
-                    "result": {
-                      "$ref": "#/components/schemas/EmbeddedDashboardResponseSchema"
-                    }
-                  },
-                  "type": "object"
+                  "$ref": "#/components/schemas/ExploreContextSchema"
                 }
               }
             },
-            "description": "Result contains the embedded dashboard configuration"
+            "description": "Returns the initial context."
+          },
+          "400": {
+            "$ref": "#/components/responses/400"
           },
           "401": {
             "$ref": "#/components/responses/401"
@@ -16026,6 +16377,9 @@
           "404": {
             "$ref": "#/components/responses/404"
           },
+          "422": {
+            "$ref": "#/components/responses/422"
+          },
           "500": {
             "$ref": "#/components/responses/500"
           }
@@ -16035,8 +16389,9 @@
             "jwt": []
           }
         ],
+        "summary": "Assembles Explore related information (form_data, slice, dataset)\\n in a single endpoint.",
         "tags": [
-          "Embedded Dashboard"
+          "Explore"
         ]
       }
     },
@@ -17001,6 +17356,59 @@
         ]
       }
     },
+    "/api/v1/query/stop": {
+      "post": {
+        "requestBody": {
+          "content": {
+            "application/json": {
+              "schema": {
+                "$ref": "#/components/schemas/StopQuerySchema"
+              }
+            }
+          },
+          "description": "Stop query schema",
+          "required": true
+        },
+        "responses": {
+          "200": {
+            "content": {
+              "application/json": {
+                "schema": {
+                  "properties": {
+                    "result": {
+                      "type": "string"
+                    }
+                  },
+                  "type": "object"
+                }
+              }
+            },
+            "description": "Query stopped"
+          },
+          "400": {
+            "$ref": "#/components/responses/400"
+          },
+          "401": {
+            "$ref": "#/components/responses/401"
+          },
+          "404": {
+            "$ref": "#/components/responses/404"
+          },
+          "500": {
+            "$ref": "#/components/responses/500"
+          }
+        },
+        "security": [
+          {
+            "jwt": []
+          }
+        ],
+        "summary": "Manually stop a query with client_id",
+        "tags": [
+          "Queries"
+        ]
+      }
+    },
     "/api/v1/query/{pk}": {
       "get": {
         "description": "Get query detail information.",
diff --git a/superset-frontend/src/SqlLab/actions/sqlLab.js b/superset-frontend/src/SqlLab/actions/sqlLab.js
index 12487d1a94..d6447e808c 100644
--- a/superset-frontend/src/SqlLab/actions/sqlLab.js
+++ b/superset-frontend/src/SqlLab/actions/sqlLab.js
@@ -450,9 +450,9 @@ export function validateQuery(queryEditor, sql) {
 export function postStopQuery(query) {
   return function (dispatch) {
     return SupersetClient.post({
-      endpoint: '/superset/stop_query/',
-      postPayload: { client_id: query.id },
-      stringify: false,
+      endpoint: '/api/v1/query/stop',
+      body: JSON.stringify({ client_id: query.id }),
+      headers: { 'Content-Type': 'application/json' },
     })
       .then(() => dispatch(stopQuery(query)))
       .then(() => dispatch(addSuccessToast(t('Query was stopped.'))))
diff --git a/superset-frontend/src/SqlLab/actions/sqlLab.test.js b/superset-frontend/src/SqlLab/actions/sqlLab.test.js
index acc79031ed..fb6ff470b4 100644
--- a/superset-frontend/src/SqlLab/actions/sqlLab.test.js
+++ b/superset-frontend/src/SqlLab/actions/sqlLab.test.js
@@ -317,11 +317,15 @@ describe('async actions', () => {
   });
 
   describe('postStopQuery', () => {
-    const stopQueryEndpoint = 'glob:*/superset/stop_query/*';
+    const stopQueryEndpoint = 'glob:*/api/v1/query/stop';
     fetchMock.post(stopQueryEndpoint, {});
+    const baseQuery = {
+      ...query,
+      id: 'test_foo',
+    };
 
     const makeRequest = () => {
-      const request = actions.postStopQuery(query);
+      const request = actions.postStopQuery(baseQuery);
       return request(dispatch);
     };
 
@@ -346,7 +350,8 @@ describe('async actions', () => {
 
       return makeRequest().then(() => {
         const call = fetchMock.calls(stopQueryEndpoint)[0];
-        expect(call[1].body.get('client_id')).toBe(query.id);
+        const body = JSON.parse(call[1].body);
+        expect(body.client_id).toBe(baseQuery.id);
       });
     });
   });
diff --git a/superset/constants.py b/superset/constants.py
index ea7920ff2f..10de5c52f0 100644
--- a/superset/constants.py
+++ b/superset/constants.py
@@ -140,6 +140,7 @@ MODEL_API_RW_METHOD_PERMISSION_MAP = {
     "get_data": "read",
     "samples": "read",
     "delete_ssh_tunnel": "write",
+    "stop_query": "read",
 }
 
 EXTRA_FORM_DATA_APPEND_KEYS = {
diff --git a/superset/exceptions.py b/superset/exceptions.py
index 153d7439eb..963bf96682 100644
--- a/superset/exceptions.py
+++ b/superset/exceptions.py
@@ -266,3 +266,7 @@ class InvalidPayloadSchemaError(SupersetErrorException):
 
 class SupersetCancelQueryException(SupersetException):
     status = 422
+
+
+class QueryNotFoundException(SupersetException):
+    status = 404
diff --git a/superset/queries/api.py b/superset/queries/api.py
index 1fb342f067..51ba148603 100644
--- a/superset/queries/api.py
+++ b/superset/queries/api.py
@@ -16,14 +16,29 @@
 # under the License.
 import logging
 
+import backoff
+from flask_appbuilder.api import expose, protect, request, safe
 from flask_appbuilder.models.sqla.interface import SQLAInterface
 
+from superset import db, event_logger
 from superset.constants import MODEL_API_RW_METHOD_PERMISSION_MAP, RouteMethod
 from superset.databases.filters import DatabaseFilter
+from superset.exceptions import SupersetException
 from superset.models.sql_lab import Query
+from superset.queries.dao import QueryDAO
 from superset.queries.filters import QueryFilter
-from superset.queries.schemas import openapi_spec_methods_override, QuerySchema
-from superset.views.base_api import BaseSupersetModelRestApi, RelatedFieldFilter
+from superset.queries.schemas import (
+    openapi_spec_methods_override,
+    QuerySchema,
+    StopQuerySchema,
+)
+from superset.superset_typing import FlaskResponse
+from superset.views.base_api import (
+    BaseSupersetModelRestApi,
+    RelatedFieldFilter,
+    requires_json,
+    statsd_metrics,
+)
 from superset.views.filters import BaseFilterRelatedUsers, FilterRelatedOwners
 
 logger = logging.getLogger(__name__)
@@ -43,6 +58,7 @@ class QueryRestApi(BaseSupersetModelRestApi):
         RouteMethod.GET_LIST,
         RouteMethod.RELATED,
         RouteMethod.DISTINCT,
+        "stop_query",
     }
 
     list_columns = [
@@ -95,9 +111,11 @@ class QueryRestApi(BaseSupersetModelRestApi):
     base_filters = [["id", QueryFilter, lambda: []]]
     base_order = ("changed_on", "desc")
     list_model_schema = QuerySchema()
+    stop_query_schema = StopQuerySchema()
 
     openapi_spec_tag = "Queries"
     openapi_spec_methods = openapi_spec_methods_override
+    openapi_spec_component_schemas = (StopQuerySchema,)
 
     order_columns = [
         "changed_on",
@@ -123,3 +141,59 @@ class QueryRestApi(BaseSupersetModelRestApi):
     base_related_field_filters = {"database": [["id", DatabaseFilter, lambda: []]]}
     allowed_rel_fields = {"database", "user"}
     allowed_distinct_fields = {"status"}
+
+    @expose("/stop", methods=["POST"])
+    @protect()
+    @safe
+    @statsd_metrics
+    @event_logger.log_this_with_context(
+        action=lambda self, *args, **kwargs: f"{self.__class__.__name__}"
+        f".stop_query",
+        log_to_statsd=False,
+    )
+    @backoff.on_exception(
+        backoff.constant,
+        Exception,
+        interval=1,
+        on_backoff=lambda details: db.session.rollback(),
+        on_giveup=lambda details: db.session.rollback(),
+        max_tries=5,
+    )
+    @requires_json
+    def stop_query(self) -> FlaskResponse:
+        """Manually stop a query with client_id
+        ---
+        post:
+          summary: Manually stop a query with client_id
+          requestBody:
+            description: Stop query schema
+            required: true
+            content:
+              application/json:
+                schema:
+                  $ref: '#/components/schemas/StopQuerySchema'
+          responses:
+            200:
+              description: Query stopped
+              content:
+                application/json:
+                  schema:
+                    type: object
+                    properties:
+                        result:
+                            type: string
+            400:
+              $ref: '#/components/responses/400'
+            401:
+              $ref: '#/components/responses/401'
+            404:
+              $ref: '#/components/responses/404'
+            500:
+              $ref: '#/components/responses/500'
+        """
+        try:
+            body = self.stop_query_schema.load(request.json)
+            QueryDAO.stop_query(body["client_id"])
+            return self.response(200, result="OK")
+        except SupersetException as ex:
+            return self.response(ex.status, message=ex.message)
diff --git a/superset/queries/dao.py b/superset/queries/dao.py
index c7d59343e8..5867b2917d 100644
--- a/superset/queries/dao.py
+++ b/superset/queries/dao.py
@@ -18,10 +18,14 @@ import logging
 from datetime import datetime
 from typing import Any, Dict
 
+from superset import sql_lab
+from superset.common.db_query_status import QueryStatus
 from superset.dao.base import BaseDAO
+from superset.exceptions import QueryNotFoundException, SupersetCancelQueryException
 from superset.extensions import db
 from superset.models.sql_lab import Query, SavedQuery
 from superset.queries.filters import QueryFilter
+from superset.utils.dates import now_as_float
 
 logger = logging.getLogger(__name__)
 
@@ -56,3 +60,26 @@ class QueryDAO(BaseDAO):
         columns = payload.get("columns", {})
         db.session.add(query)
         query.set_extra_json_key("columns", columns)
+
+    @staticmethod
+    def stop_query(client_id: str) -> None:
+        query = db.session.query(Query).filter_by(client_id=client_id).one_or_none()
+        if not query:
+            raise QueryNotFoundException(f"Query with client_id {client_id} not found")
+
+        if query.status in [
+            QueryStatus.FAILED,
+            QueryStatus.SUCCESS,
+            QueryStatus.TIMED_OUT,
+        ]:
+            logger.warning(
+                "Query with client_id could not be stopped: query already complete",
+            )
+            return
+
+        if not sql_lab.cancel_query(query):
+            raise SupersetCancelQueryException("Could not cancel query")
+
+        query.status = QueryStatus.STOPPED
+        query.end_time = now_as_float()
+        db.session.commit()
diff --git a/superset/queries/schemas.py b/superset/queries/schemas.py
index f11cf37127..a8c1e2bbcb 100644
--- a/superset/queries/schemas.py
+++ b/superset/queries/schemas.py
@@ -67,3 +67,11 @@ class QuerySchema(Schema):
     # pylint: disable=no-self-use
     def get_sql_tables(self, obj: Query) -> List[Table]:
         return obj.sql_tables
+
+
+class StopQuerySchema(Schema):
+    """
+    Schema for the stop_query API call.
+    """
+
+    client_id = fields.String()
diff --git a/superset/views/core.py b/superset/views/core.py
index 62a7c5b963..b9e1981028 100755
--- a/superset/views/core.py
+++ b/superset/views/core.py
@@ -2298,6 +2298,7 @@ class Superset(BaseSupersetView):  # pylint: disable=too-many-public-methods
         on_giveup=lambda details: db.session.rollback(),
         max_tries=5,
     )
+    @deprecated()
     def stop_query(self) -> FlaskResponse:
         client_id = request.form.get("client_id")
         query = db.session.query(Query).filter_by(client_id=client_id).one()
diff --git a/tests/integration_tests/queries/api_tests.py b/tests/integration_tests/queries/api_tests.py
index eaf4e00576..8c193662a1 100644
--- a/tests/integration_tests/queries/api_tests.py
+++ b/tests/integration_tests/queries/api_tests.py
@@ -17,6 +17,7 @@
 # isort:skip_file
 """Unit tests for Superset"""
 from datetime import datetime, timedelta
+from unittest import mock
 import json
 import random
 import string
@@ -392,3 +393,54 @@ class TestQueryApi(SupersetTestCase):
         # rollback changes
         db.session.delete(query)
         db.session.commit()
+
+    @mock.patch("superset.sql_lab.cancel_query")
+    @mock.patch("superset.views.core.db.session")
+    def test_stop_query_not_found(
+        self, mock_superset_db_session, mock_sql_lab_cancel_query
+    ):
+        """
+        Handles stop query when the DB engine spec does not
+        have a cancel query method (with invalid client_id).
+        """
+        form_data = {"client_id": "foo2"}
+        query_mock = mock.Mock()
+        query_mock.return_value = None
+        self.login(username="admin")
+        mock_superset_db_session.query().filter_by().one_or_none = query_mock
+        mock_sql_lab_cancel_query.return_value = True
+        rv = self.client.post(
+            "/api/v1/query/stop",
+            data=json.dumps(form_data),
+            content_type="application/json",
+        )
+
+        assert rv.status_code == 404
+        data = json.loads(rv.data.decode("utf-8"))
+        assert data["message"] == "Query with client_id foo2 not found"
+
+    @mock.patch("superset.sql_lab.cancel_query")
+    @mock.patch("superset.views.core.db.session")
+    def test_stop_query(self, mock_superset_db_session, mock_sql_lab_cancel_query):
+        """
+        Handles stop query when the DB engine spec does not
+        have a cancel query method.
+        """
+        form_data = {"client_id": "foo"}
+        query_mock = mock.Mock()
+        query_mock.client_id = "foo"
+        query_mock.status = QueryStatus.RUNNING
+        self.login(username="admin")
+        mock_superset_db_session.query().filter_by().one_or_none().return_value = (
+            query_mock
+        )
+        mock_sql_lab_cancel_query.return_value = True
+        rv = self.client.post(
+            "/api/v1/query/stop",
+            data=json.dumps(form_data),
+            content_type="application/json",
+        )
+
+        assert rv.status_code == 200
+        data = json.loads(rv.data.decode("utf-8"))
+        assert data["result"] == "OK"
diff --git a/tests/unit_tests/dao/queries_test.py b/tests/unit_tests/dao/queries_test.py
index 8e2a458434..590ba92d48 100644
--- a/tests/unit_tests/dao/queries_test.py
+++ b/tests/unit_tests/dao/queries_test.py
@@ -15,11 +15,14 @@
 # specific language governing permissions and limitations
 # under the License.
 import json
-from typing import Iterator
+from typing import Any, Iterator
 
 import pytest
+from pytest_mock import MockFixture
 from sqlalchemy.orm.session import Session
 
+from superset.exceptions import QueryNotFoundException, SupersetCancelQueryException
+
 
 def test_query_dao_save_metadata(session: Session) -> None:
     from superset.models.core import Database
@@ -53,3 +56,163 @@ def test_query_dao_save_metadata(session: Session) -> None:
     query = session.query(Query).one()
     QueryDAO.save_metadata(query=query, payload={"columns": []})
     assert query.extra.get("columns", None) == []
+
+
+def test_query_dao_stop_query_not_found(
+    mocker: MockFixture, app: Any, session: Session
+) -> None:
+    from superset.common.db_query_status import QueryStatus
+    from superset.models.core import Database
+    from superset.models.sql_lab import Query
+
+    engine = session.get_bind()
+    Query.metadata.create_all(engine)  # pylint: disable=no-member
+
+    db = Database(database_name="my_database", sqlalchemy_uri="sqlite://")
+
+    query_obj = Query(
+        client_id="foo",
+        database=db,
+        tab_name="test_tab",
+        sql_editor_id="test_editor_id",
+        sql="select * from bar",
+        select_sql="select * from bar",
+        executed_sql="select * from bar",
+        limit=100,
+        select_as_cta=False,
+        rows=100,
+        error_message="none",
+        results_key="abc",
+        status=QueryStatus.RUNNING,
+    )
+
+    session.add(db)
+    session.add(query_obj)
+
+    mocker.patch("superset.sql_lab.cancel_query", return_value=False)
+
+    from superset.queries.dao import QueryDAO
+
+    with pytest.raises(QueryNotFoundException):
+        QueryDAO.stop_query("foo2")
+
+    query = session.query(Query).one()
+    assert query.status == QueryStatus.RUNNING
+
+
+def test_query_dao_stop_query_not_running(
+    mocker: MockFixture, app: Any, session: Session
+) -> None:
+    from superset.common.db_query_status import QueryStatus
+    from superset.models.core import Database
+    from superset.models.sql_lab import Query
+
+    engine = session.get_bind()
+    Query.metadata.create_all(engine)  # pylint: disable=no-member
+
+    db = Database(database_name="my_database", sqlalchemy_uri="sqlite://")
+
+    query_obj = Query(
+        client_id="foo",
+        database=db,
+        tab_name="test_tab",
+        sql_editor_id="test_editor_id",
+        sql="select * from bar",
+        select_sql="select * from bar",
+        executed_sql="select * from bar",
+        limit=100,
+        select_as_cta=False,
+        rows=100,
+        error_message="none",
+        results_key="abc",
+        status=QueryStatus.FAILED,
+    )
+
+    session.add(db)
+    session.add(query_obj)
+
+    from superset.queries.dao import QueryDAO
+
+    QueryDAO.stop_query(query_obj.client_id)
+    query = session.query(Query).one()
+    assert query.status == QueryStatus.FAILED
+
+
+def test_query_dao_stop_query_failed(
+    mocker: MockFixture, app: Any, session: Session
+) -> None:
+    from superset.common.db_query_status import QueryStatus
+    from superset.models.core import Database
+    from superset.models.sql_lab import Query
+
+    engine = session.get_bind()
+    Query.metadata.create_all(engine)  # pylint: disable=no-member
+
+    db = Database(database_name="my_database", sqlalchemy_uri="sqlite://")
+
+    query_obj = Query(
+        client_id="foo",
+        database=db,
+        tab_name="test_tab",
+        sql_editor_id="test_editor_id",
+        sql="select * from bar",
+        select_sql="select * from bar",
+        executed_sql="select * from bar",
+        limit=100,
+        select_as_cta=False,
+        rows=100,
+        error_message="none",
+        results_key="abc",
+        status=QueryStatus.RUNNING,
+    )
+
+    session.add(db)
+    session.add(query_obj)
+
+    mocker.patch("superset.sql_lab.cancel_query", return_value=False)
+
+    from superset.queries.dao import QueryDAO
+
+    with pytest.raises(SupersetCancelQueryException):
+        QueryDAO.stop_query(query_obj.client_id)
+
+    query = session.query(Query).one()
+    assert query.status == QueryStatus.RUNNING
+
+
+def test_query_dao_stop_query(mocker: MockFixture, app: Any, session: Session) -> None:
+    from superset.common.db_query_status import QueryStatus
+    from superset.models.core import Database
+    from superset.models.sql_lab import Query
+
+    engine = session.get_bind()
+    Query.metadata.create_all(engine)  # pylint: disable=no-member
+
+    db = Database(database_name="my_database", sqlalchemy_uri="sqlite://")
+
+    query_obj = Query(
+        client_id="foo",
+        database=db,
+        tab_name="test_tab",
+        sql_editor_id="test_editor_id",
+        sql="select * from bar",
+        select_sql="select * from bar",
+        executed_sql="select * from bar",
+        limit=100,
+        select_as_cta=False,
+        rows=100,
+        error_message="none",
+        results_key="abc",
+        status=QueryStatus.RUNNING,
+    )
+
+    session.add(db)
+    session.add(query_obj)
+
+    mocker.patch("superset.sql_lab.cancel_query", return_value=True)
+
+    from superset.queries.dao import QueryDAO
+
+    QueryDAO.stop_query(query_obj.client_id)
+    query = session.query(Query).one()
+    assert query.status == QueryStatus.STOPPED