mirror of https://github.com/apache/superset.git
Moving appbuilder.xxx out of view files and into app.py (#8912)
* Moving appbuilder.xxx out of view files ands into app.py * Pulled url map converters out into their own file * Adding license blurb * Linting * Linting again...
This commit is contained in:
parent
28563ad088
commit
2a94150097
|
@ -34,7 +34,7 @@ EOF
|
|||
}
|
||||
|
||||
# Create an admin user
|
||||
echo_step "1" "Starting" "Setting up admin user"
|
||||
echo_step "1" "Starting" "Setting up admin user ( admin / admin )"
|
||||
superset fab create-admin \
|
||||
--username admin \
|
||||
--firstname Superset \
|
||||
|
|
332
superset/app.py
332
superset/app.py
|
@ -21,6 +21,7 @@ import os
|
|||
import wtforms_json
|
||||
from flask import Flask, redirect
|
||||
from flask_appbuilder import expose, IndexView
|
||||
from flask_babel import gettext as __, lazy_gettext as _
|
||||
from flask_compress import Compress
|
||||
from flask_wtf import CSRFProtect
|
||||
|
||||
|
@ -114,10 +115,321 @@ class SupersetAppInitializer:
|
|||
|
||||
celery_app.Task = AppContextTask
|
||||
|
||||
@staticmethod
|
||||
def init_views() -> None:
|
||||
# TODO - This should iterate over all views and register them with FAB...
|
||||
from superset import views # noqa pylint: disable=unused-variable
|
||||
def init_views(self) -> None:
|
||||
#
|
||||
# We're doing local imports, as several of them import
|
||||
# models which in turn try to import
|
||||
# the global Flask app
|
||||
#
|
||||
# pylint: disable=too-many-locals
|
||||
# pylint: disable=too-many-statements
|
||||
from superset.connectors.druid.views import (
|
||||
DruidDatasourceModelView,
|
||||
DruidClusterModelView,
|
||||
DruidMetricInlineView,
|
||||
DruidColumnInlineView,
|
||||
Druid,
|
||||
)
|
||||
from superset.connectors.sqla.views import (
|
||||
TableColumnInlineView,
|
||||
SqlMetricInlineView,
|
||||
TableModelView,
|
||||
)
|
||||
from superset.views.annotations import (
|
||||
AnnotationLayerModelView,
|
||||
AnnotationModelView,
|
||||
)
|
||||
from superset.views.api import Api
|
||||
from superset.views.core import (
|
||||
AccessRequestsModelView,
|
||||
SliceModelView,
|
||||
SliceAsync,
|
||||
SliceAddView,
|
||||
KV,
|
||||
R,
|
||||
Superset,
|
||||
CssTemplateModelView,
|
||||
CssTemplateAsyncModelView,
|
||||
)
|
||||
from superset.views.dashboard.api import DashboardRestApi
|
||||
from superset.views.dashboard.views import (
|
||||
DashboardModelView,
|
||||
Dashboard,
|
||||
DashboardAddView,
|
||||
DashboardModelViewAsync,
|
||||
)
|
||||
from superset.views.database.api import DatabaseRestApi
|
||||
from superset.views.database.views import (
|
||||
DatabaseView,
|
||||
DatabaseTablesAsync,
|
||||
CsvToDatabaseView,
|
||||
DatabaseAsync,
|
||||
)
|
||||
from superset.views.datasource import Datasource
|
||||
from superset.views.log.api import LogRestApi
|
||||
from superset.views.log.views import LogModelView
|
||||
from superset.views.schedules import (
|
||||
DashboardEmailScheduleView,
|
||||
SliceEmailScheduleView,
|
||||
)
|
||||
from superset.views.sql_lab import (
|
||||
QueryView,
|
||||
SavedQueryViewApi,
|
||||
SavedQueryView,
|
||||
TabStateView,
|
||||
TableSchemaView,
|
||||
SqlLab,
|
||||
)
|
||||
from superset.views.tags import TagView
|
||||
|
||||
#
|
||||
# Setup API views
|
||||
#
|
||||
appbuilder.add_api(DashboardRestApi)
|
||||
appbuilder.add_api(DatabaseRestApi)
|
||||
|
||||
#
|
||||
# Setup regular views
|
||||
#
|
||||
appbuilder.add_view(
|
||||
AnnotationLayerModelView,
|
||||
"Annotation Layers",
|
||||
label=__("Annotation Layers"),
|
||||
icon="fa-comment",
|
||||
category="Manage",
|
||||
category_label=__("Manage"),
|
||||
category_icon="",
|
||||
)
|
||||
appbuilder.add_view(
|
||||
AnnotationModelView,
|
||||
"Annotations",
|
||||
label=__("Annotations"),
|
||||
icon="fa-comments",
|
||||
category="Manage",
|
||||
category_label=__("Manage"),
|
||||
category_icon="",
|
||||
)
|
||||
appbuilder.add_view(
|
||||
SliceModelView,
|
||||
"Charts",
|
||||
label=__("Charts"),
|
||||
icon="fa-bar-chart",
|
||||
category="",
|
||||
category_icon="",
|
||||
)
|
||||
appbuilder.add_view(
|
||||
DatabaseView,
|
||||
"Databases",
|
||||
label=__("Databases"),
|
||||
icon="fa-database",
|
||||
category="Sources",
|
||||
category_label=__("Sources"),
|
||||
category_icon="fa-database",
|
||||
)
|
||||
appbuilder.add_view(
|
||||
DashboardModelView,
|
||||
"Dashboards",
|
||||
label=__("Dashboards"),
|
||||
icon="fa-dashboard",
|
||||
category="",
|
||||
category_icon="",
|
||||
)
|
||||
appbuilder.add_view(
|
||||
CssTemplateModelView,
|
||||
"CSS Templates",
|
||||
label=__("CSS Templates"),
|
||||
icon="fa-css3",
|
||||
category="Manage",
|
||||
category_label=__("Manage"),
|
||||
category_icon="",
|
||||
)
|
||||
appbuilder.add_view(
|
||||
QueryView,
|
||||
"Queries",
|
||||
label=__("Queries"),
|
||||
category="Manage",
|
||||
category_label=__("Manage"),
|
||||
icon="fa-search",
|
||||
)
|
||||
|
||||
#
|
||||
# Setup views with no menu
|
||||
#
|
||||
appbuilder.add_view_no_menu(Api)
|
||||
appbuilder.add_view_no_menu(CssTemplateAsyncModelView)
|
||||
appbuilder.add_view_no_menu(CsvToDatabaseView)
|
||||
appbuilder.add_view_no_menu(Dashboard)
|
||||
appbuilder.add_view_no_menu(DashboardAddView)
|
||||
appbuilder.add_view_no_menu(DashboardModelViewAsync)
|
||||
appbuilder.add_view_no_menu(DatabaseAsync)
|
||||
appbuilder.add_view_no_menu(DatabaseTablesAsync)
|
||||
appbuilder.add_view_no_menu(Datasource)
|
||||
appbuilder.add_view_no_menu(KV)
|
||||
appbuilder.add_view_no_menu(R)
|
||||
appbuilder.add_view_no_menu(SavedQueryView)
|
||||
appbuilder.add_view_no_menu(SavedQueryViewApi)
|
||||
appbuilder.add_view_no_menu(SliceAddView)
|
||||
appbuilder.add_view_no_menu(SliceAsync)
|
||||
appbuilder.add_view_no_menu(SqlLab)
|
||||
appbuilder.add_view_no_menu(SqlMetricInlineView)
|
||||
appbuilder.add_view_no_menu(Superset)
|
||||
appbuilder.add_view_no_menu(TableColumnInlineView)
|
||||
appbuilder.add_view_no_menu(TableModelView)
|
||||
appbuilder.add_view_no_menu(TableSchemaView)
|
||||
appbuilder.add_view_no_menu(TabStateView)
|
||||
appbuilder.add_view_no_menu(TagView)
|
||||
|
||||
#
|
||||
# Add links
|
||||
#
|
||||
appbuilder.add_link(
|
||||
__("Saved Queries"),
|
||||
href="/sqllab/my_queries/",
|
||||
icon="fa-save",
|
||||
category="SQL Lab",
|
||||
)
|
||||
appbuilder.add_link(
|
||||
"Import Dashboards",
|
||||
label=__("Import Dashboards"),
|
||||
href="/superset/import_dashboards",
|
||||
icon="fa-cloud-upload",
|
||||
category="Manage",
|
||||
category_label=__("Manage"),
|
||||
category_icon="fa-wrench",
|
||||
)
|
||||
appbuilder.add_link(
|
||||
"SQL Editor",
|
||||
label=_("SQL Editor"),
|
||||
href="/superset/sqllab",
|
||||
category_icon="fa-flask",
|
||||
icon="fa-flask",
|
||||
category="SQL Lab",
|
||||
category_label=__("SQL Lab"),
|
||||
)
|
||||
appbuilder.add_link(
|
||||
"Query Search",
|
||||
label=_("Query Search"),
|
||||
href="/superset/sqllab#search",
|
||||
icon="fa-search",
|
||||
category_icon="fa-flask",
|
||||
category="SQL Lab",
|
||||
category_label=__("SQL Lab"),
|
||||
)
|
||||
appbuilder.add_link(
|
||||
"Upload a CSV",
|
||||
label=__("Upload a CSV"),
|
||||
href="/csvtodatabaseview/form",
|
||||
icon="fa-upload",
|
||||
category="Sources",
|
||||
category_label=__("Sources"),
|
||||
category_icon="fa-wrench",
|
||||
)
|
||||
appbuilder.add_link(
|
||||
"Tables",
|
||||
label=__("Tables"),
|
||||
href="/tablemodelview/list/?_flt_1_is_sqllab_view=y",
|
||||
icon="fa-table",
|
||||
category="Sources",
|
||||
category_label=__("Sources"),
|
||||
category_icon="fa-table",
|
||||
)
|
||||
|
||||
#
|
||||
# Conditionally setup log views
|
||||
#
|
||||
if (
|
||||
not self.config["FAB_ADD_SECURITY_VIEWS"] is False
|
||||
or self.config["SUPERSET_LOG_VIEW"] is False
|
||||
):
|
||||
appbuilder.add_api(LogRestApi)
|
||||
appbuilder.add_view(
|
||||
LogModelView,
|
||||
"Action Log",
|
||||
label=__("Action Log"),
|
||||
category="Security",
|
||||
category_label=__("Security"),
|
||||
icon="fa-list-ol",
|
||||
)
|
||||
|
||||
#
|
||||
# Conditionally setup email views
|
||||
#
|
||||
if self.config["ENABLE_SCHEDULED_EMAIL_REPORTS"]:
|
||||
appbuilder.add_separator("Manage")
|
||||
appbuilder.add_view(
|
||||
DashboardEmailScheduleView,
|
||||
"Dashboard Email Schedules",
|
||||
label=__("Dashboard Emails"),
|
||||
category="Manage",
|
||||
category_label=__("Manage"),
|
||||
icon="fa-search",
|
||||
)
|
||||
appbuilder.add_view(
|
||||
SliceEmailScheduleView,
|
||||
"Chart Emails",
|
||||
label=__("Chart Email Schedules"),
|
||||
category="Manage",
|
||||
category_label=__("Manage"),
|
||||
icon="fa-search",
|
||||
)
|
||||
|
||||
#
|
||||
# Conditionally add Access Request Model View
|
||||
#
|
||||
if self.config["ENABLE_ACCESS_REQUEST"]:
|
||||
appbuilder.add_view(
|
||||
AccessRequestsModelView,
|
||||
"Access requests",
|
||||
label=__("Access requests"),
|
||||
category="Security",
|
||||
category_label=__("Security"),
|
||||
icon="fa-table",
|
||||
)
|
||||
|
||||
#
|
||||
# Conditionally setup Druid Views
|
||||
#
|
||||
if self.config["DRUID_IS_ACTIVE"]:
|
||||
appbuilder.add_separator("Sources")
|
||||
appbuilder.add_view(
|
||||
DruidDatasourceModelView,
|
||||
"Druid Datasources",
|
||||
label=__("Druid Datasources"),
|
||||
category="Sources",
|
||||
category_label=__("Sources"),
|
||||
icon="fa-cube",
|
||||
)
|
||||
appbuilder.add_view(
|
||||
DruidClusterModelView,
|
||||
name="Druid Clusters",
|
||||
label=__("Druid Clusters"),
|
||||
icon="fa-cubes",
|
||||
category="Sources",
|
||||
category_label=__("Sources"),
|
||||
category_icon="fa-database",
|
||||
)
|
||||
appbuilder.add_view_no_menu(DruidMetricInlineView)
|
||||
appbuilder.add_view_no_menu(DruidColumnInlineView)
|
||||
appbuilder.add_view_no_menu(Druid)
|
||||
appbuilder.add_link(
|
||||
"Scan New Datasources",
|
||||
label=__("Scan New Datasources"),
|
||||
href="/druid/scan_new_datasources/",
|
||||
category="Sources",
|
||||
category_label=__("Sources"),
|
||||
category_icon="fa-database",
|
||||
icon="fa-refresh",
|
||||
)
|
||||
appbuilder.add_link(
|
||||
"Refresh Druid Metadata",
|
||||
label=__("Refresh Druid Metadata"),
|
||||
href="/druid/refresh_datasources/",
|
||||
category="Sources",
|
||||
category_label=__("Sources"),
|
||||
category_icon="fa-database",
|
||||
icon="fa-cog",
|
||||
)
|
||||
appbuilder.add_separator("Sources")
|
||||
|
||||
def init_app_in_ctx(self) -> None:
|
||||
"""
|
||||
|
@ -125,6 +437,7 @@ class SupersetAppInitializer:
|
|||
"""
|
||||
self.configure_feature_flags()
|
||||
self.configure_fab()
|
||||
self.configure_url_map_converters()
|
||||
self.configure_data_sources()
|
||||
|
||||
# Hook that provides administrators a handle on the Flask APP
|
||||
|
@ -203,6 +516,17 @@ class SupersetAppInitializer:
|
|||
appbuilder.update_perms = False
|
||||
appbuilder.init_app(self.flask_app, db.session)
|
||||
|
||||
def configure_url_map_converters(self):
|
||||
#
|
||||
# Doing local imports here as model importing causes a reference to
|
||||
# app.config to be invoked and we need the current_app to have been setup
|
||||
#
|
||||
from superset.utils.url_map_converters import RegexConverter
|
||||
from superset.utils.url_map_converters import ObjectTypeConverter
|
||||
|
||||
self.flask_app.url_map.converters["regex"] = RegexConverter
|
||||
self.flask_app.url_map.converters["object_type"] = ObjectTypeConverter
|
||||
|
||||
def configure_jinja_context(self):
|
||||
jinja_context_manager.init_app(self.flask_app)
|
||||
|
||||
|
|
|
@ -406,54 +406,3 @@ class Druid(BaseSupersetView):
|
|||
datasources only and add them.
|
||||
"""
|
||||
return self.refresh_datasources(refresh_all=False)
|
||||
|
||||
|
||||
if app.config["DRUID_IS_ACTIVE"]:
|
||||
|
||||
appbuilder.add_separator("Sources")
|
||||
|
||||
appbuilder.add_view(
|
||||
DruidDatasourceModelView,
|
||||
"Druid Datasources",
|
||||
label=__("Druid Datasources"),
|
||||
category="Sources",
|
||||
category_label=__("Sources"),
|
||||
icon="fa-cube",
|
||||
)
|
||||
|
||||
appbuilder.add_view(
|
||||
DruidClusterModelView,
|
||||
name="Druid Clusters",
|
||||
label=__("Druid Clusters"),
|
||||
icon="fa-cubes",
|
||||
category="Sources",
|
||||
category_label=__("Sources"),
|
||||
category_icon="fa-database",
|
||||
)
|
||||
|
||||
appbuilder.add_view_no_menu(DruidMetricInlineView)
|
||||
|
||||
appbuilder.add_view_no_menu(DruidColumnInlineView)
|
||||
|
||||
appbuilder.add_view_no_menu(Druid)
|
||||
|
||||
appbuilder.add_link(
|
||||
"Scan New Datasources",
|
||||
label=__("Scan New Datasources"),
|
||||
href="/druid/scan_new_datasources/",
|
||||
category="Sources",
|
||||
category_label=__("Sources"),
|
||||
category_icon="fa-database",
|
||||
icon="fa-refresh",
|
||||
)
|
||||
appbuilder.add_link(
|
||||
"Refresh Druid Metadata",
|
||||
label=__("Refresh Druid Metadata"),
|
||||
href="/druid/refresh_datasources/",
|
||||
category="Sources",
|
||||
category_label=__("Sources"),
|
||||
category_icon="fa-database",
|
||||
icon="fa-cog",
|
||||
)
|
||||
|
||||
appbuilder.add_separator("Sources")
|
||||
|
|
|
@ -162,9 +162,6 @@ class TableColumnInlineView(CompactCRUDMixin, SupersetModelView):
|
|||
edit_form_extra_fields = add_form_extra_fields
|
||||
|
||||
|
||||
appbuilder.add_view_no_menu(TableColumnInlineView)
|
||||
|
||||
|
||||
class SqlMetricInlineView(CompactCRUDMixin, SupersetModelView):
|
||||
datamodel = SQLAInterface(models.SqlMetric)
|
||||
|
||||
|
@ -224,9 +221,6 @@ class SqlMetricInlineView(CompactCRUDMixin, SupersetModelView):
|
|||
edit_form_extra_fields = add_form_extra_fields
|
||||
|
||||
|
||||
appbuilder.add_view_no_menu(SqlMetricInlineView)
|
||||
|
||||
|
||||
class TableModelView(DatasourceModelView, DeleteMixin, YamlExportMixin):
|
||||
datamodel = SQLAInterface(models.SqlaTable)
|
||||
|
||||
|
@ -426,15 +420,3 @@ class TableModelView(DatasourceModelView, DeleteMixin, YamlExportMixin):
|
|||
flash(failure_msg, "danger")
|
||||
|
||||
return redirect("/tablemodelview/list/")
|
||||
|
||||
|
||||
appbuilder.add_view_no_menu(TableModelView)
|
||||
appbuilder.add_link(
|
||||
"Tables",
|
||||
label=__("Tables"),
|
||||
href="/tablemodelview/list/?_flt_1_is_sqllab_view=y",
|
||||
icon="fa-table",
|
||||
category="Sources",
|
||||
category_label=__("Sources"),
|
||||
category_icon="fa-table",
|
||||
)
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
# Licensed to the Apache Software Foundation (ASF) under one
|
||||
# or more contributor license agreements. See the NOTICE file
|
||||
# distributed with this work for additional information
|
||||
# regarding copyright ownership. The ASF licenses this file
|
||||
# to you under the Apache License, Version 2.0 (the
|
||||
# "License"); you may not use this file except in compliance
|
||||
# with the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing,
|
||||
# software distributed under the License is distributed on an
|
||||
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
# KIND, either express or implied. See the License for the
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
from werkzeug.routing import BaseConverter
|
||||
|
||||
from superset.models.tags import ObjectTypes
|
||||
|
||||
|
||||
class RegexConverter(BaseConverter):
|
||||
def __init__(self, url_map, *items):
|
||||
super(RegexConverter, self).__init__(url_map)
|
||||
self.regex = items[0]
|
||||
|
||||
|
||||
class ObjectTypeConverter(BaseConverter):
|
||||
"""Validate that object_type is indeed an object type."""
|
||||
|
||||
def to_python(self, value):
|
||||
return ObjectTypes[value]
|
||||
|
||||
def to_url(self, value):
|
||||
return value.name
|
|
@ -15,10 +15,9 @@
|
|||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
from flask_appbuilder.models.sqla.interface import SQLAInterface
|
||||
from flask_babel import gettext as __, lazy_gettext as _
|
||||
from flask_babel import lazy_gettext as _
|
||||
from wtforms.validators import StopValidation
|
||||
|
||||
from superset import appbuilder
|
||||
from superset.models.annotations import Annotation, AnnotationLayer
|
||||
|
||||
from .base import DeleteMixin, SupersetModelView
|
||||
|
@ -105,23 +104,3 @@ class AnnotationLayerModelView(
|
|||
add_columns = edit_columns
|
||||
|
||||
label_columns = {"name": _("Name"), "descr": _("Description")}
|
||||
|
||||
|
||||
appbuilder.add_view(
|
||||
AnnotationLayerModelView,
|
||||
"Annotation Layers",
|
||||
label=__("Annotation Layers"),
|
||||
icon="fa-comment",
|
||||
category="Manage",
|
||||
category_label=__("Manage"),
|
||||
category_icon="",
|
||||
)
|
||||
appbuilder.add_view(
|
||||
AnnotationModelView,
|
||||
"Annotations",
|
||||
label=__("Annotations"),
|
||||
icon="fa-comments",
|
||||
category="Manage",
|
||||
category_label=__("Manage"),
|
||||
category_icon="",
|
||||
)
|
||||
|
|
|
@ -20,7 +20,7 @@ from flask import request
|
|||
from flask_appbuilder import expose
|
||||
from flask_appbuilder.security.decorators import has_access_api
|
||||
|
||||
from superset import appbuilder, db, event_logger, security_manager
|
||||
from superset import db, event_logger, security_manager
|
||||
from superset.common.query_context import QueryContext
|
||||
from superset.legacy import update_time_range
|
||||
from superset.models.slice import Slice
|
||||
|
@ -70,6 +70,3 @@ class Api(BaseSupersetView):
|
|||
update_time_range(form_data)
|
||||
|
||||
return json.dumps(form_data)
|
||||
|
||||
|
||||
appbuilder.add_view_no_menu(Api)
|
||||
|
|
|
@ -106,9 +106,7 @@ from .base import (
|
|||
json_success,
|
||||
SupersetModelView,
|
||||
)
|
||||
from .dashboard import views as dash_views
|
||||
from .dashboard.filters import DashboardFilter
|
||||
from .database import views as in_views
|
||||
from .utils import (
|
||||
apply_display_max_row_limit,
|
||||
bootstrap_user_data,
|
||||
|
@ -260,36 +258,25 @@ class SliceFilter(BaseFilter):
|
|||
)
|
||||
|
||||
|
||||
if config["ENABLE_ACCESS_REQUEST"]:
|
||||
|
||||
class AccessRequestsModelView(SupersetModelView, DeleteMixin):
|
||||
datamodel = SQLAInterface(DAR)
|
||||
list_columns = [
|
||||
"username",
|
||||
"user_roles",
|
||||
"datasource_link",
|
||||
"roles_with_datasource",
|
||||
"created_on",
|
||||
]
|
||||
order_columns = ["created_on"]
|
||||
base_order = ("changed_on", "desc")
|
||||
label_columns = {
|
||||
"username": _("User"),
|
||||
"user_roles": _("User Roles"),
|
||||
"database": _("Database URL"),
|
||||
"datasource_link": _("Datasource"),
|
||||
"roles_with_datasource": _("Roles to grant"),
|
||||
"created_on": _("Created On"),
|
||||
}
|
||||
|
||||
appbuilder.add_view(
|
||||
AccessRequestsModelView,
|
||||
"Access requests",
|
||||
label=__("Access requests"),
|
||||
category="Security",
|
||||
category_label=__("Security"),
|
||||
icon="fa-table",
|
||||
)
|
||||
class AccessRequestsModelView(SupersetModelView, DeleteMixin):
|
||||
datamodel = SQLAInterface(DAR)
|
||||
list_columns = [
|
||||
"username",
|
||||
"user_roles",
|
||||
"datasource_link",
|
||||
"roles_with_datasource",
|
||||
"created_on",
|
||||
]
|
||||
order_columns = ["created_on"]
|
||||
base_order = ("changed_on", "desc")
|
||||
label_columns = {
|
||||
"username": _("User"),
|
||||
"user_roles": _("User Roles"),
|
||||
"database": _("Database URL"),
|
||||
"datasource_link": _("Datasource"),
|
||||
"roles_with_datasource": _("Roles to grant"),
|
||||
"created_on": _("Created On"),
|
||||
}
|
||||
|
||||
|
||||
class SliceModelView(SupersetModelView, DeleteMixin):
|
||||
|
@ -384,16 +371,6 @@ class SliceModelView(SupersetModelView, DeleteMixin):
|
|||
)
|
||||
|
||||
|
||||
appbuilder.add_view(
|
||||
SliceModelView,
|
||||
"Charts",
|
||||
label=__("Charts"),
|
||||
icon="fa-bar-chart",
|
||||
category="",
|
||||
category_icon="",
|
||||
)
|
||||
|
||||
|
||||
class SliceAsync(SliceModelView):
|
||||
route_base = "/sliceasync"
|
||||
list_columns = [
|
||||
|
@ -409,9 +386,6 @@ class SliceAsync(SliceModelView):
|
|||
label_columns = {"icons": " ", "slice_link": _("Chart")}
|
||||
|
||||
|
||||
appbuilder.add_view_no_menu(SliceAsync)
|
||||
|
||||
|
||||
class SliceAddView(SliceModelView):
|
||||
route_base = "/sliceaddview"
|
||||
list_columns = [
|
||||
|
@ -434,19 +408,6 @@ class SliceAddView(SliceModelView):
|
|||
]
|
||||
|
||||
|
||||
appbuilder.add_view_no_menu(SliceAddView)
|
||||
|
||||
|
||||
appbuilder.add_view(
|
||||
dash_views.DashboardModelView,
|
||||
"Dashboards",
|
||||
label=__("Dashboards"),
|
||||
icon="fa-dashboard",
|
||||
category="",
|
||||
category_icon="",
|
||||
)
|
||||
|
||||
|
||||
@talisman(force_https=False)
|
||||
@app.route("/health")
|
||||
def health():
|
||||
|
@ -495,9 +456,6 @@ class KV(BaseSupersetView):
|
|||
return Response(kv.value, status=200, content_type="text/plain")
|
||||
|
||||
|
||||
appbuilder.add_view_no_menu(KV)
|
||||
|
||||
|
||||
class R(BaseSupersetView):
|
||||
|
||||
"""used for short urls"""
|
||||
|
@ -533,9 +491,6 @@ class R(BaseSupersetView):
|
|||
)
|
||||
|
||||
|
||||
appbuilder.add_view_no_menu(R)
|
||||
|
||||
|
||||
class Superset(BaseSupersetView):
|
||||
"""The base views for Superset!"""
|
||||
|
||||
|
@ -2997,9 +2952,6 @@ class Superset(BaseSupersetView):
|
|||
)
|
||||
|
||||
|
||||
appbuilder.add_view_no_menu(Superset)
|
||||
|
||||
|
||||
class CssTemplateModelView(SupersetModelView, DeleteMixin):
|
||||
datamodel = SQLAInterface(models.CssTemplate)
|
||||
|
||||
|
@ -3018,50 +2970,6 @@ class CssTemplateAsyncModelView(CssTemplateModelView):
|
|||
list_columns = ["template_name", "css"]
|
||||
|
||||
|
||||
appbuilder.add_view(
|
||||
CssTemplateModelView,
|
||||
"CSS Templates",
|
||||
label=__("CSS Templates"),
|
||||
icon="fa-css3",
|
||||
category="Manage",
|
||||
category_label=__("Manage"),
|
||||
category_icon="",
|
||||
)
|
||||
|
||||
|
||||
appbuilder.add_view_no_menu(CssTemplateAsyncModelView)
|
||||
|
||||
appbuilder.add_link(
|
||||
"SQL Editor",
|
||||
label=_("SQL Editor"),
|
||||
href="/superset/sqllab",
|
||||
category_icon="fa-flask",
|
||||
icon="fa-flask",
|
||||
category="SQL Lab",
|
||||
category_label=__("SQL Lab"),
|
||||
)
|
||||
|
||||
appbuilder.add_link(
|
||||
"Query Search",
|
||||
label=_("Query Search"),
|
||||
href="/superset/sqllab#search",
|
||||
icon="fa-search",
|
||||
category_icon="fa-flask",
|
||||
category="SQL Lab",
|
||||
category_label=__("SQL Lab"),
|
||||
)
|
||||
|
||||
appbuilder.add_link(
|
||||
"Upload a CSV",
|
||||
label=__("Upload a CSV"),
|
||||
href="/csvtodatabaseview/form",
|
||||
icon="fa-upload",
|
||||
category="Sources",
|
||||
category_label=__("Sources"),
|
||||
category_icon="fa-wrench",
|
||||
)
|
||||
|
||||
|
||||
@app.after_request
|
||||
def apply_http_headers(response: Response):
|
||||
"""Applies the configuration's http headers to all responses"""
|
||||
|
@ -3077,17 +2985,6 @@ def apply_http_headers(response: Response):
|
|||
return response
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------
|
||||
# Redirecting URL from previous names
|
||||
class RegexConverter(BaseConverter):
|
||||
def __init__(self, url_map, *items):
|
||||
super(RegexConverter, self).__init__(url_map)
|
||||
self.regex = items[0]
|
||||
|
||||
|
||||
app.url_map.converters["regex"] = RegexConverter
|
||||
|
||||
|
||||
@app.route('/<regex("panoramix\/.*"):url>')
|
||||
def panoramix(url):
|
||||
return redirect(request.full_path.replace("panoramix", "superset"))
|
||||
|
|
|
@ -24,7 +24,6 @@ from marshmallow import fields, post_load, pre_load, Schema, ValidationError
|
|||
from marshmallow.validate import Length
|
||||
from sqlalchemy.exc import SQLAlchemyError
|
||||
|
||||
from superset import appbuilder
|
||||
from superset.exceptions import SupersetException
|
||||
from superset.models.dashboard import Dashboard
|
||||
from superset.utils import core as utils
|
||||
|
@ -357,6 +356,3 @@ class DashboardRestApi(DashboardMixin, BaseSupersetModelRestApi):
|
|||
return self.response(200, message="OK")
|
||||
except SQLAlchemyError as e:
|
||||
return self.response_422(message=str(e))
|
||||
|
||||
|
||||
appbuilder.add_api(DashboardRestApi)
|
||||
|
|
|
@ -24,7 +24,7 @@ from flask_appbuilder.security.decorators import has_access
|
|||
from flask_babel import gettext as __, lazy_gettext as _
|
||||
|
||||
import superset.models.core as models
|
||||
from superset import appbuilder, db, event_logger
|
||||
from superset import db, event_logger
|
||||
from superset.utils import core as utils
|
||||
|
||||
from ..base import (
|
||||
|
@ -100,9 +100,6 @@ class Dashboard(BaseSupersetView):
|
|||
return redirect(f"/superset/dashboard/{new_dashboard.id}/?edit=true")
|
||||
|
||||
|
||||
appbuilder.add_view_no_menu(Dashboard)
|
||||
|
||||
|
||||
class DashboardModelViewAsync(DashboardModelView): # pylint: disable=too-many-ancestors
|
||||
route_base = "/dashboardasync"
|
||||
list_columns = [
|
||||
|
@ -123,9 +120,6 @@ class DashboardModelViewAsync(DashboardModelView): # pylint: disable=too-many-a
|
|||
}
|
||||
|
||||
|
||||
appbuilder.add_view_no_menu(DashboardModelViewAsync)
|
||||
|
||||
|
||||
class DashboardAddView(DashboardModelView): # pylint: disable=too-many-ancestors
|
||||
route_base = "/dashboardaddview"
|
||||
list_columns = [
|
||||
|
@ -139,6 +133,3 @@ class DashboardAddView(DashboardModelView): # pylint: disable=too-many-ancestor
|
|||
"changed_by_name",
|
||||
]
|
||||
show_columns = list(set(DashboardModelView.edit_columns + list_columns))
|
||||
|
||||
|
||||
appbuilder.add_view_no_menu(DashboardAddView)
|
||||
|
|
|
@ -18,7 +18,6 @@ from flask_appbuilder import ModelRestApi
|
|||
from flask_appbuilder.models.sqla.interface import SQLAInterface
|
||||
|
||||
import superset.models.core as models
|
||||
from superset import appbuilder
|
||||
|
||||
from .mixins import DatabaseFilter, DatabaseMixin
|
||||
from .validators import sqlalchemy_uri_validator
|
||||
|
@ -58,6 +57,3 @@ class DatabaseRestApi(DatabaseMixin, ModelRestApi):
|
|||
# Removes the local limit for the page size
|
||||
max_page_size = -1
|
||||
validators_columns = {"sqlalchemy_uri": sqlalchemy_uri_validator}
|
||||
|
||||
|
||||
appbuilder.add_api(DatabaseRestApi)
|
||||
|
|
|
@ -19,13 +19,13 @@ import os
|
|||
from flask import flash, g, redirect
|
||||
from flask_appbuilder import SimpleFormView
|
||||
from flask_appbuilder.models.sqla.interface import SQLAInterface
|
||||
from flask_babel import gettext as __, lazy_gettext as _
|
||||
from flask_babel import lazy_gettext as _
|
||||
from werkzeug.utils import secure_filename
|
||||
from wtforms.fields import StringField
|
||||
from wtforms.validators import ValidationError
|
||||
|
||||
import superset.models.core as models
|
||||
from superset import app, appbuilder, db
|
||||
from superset import app, db
|
||||
from superset.connectors.sqla.models import SqlaTable
|
||||
from superset.utils import core as utils
|
||||
from superset.views.base import DeleteMixin, SupersetModelView, YamlExportMixin
|
||||
|
@ -60,28 +60,6 @@ class DatabaseView(
|
|||
DeleteMixin._delete(self, pk)
|
||||
|
||||
|
||||
appbuilder.add_link(
|
||||
"Import Dashboards",
|
||||
label=__("Import Dashboards"),
|
||||
href="/superset/import_dashboards",
|
||||
icon="fa-cloud-upload",
|
||||
category="Manage",
|
||||
category_label=__("Manage"),
|
||||
category_icon="fa-wrench",
|
||||
)
|
||||
|
||||
|
||||
appbuilder.add_view(
|
||||
DatabaseView,
|
||||
"Databases",
|
||||
label=__("Databases"),
|
||||
icon="fa-database",
|
||||
category="Sources",
|
||||
category_label=__("Sources"),
|
||||
category_icon="fa-database",
|
||||
)
|
||||
|
||||
|
||||
class CsvToDatabaseView(SimpleFormView):
|
||||
form = CsvToDatabaseForm
|
||||
form_template = "superset/form_view/csv_to_database_view/edit.html"
|
||||
|
@ -181,16 +159,10 @@ class CsvToDatabaseView(SimpleFormView):
|
|||
return redirect("/tablemodelview/list/")
|
||||
|
||||
|
||||
appbuilder.add_view_no_menu(CsvToDatabaseView)
|
||||
|
||||
|
||||
class DatabaseTablesAsync(DatabaseView): # pylint: disable=too-many-ancestors
|
||||
list_columns = ["id", "all_table_names_in_database", "all_schema_names"]
|
||||
|
||||
|
||||
appbuilder.add_view_no_menu(DatabaseTablesAsync)
|
||||
|
||||
|
||||
class DatabaseAsync(DatabaseView): # pylint: disable=too-many-ancestors
|
||||
list_columns = [
|
||||
"id",
|
||||
|
@ -205,6 +177,3 @@ class DatabaseAsync(DatabaseView): # pylint: disable=too-many-ancestors
|
|||
"allows_subquery",
|
||||
"backend",
|
||||
]
|
||||
|
||||
|
||||
appbuilder.add_view_no_menu(DatabaseAsync)
|
||||
|
|
|
@ -22,7 +22,7 @@ from flask_appbuilder import expose
|
|||
from flask_appbuilder.security.decorators import has_access_api
|
||||
from sqlalchemy.orm.exc import NoResultFound
|
||||
|
||||
from superset import appbuilder, db
|
||||
from superset import db
|
||||
from superset.connectors.connector_registry import ConnectorRegistry
|
||||
from superset.models.core import Database
|
||||
|
||||
|
@ -114,6 +114,3 @@ class Datasource(BaseSupersetView):
|
|||
raise Exception(f"Unsupported datasource_type: {datasource_type}")
|
||||
external_metadata = datasource.external_metadata()
|
||||
return self.json_response(external_metadata)
|
||||
|
||||
|
||||
appbuilder.add_view_no_menu(Datasource)
|
||||
|
|
|
@ -18,7 +18,6 @@ from flask_appbuilder import ModelRestApi
|
|||
from flask_appbuilder.models.sqla.interface import SQLAInterface
|
||||
|
||||
import superset.models.core as models
|
||||
from superset import app, appbuilder
|
||||
|
||||
from . import LogMixin
|
||||
|
||||
|
@ -39,10 +38,3 @@ class LogRestApi(LogMixin, ModelRestApi):
|
|||
allow_browser_login = True
|
||||
list_columns = ("user.username", "action", "dttm")
|
||||
show_columns = list_columns
|
||||
|
||||
|
||||
if (
|
||||
not app.config["FAB_ADD_SECURITY_VIEWS"] is False
|
||||
or app.config["SUPERSET_LOG_VIEW"] is False
|
||||
):
|
||||
appbuilder.add_api(LogRestApi)
|
||||
|
|
|
@ -15,10 +15,8 @@
|
|||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
from flask_appbuilder.models.sqla.interface import SQLAInterface
|
||||
from flask_babel import gettext as __
|
||||
|
||||
import superset.models.core as models
|
||||
from superset import app, appbuilder
|
||||
from superset.views.base import SupersetModelView
|
||||
|
||||
from . import LogMixin
|
||||
|
@ -26,17 +24,3 @@ from . import LogMixin
|
|||
|
||||
class LogModelView(LogMixin, SupersetModelView): # pylint: disable=too-many-ancestors
|
||||
datamodel = SQLAInterface(models.Log)
|
||||
|
||||
|
||||
if (
|
||||
not app.config["FAB_ADD_SECURITY_VIEWS"] is False
|
||||
or app.config["SUPERSET_LOG_VIEW"] is False
|
||||
):
|
||||
appbuilder.add_view(
|
||||
LogModelView,
|
||||
"Action Log",
|
||||
label=__("Action Log"),
|
||||
category="Security",
|
||||
category_label=__("Security"),
|
||||
icon="fa-list-ol",
|
||||
)
|
||||
|
|
|
@ -23,10 +23,10 @@ from flask import flash, g
|
|||
from flask_appbuilder import expose
|
||||
from flask_appbuilder.models.sqla.interface import SQLAInterface
|
||||
from flask_appbuilder.security.decorators import has_access
|
||||
from flask_babel import gettext as __, lazy_gettext as _
|
||||
from flask_babel import lazy_gettext as _
|
||||
from wtforms import BooleanField, StringField
|
||||
|
||||
from superset import app, appbuilder, db, security_manager
|
||||
from superset import db, security_manager
|
||||
from superset.exceptions import SupersetException
|
||||
from superset.models.dashboard import Dashboard
|
||||
from superset.models.schedules import (
|
||||
|
@ -271,29 +271,3 @@ class SliceEmailScheduleView(EmailScheduleView): # pylint: disable=too-many-anc
|
|||
if item.slice is None:
|
||||
raise SupersetException("Slice is mandatory")
|
||||
super(SliceEmailScheduleView, self).pre_add(item)
|
||||
|
||||
|
||||
def _register_schedule_menus():
|
||||
appbuilder.add_separator("Manage")
|
||||
|
||||
appbuilder.add_view(
|
||||
DashboardEmailScheduleView,
|
||||
"Dashboard Email Schedules",
|
||||
label=__("Dashboard Emails"),
|
||||
category="Manage",
|
||||
category_label=__("Manage"),
|
||||
icon="fa-search",
|
||||
)
|
||||
|
||||
appbuilder.add_view(
|
||||
SliceEmailScheduleView,
|
||||
"Chart Emails",
|
||||
label=__("Chart Email Schedules"),
|
||||
category="Manage",
|
||||
category_label=__("Manage"),
|
||||
icon="fa-search",
|
||||
)
|
||||
|
||||
|
||||
if app.config["ENABLE_SCHEDULED_EMAIL_REPORTS"]:
|
||||
_register_schedule_menus()
|
||||
|
|
|
@ -21,10 +21,10 @@ from flask import g, redirect, request, Response
|
|||
from flask_appbuilder import expose
|
||||
from flask_appbuilder.models.sqla.interface import SQLAInterface
|
||||
from flask_appbuilder.security.decorators import has_access, has_access_api
|
||||
from flask_babel import gettext as __, lazy_gettext as _
|
||||
from flask_babel import lazy_gettext as _
|
||||
from flask_sqlalchemy import BaseQuery
|
||||
|
||||
from superset import appbuilder, db, get_feature_flags, security_manager
|
||||
from superset import db, get_feature_flags, security_manager
|
||||
from superset.models.sql_lab import Query, SavedQuery, TableSchema, TabState
|
||||
from superset.utils import core as utils
|
||||
|
||||
|
@ -71,16 +71,6 @@ class QueryView(SupersetModelView):
|
|||
}
|
||||
|
||||
|
||||
appbuilder.add_view(
|
||||
QueryView,
|
||||
"Queries",
|
||||
label=__("Queries"),
|
||||
category="Manage",
|
||||
category_label=__("Manage"),
|
||||
icon="fa-search",
|
||||
)
|
||||
|
||||
|
||||
class SavedQueryView(
|
||||
SupersetModelView, DeleteMixin
|
||||
): # pylint: disable=too-many-ancestors
|
||||
|
@ -173,10 +163,6 @@ class SavedQueryViewApi(SavedQueryView): # pylint: disable=too-many-ancestors
|
|||
return super().show(pk)
|
||||
|
||||
|
||||
appbuilder.add_view_no_menu(SavedQueryViewApi)
|
||||
appbuilder.add_view_no_menu(SavedQueryView)
|
||||
|
||||
|
||||
def _get_owner_id(tab_state_id):
|
||||
return db.session.query(TabState.user_id).filter_by(id=tab_state_id).scalar()
|
||||
|
||||
|
@ -332,15 +318,6 @@ class TableSchemaView(BaseSupersetView):
|
|||
return json_success(response)
|
||||
|
||||
|
||||
appbuilder.add_view_no_menu(TabStateView)
|
||||
appbuilder.add_view_no_menu(TableSchemaView)
|
||||
|
||||
|
||||
appbuilder.add_link(
|
||||
__("Saved Queries"), href="/sqllab/my_queries/", icon="fa-save", category="SQL Lab"
|
||||
)
|
||||
|
||||
|
||||
class SqlLab(BaseSupersetView):
|
||||
"""The base views for Superset!"""
|
||||
|
||||
|
@ -349,6 +326,3 @@ class SqlLab(BaseSupersetView):
|
|||
def my_queries(self): # pylint: disable=no-self-use
|
||||
"""Assigns a list of found users to the given role."""
|
||||
return redirect("/savedqueryview/list/?_flt_0_user={}".format(g.user.id))
|
||||
|
||||
|
||||
appbuilder.add_view_no_menu(SqlLab)
|
||||
|
|
|
@ -22,9 +22,8 @@ from flask_appbuilder import expose
|
|||
from flask_appbuilder.security.decorators import has_access_api
|
||||
from jinja2.sandbox import SandboxedEnvironment
|
||||
from sqlalchemy import and_, func
|
||||
from werkzeug.routing import BaseConverter
|
||||
|
||||
from superset import app, appbuilder, db, utils
|
||||
from superset import db, utils
|
||||
from superset.jinja_context import current_user_id, current_username
|
||||
from superset.models.dashboard import Dashboard
|
||||
from superset.models.slice import Slice
|
||||
|
@ -34,17 +33,6 @@ from superset.models.tags import ObjectTypes, Tag, TaggedObject, TagTypes
|
|||
from .base import BaseSupersetView, json_success
|
||||
|
||||
|
||||
class ObjectTypeConverter(BaseConverter):
|
||||
|
||||
"""Validate that object_type is indeed an object type."""
|
||||
|
||||
def to_python(self, value):
|
||||
return ObjectTypes[value]
|
||||
|
||||
def to_url(self, value):
|
||||
return value.name
|
||||
|
||||
|
||||
def process_template(content):
|
||||
env = SandboxedEnvironment()
|
||||
template = env.from_string(content)
|
||||
|
@ -228,7 +216,3 @@ class TagView(BaseSupersetView):
|
|||
)
|
||||
|
||||
return json_success(json.dumps(results, default=utils.core.json_int_dttm_ser))
|
||||
|
||||
|
||||
app.url_map.converters["object_type"] = ObjectTypeConverter
|
||||
appbuilder.add_view_no_menu(TagView)
|
||||
|
|
Loading…
Reference in New Issue