123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209 |
- # pylint: disable=C,R,W
- """Package's main module!"""
- import json
- import logging
- from logging.handlers import TimedRotatingFileHandler
- import os
- from flask import Flask, redirect
- from flask_appbuilder import AppBuilder, IndexView, SQLA
- from flask_appbuilder.baseviews import expose
- from flask_compress import Compress
- from flask_migrate import Migrate
- from flask_wtf.csrf import CSRFProtect
- from werkzeug.contrib.fixers import ProxyFix
- from superset import config, utils
- from superset.connectors.connector_registry import ConnectorRegistry
- from superset.security import SupersetSecurityManager
- APP_DIR = os.path.dirname(__file__)
- CONFIG_MODULE = os.environ.get('SUPERSET_CONFIG', 'superset.config')
- if not os.path.exists(config.DATA_DIR):
- os.makedirs(config.DATA_DIR)
- with open(APP_DIR + '/static/assets/backendSync.json', 'r') as f:
- frontend_config = json.load(f)
- app = Flask(__name__)
- app.config.from_object(CONFIG_MODULE)
- conf = app.config
- #################################################################
- # Handling manifest file logic at app start
- #################################################################
- MANIFEST_FILE = APP_DIR + '/static/assets/dist/manifest.json'
- manifest = {}
- def parse_manifest_json():
- global manifest
- try:
- with open(MANIFEST_FILE, 'r') as f:
- # the manifest inclues non-entry files
- # we only need entries in templates
- full_manifest = json.load(f)
- manifest = full_manifest.get('entrypoints', {})
- except Exception:
- pass
- def get_js_manifest_files(filename):
- if app.debug:
- parse_manifest_json()
- entry_files = manifest.get(filename, {})
- return entry_files.get('js', [])
- def get_css_manifest_files(filename):
- if app.debug:
- parse_manifest_json()
- entry_files = manifest.get(filename, {})
- return entry_files.get('css', [])
- def get_unloaded_chunks(files, loaded_chunks):
- filtered_files = [f for f in files if f not in loaded_chunks]
- for f in filtered_files:
- loaded_chunks.add(f)
- return filtered_files
- parse_manifest_json()
- @app.context_processor
- def get_manifest():
- return dict(
- loaded_chunks=set(),
- get_unloaded_chunks=get_unloaded_chunks,
- js_manifest=get_js_manifest_files,
- css_manifest=get_css_manifest_files,
- )
- #################################################################
- for bp in conf.get('BLUEPRINTS'):
- try:
- print("Registering blueprint: '{}'".format(bp.name))
- app.register_blueprint(bp)
- except Exception as e:
- print('blueprint registration failed')
- logging.exception(e)
- if conf.get('SILENCE_FAB'):
- logging.getLogger('flask_appbuilder').setLevel(logging.ERROR)
- if app.debug:
- app.logger.setLevel(logging.DEBUG)
- else:
- # In production mode, add log handler to sys.stderr.
- app.logger.addHandler(logging.StreamHandler())
- app.logger.setLevel(logging.INFO)
- logging.getLogger('pyhive.presto').setLevel(logging.INFO)
- db = SQLA(app)
- if conf.get('WTF_CSRF_ENABLED'):
- csrf = CSRFProtect(app)
- csrf_exempt_list = conf.get('WTF_CSRF_EXEMPT_LIST', [])
- for ex in csrf_exempt_list:
- csrf.exempt(ex)
- utils.pessimistic_connection_handling(db.engine)
- cache = utils.setup_cache(app, conf.get('CACHE_CONFIG'))
- tables_cache = utils.setup_cache(app, conf.get('TABLE_NAMES_CACHE_CONFIG'))
- migrate = Migrate(app, db, directory=APP_DIR + '/migrations')
- # Logging configuration
- logging.basicConfig(format=app.config.get('LOG_FORMAT'))
- logging.getLogger().setLevel(app.config.get('LOG_LEVEL'))
- if app.config.get('ENABLE_TIME_ROTATE'):
- logging.getLogger().setLevel(app.config.get('TIME_ROTATE_LOG_LEVEL'))
- handler = TimedRotatingFileHandler(
- app.config.get('FILENAME'),
- when=app.config.get('ROLLOVER'),
- interval=app.config.get('INTERVAL'),
- backupCount=app.config.get('BACKUP_COUNT'))
- logging.getLogger().addHandler(handler)
- if app.config.get('ENABLE_CORS'):
- from flask_cors import CORS
- CORS(app, **app.config.get('CORS_OPTIONS'))
- if app.config.get('ENABLE_PROXY_FIX'):
- app.wsgi_app = ProxyFix(app.wsgi_app)
- if app.config.get('ENABLE_CHUNK_ENCODING'):
- class ChunkedEncodingFix(object):
- def __init__(self, app):
- self.app = app
- def __call__(self, environ, start_response):
- # Setting wsgi.input_terminated tells werkzeug.wsgi to ignore
- # content-length and read the stream till the end.
- if environ.get('HTTP_TRANSFER_ENCODING', '').lower() == u'chunked':
- environ['wsgi.input_terminated'] = True
- return self.app(environ, start_response)
- app.wsgi_app = ChunkedEncodingFix(app.wsgi_app)
- if app.config.get('UPLOAD_FOLDER'):
- try:
- os.makedirs(app.config.get('UPLOAD_FOLDER'))
- except OSError:
- pass
- for middleware in app.config.get('ADDITIONAL_MIDDLEWARE'):
- app.wsgi_app = middleware(app.wsgi_app)
- class MyIndexView(IndexView):
- @expose('/')
- def index(self):
- return redirect('/superset/welcome')
- custom_sm = app.config.get('CUSTOM_SECURITY_MANAGER') or SupersetSecurityManager
- if not issubclass(custom_sm, SupersetSecurityManager):
- raise Exception(
- """Your CUSTOM_SECURITY_MANAGER must now extend SupersetSecurityManager,
- not FAB's security manager.
- See [4565] in UPDATING.md""")
- appbuilder = AppBuilder(
- app,
- db.session,
- base_template='superset/base.html',
- indexview=MyIndexView,
- security_manager_class=custom_sm,
- update_perms=utils.get_update_perms_flag(),
- )
- security_manager = appbuilder.sm
- results_backend = app.config.get('RESULTS_BACKEND')
- # Registering sources
- module_datasource_map = app.config.get('DEFAULT_MODULE_DS_MAP')
- module_datasource_map.update(app.config.get('ADDITIONAL_MODULE_DS_MAP'))
- ConnectorRegistry.register_sources(module_datasource_map)
- # Flask-Compress
- if conf.get('ENABLE_FLASK_COMPRESS'):
- Compress(app)
- # Hook that provides administrators a handle on the Flask APP
- # after initialization
- flask_app_mutator = app.config.get('FLASK_APP_MUTATOR')
- if flask_app_mutator:
- flask_app_mutator(app)
- from superset import views # noqa
|