class_docstr: The base views for Superset!
class_docstr_tok: ["The","base","views","for","Superset","!"]
code: def explore(
      self,
      datasource_type: str | None = None,
      datasource_id: int | None = None,
      key: str | None = None,
  ) -> FlaskResponse:
      if request.method == "GET":
          return redirect(Superset.get_redirect_url())
  
      initial_form_data = {}
  
      form_data_key = request.args.get("form_data_key")
      if key is not None:
          command = GetExplorePermalinkCommand(key)
          try:
              if permalink_value := command.run():
                  state = permalink_value["state"]
                  initial_form_data = state["formData"]
                  url_params = state.get("urlParams")
                  if url_params:
                      initial_form_data["url_params"] = dict(url_params)
              else:
                  return json_error_response(
                      _("Error: permalink state not found"), status=404
                  )
          except (
              ChartNotFoundError,
              ExplorePermalinkGetFailedError,
          ) as ex:
              flash(__("Error: %(msg)s", msg=ex.message), "danger")
              return redirect("/chart/list/")
      elif form_data_key:
          parameters = CommandParameters(key=form_data_key)
          value = GetFormDataCommand(parameters).run()
          initial_form_data = json.loads(value) if value else {}
  
      if not initial_form_data:
          slice_id = request.args.get("slice_id")
          dataset_id = request.args.get("dataset_id")
          if slice_id:
              initial_form_data["slice_id"] = slice_id
              if form_data_key:
                  flash(
                      _(
                          "Form data not found in cache, reverting to chart metadata."
                      )
                  )
          elif dataset_id:
              initial_form_data["datasource"] = f"{dataset_id}__table"
              if form_data_key:
                  flash(
                      _(
                          "Form data not found in cache, reverting to dataset metadata."
                      )
                  )
  
      form_data, slc = get_form_data(
          use_slice_data=True, initial_form_data=initial_form_data
      )
  
      query_context = request.form.get("query_context")
  
      try:
          datasource_id, datasource_type = get_datasource_info(
              datasource_id, datasource_type, form_data
          )
      except SupersetException:
          datasource_id = None
          # fallback unknown datasource to table type
          datasource_type = SqlaTable.type
  
      datasource: BaseDatasource | None = None
      if datasource_id is not None:
          with contextlib.suppress(DatasetNotFoundError):
              datasource = DatasourceDAO.get_datasource(
                  db.session,
                  DatasourceType("table"),
                  datasource_id,
              )
  
      datasource_name = (
          datasource.name if datasource else _("[Missing Dataset]")
      )
      viz_type = form_data.get("viz_type")
      if not viz_type and datasource and datasource.default_endpoint:
          return redirect(datasource.default_endpoint)
  
      selectedColumns = []
  
      if "selectedColumns" in form_data:
          selectedColumns = form_data.pop("selectedColumns")
  
      if "viz_type" not in form_data:
          form_data["viz_type"] = app.config["DEFAULT_VIZ_TYPE"]
          if app.config["DEFAULT_VIZ_TYPE"] == "table":
              all_columns = []
              for x in selectedColumns:
                  all_columns.append(x["name"])
              form_data["all_columns"] = all_columns
  
      # slc perms
      slice_add_perm = security_manager.can_access("can_write", "Chart")
      slice_overwrite_perm = (
          security_manager.is_owner(slc) if slc else False
      )
      slice_download_perm = security_manager.can_access(
          "can_csv", "Superset"
      )
  
      form_data["datasource"] = (
          str(datasource_id) + "__" + cast(str, datasource_type)
      )
  
      # On explore, merge legacy and extra filters into the form data
      utils.convert_legacy_filters_into_adhoc(form_data)
      utils.merge_extra_filters(form_data)
  
      # merge request url params
      if request.method == "GET":
          utils.merge_request_params(form_data, request.args)
  
      # handle save or overwrite
      action = request.args.get("action")
  
      if action == "overwrite" and not slice_overwrite_perm:
          return json_error_response(
              _("You don't have the rights to alter this chart"),
              status=403,
          )
  
      if action == "saveas" and not slice_add_perm:
          return json_error_response(
              _("You don't have the rights to create a chart"),
              status=403,
          )
  
      if action in ("saveas", "overwrite") and datasource:
          return self.save_or_overwrite_slice(
              slc,
              slice_add_perm,
              slice_overwrite_perm,
              slice_download_perm,
              datasource.id,
              datasource.type,
              datasource.name,
              query_context,
          )
      standalone_mode = ReservedUrlParameters.is_standalone_mode()
      force = request.args.get("force") in {"force", "1", "true"}
      dummy_datasource_data: dict[str, Any] = {
          "type": datasource_type,
          "name": datasource_name,
          "columns": [],
          "metrics": [],
          "database": {"id": 0, "backend": ""},
      }
      try:
          datasource_data = (
              datasource.data if datasource else dummy_datasource_data
          )
      except (SupersetException, SQLAlchemyError):
          datasource_data = dummy_datasource_data
  
      if datasource:
          datasource_data["owners"] = datasource.owners_data
          if isinstance(datasource, Query):
              datasource_data["columns"] = datasource.columns
  
      bootstrap_data = {
          "can_add": slice_add_perm,
          "datasource": sanitize_datasource_data(datasource_data),
          "form_data": form_data,
          "datasource_id": datasource_id,
          "datasource_type": datasource_type,
          "slice": slc.data if slc else None,
          "standalone": standalone_mode,
          "force": force,
          "user": bootstrap_user_data(g.user, include_perms=True),
          "forced_height": request.args.get("height"),
          "common": common_bootstrap_payload(),
      }
      if slc:
          title = slc.slice_name
      elif datasource:
          table_name = (
              datasource.table_name
              if datasource_type == "table"
              else datasource.datasource_name
          )
          title = _("Explore - %(table)s", table=table_name)
      else:
          title = _("Explore")
  
      return self.render_template(
          "superset/basic.html",
          bootstrap_data=json.dumps(
              bootstrap_data,
              default=utils.pessimistic_json_iso_dttm_ser,
          ),
          entry="explore",
          title=title,
          standalone_mode=standalone_mode,
      )
  
