diff --git a/docs/static/resources/openapi.json b/docs/static/resources/openapi.json index 62153bac51cb8..0540065f8978c 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.User2" }, "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.User" + }, + "created_on_delta_humanized": { + "readOnly": true + }, + "dashboards": { + "$ref": "#/components/schemas/ChartDataRestApi.get_list.Dashboard" }, "datasource_id": { "format": "int32", @@ -1707,7 +1742,7 @@ "type": "string" }, "last_saved_by": { - "$ref": "#/components/schemas/ChartDataRestApi.get_list.User2" + "$ref": "#/components/schemas/ChartDataRestApi.get_list.User3" }, "owners": { "$ref": "#/components/schemas/ChartDataRestApi.get_list.User1" @@ -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" @@ -1803,10 +1856,6 @@ "maxLength": 64, "type": "string" }, - "id": { - "format": "int32", - "type": "integer" - }, "last_name": { "maxLength": 64, "type": "string" @@ -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.User2" }, "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.User" + }, + "created_on_delta_humanized": { + "readOnly": true + }, + "dashboards": { + "$ref": "#/components/schemas/ChartRestApi.get_list.Dashboard" }, "datasource_id": { "format": "int32", @@ -2465,7 +2534,7 @@ "type": "string" }, "last_saved_by": { - "$ref": "#/components/schemas/ChartRestApi.get_list.User2" + "$ref": "#/components/schemas/ChartRestApi.get_list.User3" }, "owners": { "$ref": "#/components/schemas/ChartRestApi.get_list.User1" @@ -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" @@ -2561,10 +2648,6 @@ "maxLength": 64, "type": "string" }, - "id": { - "format": "int32", - "type": "integer" - }, "last_name": { "maxLength": 64, "type": "string" @@ -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": { @@ -3222,7 +3312,7 @@ "type": "string" }, "changed_by": { - "$ref": "#/components/schemas/DashboardRestApi.get_list.User" + "$ref": "#/components/schemas/DashboardRestApi.get_list.User2" }, "changed_by_name": { "readOnly": true @@ -3237,10 +3327,7 @@ "readOnly": true }, "created_by": { - "$ref": "#/components/schemas/DashboardRestApi.get_list.User2" - }, - "created_on_delta_humanized": { - "readOnly": true + "$ref": "#/components/schemas/DashboardRestApi.get_list.User" }, "created_on_delta_humanized": { "readOnly": true @@ -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, @@ -3325,16 +3412,11 @@ "last_name": { "maxLength": 64, "type": "string" - }, - "username": { - "maxLength": 64, - "type": "string" } }, "required": [ "first_name", - "last_name", - "username" + "last_name" ], "type": "object" }, @@ -3382,11 +3464,16 @@ "last_name": { "maxLength": 64, "type": "string" + }, + "username": { + "maxLength": 64, + "type": "string" } }, "required": [ "first_name", - "last_name" + "last_name", + "username" ], "type": "object" }, @@ -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 }, @@ -3752,9 +3833,6 @@ "sqlalchemy_uri": { "maxLength": 1024, "type": "string" - }, - "engine_information": { - "readOnly": true } }, "required": [ @@ -3815,6 +3893,9 @@ "disable_data_preview": { "readOnly": true }, + "engine_information": { + "readOnly": true + }, "explore_database_id": { "readOnly": true }, @@ -3834,9 +3915,6 @@ "id": { "format": "int32", "type": "integer" - }, - "engine_information": { - "readOnly": true } }, "required": [ @@ -3899,8 +3977,8 @@ "minLength": 1, "type": "string" }, - "encrypted_extra": { - "description": "

JSON string containing additional connection configuration.
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.

", + "driver": { + "description": "SQLAlchemy driver to use", "nullable": true, "type": "string" }, @@ -3936,6 +4014,11 @@ "nullable": true, "type": "boolean" }, + "masked_encrypted_extra": { + "description": "

JSON string containing additional connection configuration.
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.

", + "nullable": true, + "type": "string" + }, "parameters": { "additionalProperties": {}, "description": "DB-specific parameters for configuration", @@ -3951,6 +4034,9 @@ "maxLength": 1024, "minLength": 1, "type": "string" + }, + "uuid": { + "type": "string" } }, "required": [ @@ -3997,8 +4083,8 @@ "nullable": true, "type": "string" }, - "encrypted_extra": { - "description": "

JSON string containing additional connection configuration.
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.

