Skip to content

Commit

Permalink
chore: remove deprecated apis stop_query, queries, search_queries (#2…
Browse files Browse the repository at this point in the history
  • Loading branch information
dpgaspar committed Jun 13, 2023
1 parent ca478bd commit c8e958f
Show file tree
Hide file tree
Showing 6 changed files with 2 additions and 296 deletions.
3 changes: 0 additions & 3 deletions RESOURCES/STANDARD_ROLES.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,6 @@
|can user slices on Superset|:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|
|can favstar on Superset|:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|
|can import dashboards on Superset|:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|
|can search queries on Superset|:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|
|can sqllab viz on Superset|:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|
|can schemas on Superset|:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|
|can sqllab history on Superset|:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|
Expand Down Expand Up @@ -92,8 +91,6 @@
|can sqllab table viz on Superset|:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|
|can profile on Superset|:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|
|can available domains on Superset|:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|
|can queries on Superset|:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|
|can stop query on Superset|:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|
|can request access on Superset|:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|
|can dashboard on Superset|:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|
|can post on TableSchemaView|:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|
Expand Down
1 change: 1 addition & 0 deletions UPDATING.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ assists people when migrating to a new version.

### Breaking Changes

- [24360](https://github.com/apache/superset/pull/24360): Removed deprecated APIs `/superset/stop_query/...`, `/superset/queries/...`, `/superset/search_queries`
- [24353](https://github.com/apache/superset/pull/24353): Removed deprecated APIs `/copy_dash/int:dashboard_id/`, `/save_dash/int:dashboard_id/`, `/add_slices/int:dashboard_id/`.
- [24198](https://github.com/apache/superset/pull/24198) The FAB views `User Registrations` and `User's Statistics` have been changed to Admin only. To re-enable them for non-admin users, please add the following perms to your custom role: `menu access on User's Statistics` and `menu access on User Registrations`.
- [24354](https://github.com/apache/superset/pull/24354): Removed deprecated APIs `/superset/testconn`, `/superset/validate_sql_json/`, `/superset/schemas_access_for_file_upload`, `/superset/extra_table_metadata`
Expand Down
2 changes: 0 additions & 2 deletions superset/security/manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -241,9 +241,7 @@ class SupersetSecurityManager( # pylint: disable=too-many-public-methods
("can_sqllab_viz", "Superset"),
("can_sqllab_table_viz", "Superset"), # Deprecated permission remove on 3.0.0
("can_sqllab", "Superset"),
("can_stop_query", "Superset"), # Deprecated permission remove on 3.0.0
("can_test_conn", "Superset"), # Deprecated permission remove on 3.0.0
("can_search_queries", "Superset"), # Deprecated permission remove on 3.0.0
("can_activate", "TabStateView"),
("can_get", "TabStateView"),
("can_delete_query", "TabStateView"),
Expand Down
140 changes: 0 additions & 140 deletions superset/views/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
from typing import Any, Callable, cast
from urllib import parse

import backoff
import simplejson as json
from flask import abort, flash, g, redirect, render_template, request, Response
from flask_appbuilder import expose
Expand All @@ -44,21 +43,18 @@
event_logger,
is_feature_enabled,
security_manager,
sql_lab,
viz,
)
from superset.charts.commands.exceptions import ChartNotFoundError
from superset.charts.dao import ChartDAO
from superset.common.chart_data import ChartDataResultFormat, ChartDataResultType
from superset.common.db_query_status import QueryStatus
from superset.connectors.base.models import BaseDatasource
from superset.connectors.sqla.models import (
AnnotationDatasource,
SqlaTable,
SqlMetric,
TableColumn,
)
from superset.constants import QUERY_EARLY_CANCEL_KEY
from superset.dashboards.commands.exceptions import DashboardAccessDeniedError
from superset.dashboards.commands.importers.v0 import ImportDashboardsCommand
from superset.dashboards.permalink.commands.get import GetDashboardPermalinkCommand
Expand All @@ -70,7 +66,6 @@
from superset.exceptions import (
CacheLoadError,
DatabaseNotFound,
SupersetCancelQueryException,
SupersetErrorException,
SupersetException,
SupersetGenericErrorException,
Expand All @@ -94,7 +89,6 @@
from superset.utils.async_query_manager import AsyncQueryTokenException
from superset.utils.cache import etag_cache
from superset.utils.core import DatasourceType, get_user_id, ReservedUrlParameters
from superset.utils.dates import now_as_float
from superset.views.base import (
api,
BaseSupersetView,
Expand Down Expand Up @@ -1433,44 +1427,6 @@ def extra_table_metadata( # pylint: disable=no-self-use
def theme(self) -> FlaskResponse:
return self.render_template("superset/theme.html")

@has_access_api
@handle_api_exception
@expose("/stop_query/", methods=("POST",))
@event_logger.log_this
@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,
)
@deprecated(new_target="/api/v1/query/stop")
def stop_query(self) -> FlaskResponse:
client_id = request.form.get("client_id")
query = db.session.query(Query).filter_by(client_id=client_id).one()
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 self.json_response("OK")

if not sql_lab.cancel_query(query):
raise SupersetCancelQueryException("Could not cancel query")

query.status = QueryStatus.STOPPED
# Add the stop identity attribute because the sqlalchemy thread is unsafe
# because of multiple updates to the status in the query table
query.set_extra_json_key(QUERY_EARLY_CANCEL_KEY, True)
query.end_time = now_as_float()
db.session.commit()

return self.json_response("OK")

@api
@handle_api_exception
@has_access
Expand All @@ -1495,102 +1451,6 @@ def fetch_datasource_metadata(self) -> FlaskResponse: # pylint: disable=no-self
datasource.raise_for_access()
return json_success(json.dumps(sanitize_datasource_data(datasource.data)))

@has_access_api
@event_logger.log_this
@expose("/queries/<float:last_updated_ms>")
@expose("/queries/<int:last_updated_ms>")
@deprecated(new_target="api/v1/query/updated_since")
def queries(self, last_updated_ms: float | int) -> FlaskResponse:
"""
Get the updated queries.
:param last_updated_ms: Unix time (milliseconds)
"""

return self.queries_exec(last_updated_ms)

@staticmethod
def queries_exec(last_updated_ms: float | int) -> FlaskResponse:
stats_logger.incr("queries")
if not get_user_id():
return json_error_response(
"Please login to access the queries.", status=403
)

# UTC date time, same that is stored in the DB.
last_updated_dt = datetime.utcfromtimestamp(last_updated_ms / 1000)

sql_queries = (
db.session.query(Query)
.filter(Query.user_id == get_user_id(), Query.changed_on >= last_updated_dt)
.all()
)
dict_queries = {q.client_id: q.to_dict() for q in sql_queries}
return json_success(json.dumps(dict_queries, default=utils.json_int_dttm_ser))

@has_access
@event_logger.log_this
@expose("/search_queries")
@deprecated(new_target="api/v1/query/")
def search_queries(self) -> FlaskResponse: # pylint: disable=no-self-use
"""
Search for previously run sqllab queries. Used for Sqllab Query Search
page /superset/sqllab#search.
Custom permission can_only_search_queries_owned restricts queries
to only queries run by current user.
:returns: Response with list of sql query dicts
"""
if security_manager.can_access_all_queries():
search_user_id = request.args.get("user_id")
elif request.args.get("user_id") is not None:
try:
search_user_id = int(cast(int, request.args.get("user_id")))
except ValueError:
return Response(status=400, mimetype="application/json")
if search_user_id != get_user_id():
return Response(status=403, mimetype="application/json")
else:
search_user_id = get_user_id()
database_id = request.args.get("database_id")
search_text = request.args.get("search_text")
# From and To time stamp should be Epoch timestamp in seconds

query = db.session.query(Query)
if search_user_id:
# Filter on user_id
query = query.filter(Query.user_id == search_user_id)

if database_id:
# Filter on db Id
query = query.filter(Query.database_id == database_id)

if status := request.args.get("status"):
# Filter on status
query = query.filter(Query.status == status)

if search_text:
# Filter on search text
query = query.filter(Query.sql.like(f"%{search_text}%"))

if from_time := request.args.get("from"):
query = query.filter(Query.start_time > int(from_time))

if to_time := request.args.get("to"):
query = query.filter(Query.start_time < int(to_time))

query_limit = config["QUERY_SEARCH_LIMIT"]
sql_queries = query.order_by(Query.start_time.asc()).limit(query_limit).all()

dict_queries = [q.to_dict() for q in sql_queries]

return Response(
json.dumps(dict_queries, default=utils.json_int_dttm_ser),
status=200,
mimetype="application/json",
)

@app.errorhandler(500)
def show_traceback(self) -> FlaskResponse: # pylint: disable=no-self-use
return (
Expand Down
23 changes: 0 additions & 23 deletions tests/integration_tests/core_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -1243,29 +1243,6 @@ def test_dashboard_injected_exceptions(self, mock_db_connection_mutator):
data = self.get_resp(url)
self.assertIn("Error message", data)

@mock.patch("superset.sql_lab.cancel_query")
@mock.patch("superset.views.core.db.session")
def test_stop_query_not_implemented(
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().return_value = query_mock
mock_sql_lab_cancel_query.return_value = False
rv = self.client.post(
"/superset/stop_query/",
data={"form_data": json.dumps(form_data)},
)

assert rv.status_code == 422

@pytest.mark.usefixtures("load_energy_table_with_slice")
@mock.patch("superset.explore.form_data.commands.create.CreateFormDataCommand.run")
def test_explore_redirect(self, mock_command: mock.Mock):
Expand Down
Loading

0 comments on commit c8e958f

Please sign in to comment.