class_docstr: The base views for Superset!
class_docstr_tok: ["The","base","views","for","Superset","!"]
docstr: Save or overwrite a slice
docstr_tok: ["Save","or","overwrite","a","slice"]
code: def save_or_overwrite_slice(
      # pylint: disable=too-many-arguments,too-many-locals
      slc: Slice | None,
      slice_add_perm: bool,
      slice_overwrite_perm: bool,
      slice_download_perm: bool,
      datasource_id: int,
      datasource_type: str,
      datasource_name: str,
      query_context: str | None = None,
  ) -> FlaskResponse:
      """Save or overwrite a slice"""
      slice_name = request.args.get("slice_name")
      action = request.args.get("action")
      form_data = get_form_data()[0]
  
      if action == "saveas":
          if "slice_id" in form_data:
              form_data.pop("slice_id")  # don't save old slice_id
          slc = Slice(owners=[g.user] if g.user else [])
  
      utils.remove_extra_adhoc_filters(form_data)
  
      assert slc
      slc.params = json.dumps(form_data, indent=2, sort_keys=True)
      slc.datasource_name = datasource_name
      slc.viz_type = form_data["viz_type"]
      slc.datasource_type = datasource_type
      slc.datasource_id = datasource_id
      slc.last_saved_by = g.user
      slc.last_saved_at = datetime.now()
      slc.slice_name = slice_name
      slc.query_context = query_context
  
      if action == "saveas" and slice_add_perm:
          ChartDAO.create(slc)
          msg = _("Chart [{}] has been saved").format(slc.slice_name)
          flash(msg, "success")
      elif action == "overwrite" and slice_overwrite_perm:
          ChartDAO.update(slc)
          msg = _("Chart [{}] has been overwritten").format(
              slc.slice_name
          )
          flash(msg, "success")
  
      # Adding slice to a dashboard if requested
      dash: Dashboard | None = None
  
      save_to_dashboard_id = request.args.get("save_to_dashboard_id")
      new_dashboard_name = request.args.get("new_dashboard_name")
      if save_to_dashboard_id:
          # Adding the chart to an existing dashboard
          dash = cast(
              Dashboard,
              db.session.query(Dashboard)
              .filter_by(id=int(save_to_dashboard_id))
              .one(),
          )
          # check edit dashboard permissions
          dash_overwrite_perm = security_manager.is_owner(dash)
          if not dash_overwrite_perm:
              return json_error_response(
                  _(
                      "You don't have the rights to alter this dashboard"
                  ),
                  status=403,
              )
  
          flash(
              _("Chart [{}] was added to dashboard [{}]").format(
                  slc.slice_name, dash.dashboard_title
              ),
              "success",
          )
      elif new_dashboard_name:
          # Creating and adding to a new dashboard
          # check create dashboard permissions
          dash_add_perm = security_manager.can_access(
              "can_write", "Dashboard"
          )
          if not dash_add_perm:
              return json_error_response(
                  _("You don't have the rights to create a dashboard"),
                  status=403,
              )
  
          dash = Dashboard(
              dashboard_title=request.args.get("new_dashboard_name"),
              owners=[g.user] if g.user else [],
          )
          flash(
              _(
                  "Dashboard [{}] just got created and chart [{}] was added to it"
              ).format(dash.dashboard_title, slc.slice_name),
              "success",
          )
  
      if dash and slc not in dash.slices:
          dash.slices.append(slc)
          db.session.commit()
  
      response = {
          "can_add": slice_add_perm,
          "can_download": slice_download_perm,
          "form_data": slc.form_data,
          "slice": slc.data,
          "dashboard_url": dash.url if dash else None,
          "dashboard_id": dash.id if dash else None,
      }
  
      if dash and request.args.get("goto_dash") == "true":
          response.update({"dashboard": dash.url})
  
      return json_success(json.dumps(response))
  
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 12 for calling the Superset obj's underlying member method code with example usage: obj.save_or_overwrite_slice(slc, slice_add_perm, slice_overwrite_perm, slice_download_perm, datasource_id, datasource_type, datasource_name, query_context) and returns: json_success, json_error_response, json_error_response