", + "driver": { + "description": "SQLAlchemy driver to use", "nullable": true, "type": "string" }, @@ -4034,6 +4120,11 @@ "nullable": true, "type": "boolean" }, + "masked_encrypted_extra": { + "description": "

JSON string containing additional connection configuration.
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.

", + "nullable": true, + "type": "string" + }, "parameters": { "additionalProperties": {}, "description": "DB-specific parameters for configuration", @@ -4066,8 +4157,8 @@ "nullable": true, "type": "string" }, - "encrypted_extra": { - "description": "

JSON string containing additional connection configuration.
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.

", + "driver": { + "description": "SQLAlchemy driver to use", "nullable": true, "type": "string" }, @@ -4084,6 +4175,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.
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": "

JSON string containing additional connection configuration.
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.

", + "nullable": true, + "type": "string" + }, "parameters": { "additionalProperties": {}, "description": "DB-specific parameters for configuration", @@ -4105,6 +4201,13 @@ }, "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 +4218,8 @@ "nullable": true, "type": "string" }, - "encrypted_extra": { - "description": "

JSON string containing additional connection configuration.
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.

", + "driver": { + "description": "SQLAlchemy driver to use", "nullable": true, "type": "string" }, @@ -4128,10 +4231,21 @@ "description": "

JSON string containing extra configuration elements.
1. The engine_params object gets unpacked into the sqlalchemy.create_engine call, while the metadata_params gets unpacked into the sqlalchemy.MetaData call.
2. The metadata_cache_timeout is a cache timeout setting in seconds for metadata fetch of this database. Specify it as \"metadata_cache_timeout\": {\"schema_cache_timeout\": 600, \"table_cache_timeout\": 600}. If unset, cache will not be enabled for the functionality. A timeout of 0 indicates that the cache never expires.
3. The schemas_allowed_for_file_upload is a comma separated list of schemas that CSVs are allowed to upload to. Specify it as \"schemas_allowed_for_file_upload\": [\"public\", \"csv_upload\"]. If database flavor does not support schema or any schema is allowed to be accessed, just leave the list empty
4. The version field is a string specifying the this db's version. This should be used with Presto DBs so that the syntax is correct
5. The allows_virtual_table_explore field is a boolean specifying whether or not the Explore button in SQL Lab results is shown.
6. The disable_data_preview field is a boolean specifying whether or not data preview queries will be run when fetching table metadata in SQL Lab.

", "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.
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": "

JSON string containing additional connection configuration.
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.

", + "nullable": true, + "type": "string" + }, "parameters": { "additionalProperties": { "nullable": true @@ -4151,38 +4265,206 @@ ], "type": "object" }, - "DatasetColumnsPut": { + "Dataset": { "properties": { - "advanced_data_type": { - "maxLength": 255, - "minLength": 1, - "nullable": true, + "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" }, - "column_name": { - "maxLength": 255, - "minLength": 1, + "default_endpoint": { + "description": "Default endpoint for the dataset.", "type": "string" }, "description": { - "nullable": true, + "description": "Dataset description.", "type": "string" }, - "expression": { - "nullable": true, + "edit_url": { + "description": "The URL for editing the dataset.", "type": "string" }, "extra": { - "nullable": true, + "description": "JSON string containing extra configuration elements.", + "type": "object" + }, + "fetch_values_predicate": { + "description": "Predicate used when fetching values from the dataset.", "type": "string" }, - "filterable": { + "filter_select": { + "description": "SELECT filter applied to the dataset.", "type": "boolean" }, - "groupby": { + "filter_select_enabled": { + "description": "If the SELECT filter is enabled.", "type": "boolean" }, - "id": { + "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": { + "maxLength": 255, + "minLength": 1, + "nullable": true, + "type": "string" + }, + "column_name": { + "maxLength": 255, + "minLength": 1, + "type": "string" + }, + "description": { + "nullable": true, + "type": "string" + }, + "expression": { + "nullable": true, + "type": "string" + }, + "extra": { + "nullable": true, + "type": "string" + }, + "filterable": { + "type": "boolean" + }, + "groupby": { + "type": "boolean" + }, + "id": { "format": "int32", "type": "integer" }, @@ -4228,11 +4510,80 @@ }, "DatasetColumnsRestApi.get_list": { "properties": { + "advanced_data_type": { + "maxLength": 255, + "nullable": true, + "type": "string" + }, + "changed_on": { + "format": "date-time", + "nullable": true, + "type": "string" + }, + "column_name": { + "maxLength": 255, + "type": "string" + }, + "created_on": { + "format": "date-time", + "nullable": true, + "type": "string" + }, + "description": { + "nullable": true, + "type": "string" + }, + "expression": { + "nullable": true, + "type": "string" + }, + "extra": { + "nullable": true, + "type": "string" + }, + "filterable": { + "nullable": true, + "type": "boolean" + }, + "groupby": { + "nullable": true, + "type": "boolean" + }, "id": { "format": "int32", "type": "integer" + }, + "is_active": { + "nullable": true, + "type": "boolean" + }, + "is_dttm": { + "nullable": true, + "type": "boolean" + }, + "python_date_format": { + "maxLength": 255, + "nullable": true, + "type": "string" + }, + "type": { + "nullable": true, + "type": "string" + }, + "uuid": { + "format": "uuid", + "nullable": true, + "type": "string" + }, + "verbose_name": { + "maxLength": 1024, + "nullable": true, + "type": "string" } }, + "required": [ + "column_name" + ], "type": "object" }, "DatasetColumnsRestApi.post": { @@ -4446,9 +4797,31 @@ "nullable": true, "type": "integer" }, + "changed_by": { + "$ref": "#/components/schemas/DatasetRestApi.get.User2" + }, + "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.User" + }, + "created_on": { + "format": "date-time", + "nullable": true, + "type": "string" + }, + "created_on_humanized": { + "readOnly": true + }, "database": { "$ref": "#/components/schemas/DatasetRestApi.get.Database" }, @@ -4503,13 +4876,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 +4970,6 @@ "nullable": true, "type": "string" }, - "uuid": { - "format": "uuid", - "nullable": true, - "type": "string" - }, "verbose_name": { "maxLength": 1024, "nullable": true, @@ -4697,6 +5068,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,10 +5110,27 @@ ], "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": { - "$ref": "#/components/schemas/DatasetRestApi.get_list.User1" + "$ref": "#/components/schemas/DatasetRestApi.get_list.User" }, "changed_by_name": { "readOnly": true @@ -4768,7 +5173,7 @@ "readOnly": true }, "owners": { - "$ref": "#/components/schemas/DatasetRestApi.get_list.User" + "$ref": "#/components/schemas/DatasetRestApi.get_list.User1" }, "schema": { "maxLength": 255, @@ -4812,14 +5217,6 @@ "maxLength": 64, "type": "string" }, - "id": { - "format": "int32", - "type": "integer" - }, - "last_name": { - "maxLength": 64, - "type": "string" - }, "username": { "maxLength": 64, "type": "string" @@ -4827,7 +5224,6 @@ }, "required": [ "first_name", - "last_name", "username" ], "type": "object" @@ -4838,6 +5234,14 @@ "maxLength": 64, "type": "string" }, + "id": { + "format": "int32", + "type": "integer" + }, + "last_name": { + "maxLength": 64, + "type": "string" + }, "username": { "maxLength": 64, "type": "string" @@ -4845,6 +5249,7 @@ }, "required": [ "first_name", + "last_name", "username" ], "type": "object" @@ -4875,6 +5280,10 @@ "minLength": 0, "type": "string" }, + "sql": { + "nullable": true, + "type": "string" + }, "table_name": { "maxLength": 250, "minLength": 1, @@ -5004,117 +5413,43 @@ "view" ], "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", - "type": "string" + }, + "schema": { + "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 +5523,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 +6084,7 @@ "type": "string" }, "tracking_url": { - "nullable": true, - "type": "string" + "readOnly": true } }, "required": [ @@ -5840,6 +6193,10 @@ }, "RelatedResultResponse": { "properties": { + "extra": { + "description": "The extra metadata for related item", + "type": "object" + }, "text": { "description": "The related item string representation", "type": "string" @@ -6027,6 +6384,9 @@ "nullable": true, "type": "string" }, + "extra": { + "readOnly": true + }, "force_screenshot": { "nullable": true, "type": "boolean" @@ -6211,7 +6571,7 @@ "type": "boolean" }, "changed_by": { - "$ref": "#/components/schemas/ReportScheduleRestApi.get_list.User" + "$ref": "#/components/schemas/ReportScheduleRestApi.get_list.User2" }, "changed_on": { "format": "date-time", @@ -6227,7 +6587,7 @@ "type": "integer" }, "created_by": { - "$ref": "#/components/schemas/ReportScheduleRestApi.get_list.User2" + "$ref": "#/components/schemas/ReportScheduleRestApi.get_list.User" }, "created_on": { "format": "date-time", @@ -6255,6 +6615,9 @@ "nullable": true, "type": "string" }, + "extra": { + "readOnly": true + }, "id": { "format": "int32", "type": "integer" @@ -7143,6 +7506,9 @@ "nullable": true, "type": "string" }, + "extra": { + "type": "object" + }, "force_screenshot": { "type": "boolean" }, @@ -7867,6 +8233,9 @@ }, "SavedQueryRestApi.get": { "properties": { + "changed_on_delta_humanized": { + "readOnly": true + }, "created_by": { "$ref": "#/components/schemas/SavedQueryRestApi.get.User" }, @@ -7897,6 +8266,10 @@ }, "sql_tables": { "readOnly": true + }, + "template_parameters": { + "nullable": true, + "type": "string" } }, "type": "object" @@ -8059,6 +8432,10 @@ "sql": { "nullable": true, "type": "string" + }, + "template_parameters": { + "nullable": true, + "type": "string" } }, "type": "object" @@ -8087,6 +8464,10 @@ "sql": { "nullable": true, "type": "string" + }, + "template_parameters": { + "nullable": true, + "type": "string" } }, "type": "object" @@ -8112,6 +8493,85 @@ }, "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" + }, "TableExtraMetadataResponseSchema": { "properties": { "clustering": { @@ -8767,99 +9227,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 +10371,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 +10422,7 @@ } ], "tags": [ - "AsyncEventsRestApi" + "Available Domains" ] } }, @@ -11004,6 +11407,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 +14217,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 +14242,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" @@ -14576,75 +14993,6 @@ ] } }, - "/api/v1/database/{pk}/select_star/{table_name}/{schema_name}/": { - "get": { - "description": "Get database select star for table", - "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": { - "200": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/SelectStarResponseSchema" - } - } - }, - "description": "SQL statement for a select star for table" - }, - "400": { - "$ref": "#/components/responses/400" - }, - "401": { - "$ref": "#/components/responses/401" - }, - "404": { - "$ref": "#/components/responses/404" - }, - "422": { - "$ref": "#/components/responses/422" - }, - "500": { - "$ref": "#/components/responses/500" - } - }, - "security": [ - { - "jwt": [] - } - ], - "tags": [ - "Database" - ] - } - }, "/api/v1/database/{pk}/table/{table_name}/{schema_name}/": { "get": { "description": "Get database table metadata", @@ -14784,7 +15132,7 @@ ] } }, - "/api/v1/database/{pk}/validate_sql": { + "/api/v1/database/{pk}/validate_sql/": { "post": { "description": "Validates arbitrary SQL.", "parameters": [ @@ -15220,16 +15568,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 +15580,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" @@ -15575,7 +15916,7 @@ "type": "object" }, "result": { - "$ref": "#/components/schemas/DatasetRestApi.get" + "$ref": "#/components/schemas/DatasetColumnsRestApi.get" }, "show_columns": { "description": "A list of columns", @@ -15699,6 +16040,85 @@ ] } }, + "/api/v1/dataset/{pk}/column/": { + "get": { + "description": "Get a list of dataset columns", + "parameters": [ + { + "description": "The dataset id for these columns", + "in": "path", + "name": "pk", + "required": true, + "schema": { + "type": "integer" + } + }, + { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/get_list_schema" + } + } + }, + "in": "query", + "name": "q" + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "properties": { + "count": { + "description": "The total record count on the backend", + "type": "number" + }, + "ids": { + "description": "A list of column ids", + "items": { + "type": "string" + }, + "type": "array" + }, + "result": { + "description": "The result from the get list query", + "items": { + "$ref": "#/components/schemas/DatasetColumnsRestApi.get_list" + }, + "type": "array" + } + }, + "type": "object" + } + } + }, + "description": "Columns from dataset" + }, + "400": { + "$ref": "#/components/responses/400" + }, + "401": { + "$ref": "#/components/responses/401" + }, + "422": { + "$ref": "#/components/responses/422" + }, + "500": { + "$ref": "#/components/responses/500" + } + }, + "security": [ + { + "jwt": [] + } + ], + "tags": [ + "Datasets" + ] + } + }, "/api/v1/dataset/{pk}/column/{column_id}": { "delete": { "description": "Delete a Dataset column", @@ -15928,23 +16348,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 +16369,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 +16394,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.

\\nThe information can be assembled from:
- The cache using a form_data_key
- The metadata database using a permalink_key
- 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": "dataset_id", + "schema": { + "type": "integer" + } + }, + { + "in": "query", + "name": "dataset_type", "schema": { "type": "string" } @@ -16009,16 +16443,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 +16458,9 @@ "404": { "$ref": "#/components/responses/404" }, + "422": { + "$ref": "#/components/responses/422" + }, "500": { "$ref": "#/components/responses/500" } @@ -16035,8 +16470,9 @@ "jwt": [] } ], + "summary": "Assembles Explore related information (form_data, slice, dataset)\\n in a single endpoint.", "tags": [ - "Embedded Dashboard" + "Explore" ] } }, diff --git a/superset-frontend/cypress-base/cypress/integration/dashboard/utils.ts b/superset-frontend/cypress-base/cypress/integration/dashboard/utils.ts index 89d3be8b9ef46..81942e784fcbf 100644 --- a/superset-frontend/cypress-base/cypress/integration/dashboard/utils.ts +++ b/superset-frontend/cypress-base/cypress/integration/dashboard/utils.ts @@ -146,8 +146,8 @@ export function interceptUnfav() { cy.intercept(`/superset/favstar/Dashboard/*/unselect/`).as('unselect'); } -export function interceptDataset() { - cy.intercept('GET', `/api/v1/dataset/*`).as('getDataset'); +export function interceptDatasetColumns() { + cy.intercept('GET', `/api/v1/dataset/*/column`).as('getDatasetColumns'); } export function interceptCharts() { @@ -209,13 +209,13 @@ export function collapseFilterOnLeftPanel() { * @summary helper for enter native filter edit modal ************************************************************************* */ export function enterNativeFilterEditModal(waitForDataset = true) { - interceptDataset(); + interceptDatasetColumns(); cy.get(nativeFilters.filterFromDashboardView.createFilterButton).click({ force: true, }); cy.get(nativeFilters.modal.container).should('be.visible'); if (waitForDataset) { - cy.wait('@getDataset'); + cy.wait('@getDatasetColumns'); } } diff --git a/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/ColumnSelect.test.tsx b/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/ColumnSelect.test.tsx index 424b16835dfb3..ef0b3fb17eb2c 100644 --- a/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/ColumnSelect.test.tsx +++ b/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/ColumnSelect.test.tsx @@ -24,26 +24,22 @@ import { Column, JsonObject } from '@superset-ui/core'; import userEvent from '@testing-library/user-event'; import { ColumnSelect } from './ColumnSelect'; -fetchMock.get('glob:*/api/v1/dataset/123', { +fetchMock.get('glob:*/api/v1/dataset/123/column', { body: { - result: { - columns: [ - { column_name: 'column_name_01', is_dttm: true }, - { column_name: 'column_name_02', is_dttm: false }, - { column_name: 'column_name_03', is_dttm: false }, - ], - }, + result: [ + { column_name: 'column_name_01', is_dttm: true }, + { column_name: 'column_name_02', is_dttm: false }, + { column_name: 'column_name_03', is_dttm: false }, + ], }, }); -fetchMock.get('glob:*/api/v1/dataset/456', { +fetchMock.get('glob:*/api/v1/dataset/456/column', { body: { - result: { - columns: [ - { column_name: 'column_name_04', is_dttm: false }, - { column_name: 'column_name_05', is_dttm: false }, - { column_name: 'column_name_06', is_dttm: false }, - ], - }, + result: [ + { column_name: 'column_name_04', is_dttm: false }, + { column_name: 'column_name_05', is_dttm: false }, + { column_name: 'column_name_06', is_dttm: false }, + ], }, }); diff --git a/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/ColumnSelect.tsx b/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/ColumnSelect.tsx index 41c591ade3c81..db56b006a4791 100644 --- a/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/ColumnSelect.tsx +++ b/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/ColumnSelect.tsx @@ -98,17 +98,17 @@ export function ColumnSelect({ } if (datasetId != null) { cachedSupersetGet({ - endpoint: `/api/v1/dataset/${datasetId}`, + endpoint: `/api/v1/dataset/${datasetId}/column`, }).then( ({ json: { result } }) => { const lookupValue = Array.isArray(value) ? value : [value]; - const valueExists = result.columns.some((column: Column) => + const valueExists = result.some((column: Column) => lookupValue?.includes(column.column_name), ); if (!valueExists) { resetColumnField(); } - setColumns(result.columns); + setColumns(result); }, async badResponse => { const { error, message } = await getClientErrorObject(badResponse); diff --git a/superset/datasets/columns/api.py b/superset/datasets/columns/api.py index cd260a423bd72..a400c312cf814 100644 --- a/superset/datasets/columns/api.py +++ b/superset/datasets/columns/api.py @@ -15,13 +15,15 @@ # specific language governing permissions and limitations # under the License. import logging +from typing import Any from flask import Response -from flask_appbuilder.api import expose, permission_name, protect, safe +from flask_appbuilder.api import expose, permission_name, protect, rison, safe +from flask_appbuilder.api.schemas import get_list_schema from flask_appbuilder.models.sqla.interface import SQLAInterface from superset.connectors.sqla.models import TableColumn -from superset.constants import MODEL_API_RW_METHOD_PERMISSION_MAP +from superset.constants import MODEL_API_RW_METHOD_PERMISSION_MAP, RouteMethod from superset.datasets.columns.commands.delete import DeleteDatasetColumnCommand from superset.datasets.columns.commands.exceptions import ( DatasetColumnDeleteFailedError, @@ -36,14 +38,99 @@ class DatasetColumnsRestApi(BaseSupersetModelRestApi): datamodel = SQLAInterface(TableColumn) - include_route_methods = {"delete"} + allow_browser_login = True class_permission_name = "Dataset" + include_route_methods = {RouteMethod.DELETE, RouteMethod.GET_LIST} method_permission_name = MODEL_API_RW_METHOD_PERMISSION_MAP - + list_columns = [ # See DatasetRestApi.show_select_columns. + "advanced_data_type", + "changed_on", + "column_name", + "created_on", + "description", + "expression", + "filterable", + "groupby", + "id", + "is_active", + "extra", + "is_dttm", + "python_date_format", + "type", + "uuid", + "verbose_name", + ] + search_columns = ["table_id"] + max_page_size = -1 + openapi_spec_tag = "Datasets" resource_name = "dataset" - allow_browser_login = True - openapi_spec_tag = "Datasets" + @expose("//column", methods=["GET"]) + @protect() + @safe + @permission_name("get") + @rison(get_list_schema) + def get_list( # pylint: disable=arguments-differ + self, + pk: int, + **kwargs: Any, + ) -> Response: + """Get a list of dataset columns + --- + get: + description: >- + Get a list of dataset columns + parameters: + - in: path + schema: + type: integer + description: The dataset id for these columns + name: pk + - in: query + name: q + content: + application/json: + schema: + $ref: '#/components/schemas/get_list_schema' + responses: + 200: + description: Columns from dataset + content: + application/json: + schema: + type: object + properties: + ids: + description: >- + A list of column ids + type: array + items: + type: string + count: + description: >- + The total record count on the backend + type: number + result: + description: >- + The result from the get list query + type: array + items: + $ref: '#/components/schemas/{{self.__class__.__name__}}.get_list' # pylint: disable=line-too-long + 400: + $ref: '#/components/responses/400' + 401: + $ref: '#/components/responses/401' + 422: + $ref: '#/components/responses/422' + 500: + $ref: '#/components/responses/500' + """ + + rison_data = kwargs.setdefault("rison", {}) + rison_data.setdefault("filters", []) + rison_data["filters"].append({"col": "table_id", "opr": "eq", "value": pk}) + rison_data["page_size"] = -1 + return self.get_list_headless(**kwargs) @expose("//column/", methods=["DELETE"]) @protect() diff --git a/tests/integration_tests/datasets/api_tests.py b/tests/integration_tests/datasets/api_tests.py index af3a956834aac..aaa10ab18154f 100644 --- a/tests/integration_tests/datasets/api_tests.py +++ b/tests/integration_tests/datasets/api_tests.py @@ -57,6 +57,10 @@ dataset_metadata_config, dataset_ui_export, ) +from tests.integration_tests.fixtures.world_bank_dashboard import ( + load_world_bank_dashboard_with_slices, + load_world_bank_data, +) class TestDatasetApi(SupersetTestCase): @@ -2298,3 +2302,17 @@ def test_duplicate_invalid_dataset(self): } rv = self.post_assert_metric(uri, table_data, "duplicate") assert rv.status_code == 422 + + @pytest.mark.usefixtures("load_world_bank_dashboard_with_slices") + def test_get_dataset_columns(self): + if backend() == "sqlite": + return + + self.login(username="admin") + table = self.get_table(name="wb_health_population") + uri = f"api/v1/dataset/{table.id}/column" + rv = self.get_assert_metric(uri, "get_list") + response = json.loads(rv.data.decode("utf-8")) + assert rv.status_code == 200 + assert response["count"] == 328 + assert len(response["ids"]) == 328 # Non-paginated results.