imports: from __future__ import annotations
  import contextlib
  import logging
  from datetime import datetime
  from typing import Any, Callable, cast
  from urllib import parse
  import simplejson
  from flask import abort, flash, g, redirect, render_template, request, Response
  from flask_appbuilder import expose
  from flask_appbuilder.security.decorators import has_access, has_access_api, permission_name
  from flask_babel import gettext, lazy_gettext
  from sqlalchemy.exc import SQLAlchemyError
  from superset import app, appbuilder, conf, db, event_logger, is_feature_enabled, security_manager
  from superset.async_events.async_query_manager import AsyncQueryTokenException
  from superset.commands.chart.exceptions import ChartNotFoundError
  from superset.commands.chart.warm_up_cache import ChartWarmUpCacheCommand
  from superset.commands.dashboard.importers.v0 import ImportDashboardsCommand
  from superset.commands.dashboard.permalink.get import GetDashboardPermalinkCommand
  from superset.commands.dataset.exceptions import DatasetNotFoundError
  from superset.commands.explore.form_data.create import CreateFormDataCommand
  from superset.commands.explore.form_data.get import GetFormDataCommand
  from superset.commands.explore.form_data.parameters import CommandParameters
  from superset.commands.explore.permalink.get import GetExplorePermalinkCommand
  from superset.common.chart_data import ChartDataResultFormat, ChartDataResultType
  from superset.connectors.sqla.models import BaseDatasource, SqlaTable
  from superset.daos.chart import ChartDAO
  from superset.daos.datasource import DatasourceDAO
  from superset.dashboards.permalink.exceptions import DashboardPermalinkGetFailedError
  from superset.exceptions import CacheLoadError, DatabaseNotFound, SupersetException, SupersetSecurityException
  from superset.explore.permalink.exceptions import ExplorePermalinkGetFailedError
  from superset.extensions import async_query_manager, cache_manager
  from superset.models.core import Database
  from superset.models.dashboard import Dashboard
  from superset.models.slice import Slice
  from superset.models.sql_lab import Query
  from superset.models.user_attributes import UserAttribute
  from superset.superset_typing import FlaskResponse
  from superset.utils import core
  from superset.utils.cache import etag_cache
  from superset.utils.core import base_json_conv, DatasourceType, get_user_id, ReservedUrlParameters
  from superset.views.base import api, BaseSupersetView, common_bootstrap_payload, CsvResponse, data_payload_response, deprecated, generate_download_headers, get_error_msg, handle_api_exception, json_error_response, json_success
  from superset.views.utils import bootstrap_user_data, check_datasource_perms, check_explore_cache_perms, check_resource_permissions, get_datasource_info, get_form_data, get_viz, loads_request_json, redirect_with_flash, sanitize_datasource_data
  from superset.viz import BaseViz
label_desc: Use image node_id 11 for calling the Superset obj's underlying member method code with example usage: obj.explore(datasource_type, datasource_id, key) and returns: self, redirect, redirect, json_error_response, json_error_response, self, json_error_response, redirect