import sys import json import utils import sensors import db import logger import config log = logger.get_logger(__name__) conf = config.get_config() import alerter # define the web application app = Flask(__name__, template_folder=conf["constants"]["base_dir"]) # apply gzip compression if conf["gui"]["compress"]: Compress(app) # render index if no page name is provided @app.route('/') def root(): return render_template(conf["constants"]["web_template"]) # return favicon @app.route('/favicon.ico') def favicon(): return send_from_directory(conf["constants"]["web_dir"], "favicon.ico") # static folder (web)
"".join(traceback.format_stack(limit=7)[:-1])) np.seterrcall(np_err_handler) np.seterr(all="call") # Global variables, and also initializing the webapp using Flask framework: path_root = "results/" if_runningOnline = "DYNO" in os.environ # detect whether on Heroku # use cache only when in production mode; in other words, don't use cache on local machine if_useCache = if_runningOnline AUTH_CODE = "123" # ongoingJobs = [] app = Flask(__name__) Compress(app) # https://github.com/libwilliam/flask-compress # redis configuation, for SSE support: # 'os.environ.get("REDIS_URL")' is for Heroku and "redis://localhost" is meant for localhost. app.config["REDIS_URL"] = os.environ.get("REDIS_URL") or "redis://localhost" app.register_blueprint(sse, url_prefix="/stream") # load JSON schema for Puz file for validation: with open("puzzles/schema.js") as f: schema = f.read() schema = json.loads(schema) @app.route("/plot", methods=["POST", "OPTIONS"]) def plot(): startTime = time.time() # start timer
def configure_extensions(app): CORS(app, max_age=600) Compress(app)
def create_app(app_name=None): # Configuration settings import config if not app_name: app_name = config.APP_NAME # Only enable password related functionality in server mode. if config.SERVER_MODE is True: # Some times we need to access these config params where application # context is not available (we can't use current_app.config in those # cases even with current_app.app_context()) # So update these params in config itself. # And also these updated config values will picked up by application # since we are updating config before the application instance is # created. config.SECURITY_RECOVERABLE = True config.SECURITY_CHANGEABLE = True # Now we'll open change password page in alertify dialog # we don't want it to redirect to main page after password # change operation so we will open the same password change page again. config.SECURITY_POST_CHANGE_VIEW = 'browser.change_password' """Create the Flask application, startup logging and dynamically load additional modules (blueprints) that are found in this directory.""" app = PgAdmin(__name__, static_url_path='/static') # Removes unwanted whitespace from render_template function app.jinja_env.trim_blocks = True app.config.from_object(config) app.config.update(dict(PROPAGATE_EXCEPTIONS=True)) ########################################################################## # Setup logging and log the application startup ########################################################################## # We won't care about errors in the logging system, we are more # interested in application errors. logging.raiseExceptions = False # Add SQL level logging, and set the base logging level logging.addLevelName(25, 'SQL') app.logger.setLevel(logging.DEBUG) app.logger.handlers = [] # We also need to update the handler on the webserver in order to see # request. Setting the level prevents werkzeug from setting up it's own # stream handler thus ensuring all the logging goes through the pgAdmin # logger. logger = logging.getLogger('werkzeug') logger.setLevel(config.CONSOLE_LOG_LEVEL) # Set SQLITE_PATH to TEST_SQLITE_PATH while running test cases if ('PGADMIN_TESTING_MODE' in os.environ and os.environ['PGADMIN_TESTING_MODE'] == '1'): config.SQLITE_PATH = config.TEST_SQLITE_PATH config.MASTER_PASSWORD_REQUIRED = False config.UPGRADE_CHECK_ENABLED = False # Ensure the various working directories exist from pgadmin.setup import create_app_data_directory, db_upgrade create_app_data_directory(config) # File logging fh = logging.FileHandler(config.LOG_FILE, encoding='utf-8') fh.setLevel(config.FILE_LOG_LEVEL) fh.setFormatter(logging.Formatter(config.FILE_LOG_FORMAT)) app.logger.addHandler(fh) logger.addHandler(fh) # Console logging ch = logging.StreamHandler() ch.setLevel(config.CONSOLE_LOG_LEVEL) ch.setFormatter(logging.Formatter(config.CONSOLE_LOG_FORMAT)) app.logger.addHandler(ch) logger.addHandler(ch) # Log the startup app.logger.info('########################################################') app.logger.info('Starting %s v%s...', config.APP_NAME, config.APP_VERSION) app.logger.info('########################################################') app.logger.debug("Python syspath: %s", sys.path) ########################################################################## # Setup i18n ########################################################################## # Initialise i18n babel = Babel(app) app.logger.debug('Available translations: %s' % babel.list_translations()) @babel.localeselector def get_locale(): """Get the language for the user.""" language = 'en' if config.SERVER_MODE is False: # Get the user language preference from the miscellaneous module if current_user.is_authenticated: user_id = current_user.id else: user = user_datastore.get_user(config.DESKTOP_USER) if user is not None: user_id = user.id user_language = Preferences.raw_value('miscellaneous', 'user_language', None, user_id) if user_language is not None: language = user_language else: # If language is available in get request then return the same # otherwise check the session or cookie data = request.form if 'language' in data: language = data['language'] or language setattr(session, 'PGADMIN_LANGUAGE', language) elif hasattr(session, 'PGADMIN_LANGUAGE'): language = getattr(session, 'PGADMIN_LANGUAGE', language) elif hasattr(request.cookies, 'PGADMIN_LANGUAGE'): language = getattr(request.cookies, 'PGADMIN_LANGUAGE', language) return language ########################################################################## # Setup authentication ########################################################################## app.config['SQLALCHEMY_DATABASE_URI'] = u'sqlite:///{0}?timeout={1}' \ .format(config.SQLITE_PATH.replace(u'\\', u'/'), getattr(config, 'SQLITE_TIMEOUT', 500) ) # Create database connection object and mailer db.init_app(app) ########################################################################## # Upgrade the schema (if required) ########################################################################## with app.app_context(): # Run migration for the first time i.e. create database from config import SQLITE_PATH # If version not available, user must have aborted. Tables are not # created and so its an empty db if not os.path.exists(SQLITE_PATH) or get_version() == -1: db_upgrade(app) else: schema_version = get_version() # Run migration if current schema version is greater than the # schema version stored in version table if CURRENT_SCHEMA_VERSION >= schema_version: db_upgrade(app) # Update schema version to the latest if CURRENT_SCHEMA_VERSION > schema_version: set_version(CURRENT_SCHEMA_VERSION) db.session.commit() if os.name != 'nt': os.chmod(config.SQLITE_PATH, 0o600) Mail(app) import pgadmin.utils.paths as paths paths.init_app(app) # Setup Flask-Security user_datastore = SQLAlchemyUserDatastore(db, User, Role) security = Security(None, user_datastore) ########################################################################## # Setup security ########################################################################## with app.app_context(): config.CSRF_SESSION_KEY = Keys.query.filter_by( name='CSRF_SESSION_KEY').first().value config.SECRET_KEY = Keys.query.filter_by( name='SECRET_KEY').first().value config.SECURITY_PASSWORD_SALT = Keys.query.filter_by( name='SECURITY_PASSWORD_SALT').first().value # Update the app.config with proper security keyes for signing CSRF data, # signing cookies, and the SALT for hashing the passwords. app.config.update( dict({ 'CSRF_SESSION_KEY': config.CSRF_SESSION_KEY, 'SECRET_KEY': config.SECRET_KEY, 'SECURITY_PASSWORD_SALT': config.SECURITY_PASSWORD_SALT, 'SESSION_COOKIE_DOMAIN': config.SESSION_COOKIE_DOMAIN, # CSRF Token expiration till session expires 'WTF_CSRF_TIME_LIMIT': getattr(config, 'CSRF_TIME_LIMIT', None), 'WTF_CSRF_METHODS': ['GET', 'POST', 'PUT', 'DELETE'], })) security.init_app(app, user_datastore) # register custom unauthorised handler. app.login_manager.unauthorized_handler(pga_unauthorised) # Set the permanent session lifetime to the specified value in config file. app.permanent_session_lifetime = timedelta( days=config.SESSION_EXPIRATION_TIME) app.session_interface = create_session_interface(app, config.SESSION_SKIP_PATHS) # Make the Session more secure against XSS & CSRF when running in web mode if config.SERVER_MODE and config.ENHANCED_COOKIE_PROTECTION: paranoid = Paranoid(app) paranoid.redirect_view = 'browser.index' ########################################################################## # Load all available server drivers ########################################################################## driver.init_app(app) ########################################################################## # Register language to the preferences after login ########################################################################## @user_logged_in.connect_via(app) def register_language(sender, user): # After logged in, set the language in the preferences if we get from # the login page data = request.form if 'language' in data: language = data['language'] # Set the user language preference misc_preference = Preferences.module('miscellaneous') user_languages = misc_preference.preference('user_language') if user_languages and language: language = user_languages.set(language) ########################################################################## # Register any local servers we can discover ########################################################################## @user_logged_in.connect_via(app) def on_user_logged_in(sender, user): # Keep hold of the user ID user_id = user.id # Get the first server group for the user servergroup_id = 1 servergroups = ServerGroup.query.filter_by( user_id=user_id).order_by("id") if servergroups.count() > 0: servergroup = servergroups.first() servergroup_id = servergroup.id '''Add a server to the config database''' def add_server(user_id, servergroup_id, name, superuser, port, discovery_id, comment): # Create a server object if needed, and store it. servers = Server.query.filter_by( user_id=user_id, discovery_id=svr_discovery_id).order_by("id") if servers.count() > 0: return svr = Server(user_id=user_id, servergroup_id=servergroup_id, name=name, host='localhost', port=port, maintenance_db='postgres', username=superuser, ssl_mode='prefer', comment=svr_comment, discovery_id=discovery_id) db.session.add(svr) db.session.commit() # Figure out what servers are present if winreg is not None: arch_keys = set() proc_arch = os.environ['PROCESSOR_ARCHITECTURE'].lower() try: proc_arch64 = os.environ['PROCESSOR_ARCHITEW6432'].lower() except Exception as e: proc_arch64 = None if proc_arch == 'x86' and not proc_arch64: arch_keys.add(0) elif proc_arch == 'x86' or proc_arch == 'amd64': arch_keys.add(winreg.KEY_WOW64_32KEY) arch_keys.add(winreg.KEY_WOW64_64KEY) for arch_key in arch_keys: for server_type in ('PostgreSQL', 'EnterpriseDB'): try: root_key = winreg.OpenKey( winreg.HKEY_LOCAL_MACHINE, "SOFTWARE\\" + server_type + "\Services", 0, winreg.KEY_READ | arch_key) for i in xrange(0, winreg.QueryInfoKey(root_key)[0]): inst_id = winreg.EnumKey(root_key, i) inst_key = winreg.OpenKey(root_key, inst_id) svr_name = winreg.QueryValueEx( inst_key, 'Display Name')[0] svr_superuser = winreg.QueryValueEx( inst_key, 'Database Superuser')[0] svr_port = winreg.QueryValueEx(inst_key, 'Port')[0] svr_discovery_id = inst_id svr_comment = gettext( "Auto-detected %s installation with the data " "directory at %s" % (winreg.QueryValueEx(inst_key, 'Display Name')[0], winreg.QueryValueEx(inst_key, 'Data Directory')[0])) add_server(user_id, servergroup_id, svr_name, svr_superuser, svr_port, svr_discovery_id, svr_comment) inst_key.Close() except Exception as e: pass else: # We use the postgres-winreg.ini file on non-Windows try: from configparser import ConfigParser except ImportError: from ConfigParser import ConfigParser # Python 2 registry = ConfigParser() try: registry.read('/etc/postgres-reg.ini') sections = registry.sections() # Loop the sections, and get the data from any that are PG or PPAS for section in sections: if (section.startswith('PostgreSQL/') or section.startswith('EnterpriseDB/')): svr_name = registry.get(section, 'Description') svr_superuser = registry.get(section, 'Superuser') # getint function throws exception if value is blank. # Ex: Port= # In such case we should handle the exception and continue # to read the next section of the config file. try: svr_port = registry.getint(section, 'Port') except ValueError: continue svr_discovery_id = section description = registry.get(section, 'Description') data_directory = registry.get(section, 'DataDirectory') if hasattr(str, 'decode'): description = description.decode('utf-8') data_directory = data_directory.decode('utf-8') svr_comment = gettext(u"Auto-detected %s installation " u"with the data directory at %s" % (description, data_directory)) add_server(user_id, servergroup_id, svr_name, svr_superuser, svr_port, svr_discovery_id, svr_comment) except Exception as e: pass @user_logged_in.connect_via(app) @user_logged_out.connect_via(app) def force_session_write(app, user): session.force_write = True @user_logged_in.connect_via(app) def store_crypt_key(app, user): # in desktop mode, master password is used to encrypt/decrypt # and is stored in the keyManager memory if config.SERVER_MODE: if 'password' in request.form: current_app.keyManager.set(request.form['password']) @user_logged_out.connect_via(app) def current_user_cleanup(app, user): from config import PG_DEFAULT_DRIVER from pgadmin.utils.driver import get_driver from flask import current_app # remove key current_app.keyManager.reset() for mdl in current_app.logout_hooks: try: mdl.on_logout(user) except Exception as e: current_app.logger.exception(e) _driver = get_driver(PG_DEFAULT_DRIVER) _driver.gc_own() ########################################################################## # Load plugin modules ########################################################################## for module in app.find_submodules('pgadmin'): app.logger.info('Registering blueprint module: %s' % module) app.register_blueprint(module) app.register_logout_hook(module) ########################################################################## # Handle the desktop login ########################################################################## @app.before_request def before_request(): """Login the default user if running in desktop mode""" # Check the auth key is valid, if it's set, and we're not in server # mode, and it's not a help file request. if not config.SERVER_MODE and app.PGADMIN_KEY != '': if (('key' not in request.args or request.args['key'] != app.PGADMIN_KEY) and request.cookies.get('PGADMIN_KEY') != app.PGADMIN_KEY and request.endpoint != 'help.static'): abort(401) if not config.SERVER_MODE and not current_user.is_authenticated: user = user_datastore.get_user(config.DESKTOP_USER) # Throw an error if we failed to find the desktop user, to give # the sysadmin a hint. We'll continue to try to login anyway as # that'll through a nice 500 error for us. if user is None: app.logger.error( 'The desktop user %s was not found in the configuration ' 'database.' % config.DESKTOP_USER) abort(401) login_user(user) # if the server is restarted the in memory key will be lost # but the user session may still be active. Logout the user # to get the key again when login if config.SERVER_MODE and current_user.is_authenticated: if current_app.keyManager.get() is None and \ request.endpoint not in ('security.login', 'security.logout'): logout_user() @app.after_request def after_request(response): if 'key' in request.args: domain = dict() if config.COOKIE_DEFAULT_DOMAIN and \ config.COOKIE_DEFAULT_DOMAIN != 'localhost': domain['domain'] = config.COOKIE_DEFAULT_DOMAIN response.set_cookie('PGADMIN_KEY', value=request.args['key'], path=config.COOKIE_DEFAULT_PATH, **domain) # X-Frame-Options for security if config.X_FRAME_OPTIONS != "" and \ config.X_FRAME_OPTIONS.lower() != "deny": response.headers["X-Frame-Options"] = config.X_FRAME_OPTIONS return response ########################################################################## # Cache busting ########################################################################## # Version number to be added to all static file url requests # This is used by url_for function when generating urls # This will solve caching issues when application is upgrading # This is called - Cache Busting @app.url_defaults def add_internal_version(endpoint, values): extensions = config.APP_VERSION_EXTN # Add the internal version only if it is set if config.APP_VERSION_PARAM is not None and \ config.APP_VERSION_PARAM != '': # If there is a filename, add the version if 'filename' in values \ and values['filename'].endswith(extensions): values[config.APP_VERSION_PARAM] = config.APP_VERSION_INT else: # Sometimes there may be direct endpoint for some files # There will be only one rule for such endpoints urls = [url for url in app.url_map.iter_rules(endpoint)] if len(urls) == 1 and urls[0].rule.endswith(extensions): values[config.APP_VERSION_PARAM] = \ config.APP_VERSION_INT # Strip away internal version param before sending further to app as it was # required for cache busting only @app.url_value_preprocessor def strip_version_number(endpoint, values): if values and config.APP_VERSION_PARAM in values: values.pop(config.APP_VERSION_PARAM) ########################################################################## # Minify output. Not required in desktop mode ########################################################################## if not config.DEBUG and config.SERVER_MODE: from flask_compress import Compress Compress(app) @app.context_processor def inject_blueprint(): """Inject a reference to the current blueprint, if any.""" return { 'current_app': current_app, 'current_blueprint': current_blueprint } @app.errorhandler(Exception) def all_exception_handler(e): current_app.logger.error(e, exc_info=True) return internal_server_error(errormsg=str(e)) # Exclude HTTPexception from above handler (all_exception_handler) # HTTPException are user defined exceptions and those should be returned # as is @app.errorhandler(HTTPException) def http_exception_handler(e): current_app.logger.error(e, exc_info=True) return e # Intialize the key manager app.keyManager = KeyManager() ########################################################################## # Protection against CSRF attacks ########################################################################## with app.app_context(): pgCSRFProtect.init_app(app) ########################################################################## # All done! ########################################################################## return app
def __init__(self, name='__main__', server=None, static_folder='static', assets_folder=None, assets_url_path='/assets', assets_ignore='', include_assets_files=True, url_base_pathname=None, assets_external_path=None, requests_pathname_prefix=None, routes_pathname_prefix=None, compress=True, meta_tags=None, index_string=_default_index, external_scripts=None, external_stylesheets=None, suppress_callback_exceptions=None, components_cache_max_age=None, **kwargs): # pylint-disable: too-many-instance-attributes if 'csrf_protect' in kwargs: warnings.warn( ''' `csrf_protect` is no longer used, CSRF protection has been removed as it is no longer necessary. See https://github.com/plotly/dash/issues/141 for details. ''', DeprecationWarning) name = name if server is None else server.name self._assets_folder = assets_folder or os.path.join( flask.helpers.get_root_path(name), 'assets') self._assets_url_path = assets_url_path # allow users to supply their own flask server self.server = server or Flask(name, static_folder=static_folder) if 'assets' not in self.server.blueprints: self.server.register_blueprint( flask.Blueprint('assets', 'assets', static_folder=self._assets_folder, static_url_path=assets_url_path)) env_configs = _configs.env_configs() url_base_pathname, routes_pathname_prefix, requests_pathname_prefix = \ _configs.pathname_configs( url_base_pathname, routes_pathname_prefix, requests_pathname_prefix, environ_configs=env_configs) self.url_base_pathname = url_base_pathname self.config = _AttributeDict({ 'suppress_callback_exceptions': _configs.get_config('suppress_callback_exceptions', suppress_callback_exceptions, env_configs, False), 'routes_pathname_prefix': routes_pathname_prefix, 'requests_pathname_prefix': requests_pathname_prefix, 'include_assets_files': _configs.get_config('include_assets_files', include_assets_files, env_configs, True), 'assets_external_path': _configs.get_config('assets_external_path', assets_external_path, env_configs, ''), 'components_cache_max_age': int( _configs.get_config('components_cache_max_age', components_cache_max_age, env_configs, 2678400)) }) # list of dependencies self.callback_map = {} self._index_string = '' self.index_string = index_string self._meta_tags = meta_tags or [] self._favicon = None if compress: # gzip Compress(self.server) @self.server.errorhandler(exceptions.PreventUpdate) def _handle_error(error): """Handle a halted callback and return an empty 204 response""" print(error, file=sys.stderr) return ('', 204) # static files from the packages self.css = Css() self.scripts = Scripts() self._external_scripts = external_scripts or [] self._external_stylesheets = external_stylesheets or [] self.assets_ignore = assets_ignore self.registered_paths = collections.defaultdict(set) # urls self.routes = [] self._add_url( '{}_dash-layout'.format(self.config['routes_pathname_prefix']), self.serve_layout) self._add_url( '{}_dash-dependencies'.format( self.config['routes_pathname_prefix']), self.dependencies) self._add_url( '{}_dash-update-component'.format( self.config['routes_pathname_prefix']), self.dispatch, ['POST']) self._add_url(('{}_dash-component-suites' '/<string:package_name>' '/<path:path_in_package_dist>').format( self.config['routes_pathname_prefix']), self.serve_component_suites) self._add_url( '{}_dash-routes'.format(self.config['routes_pathname_prefix']), self.serve_routes) self._add_url(self.config['routes_pathname_prefix'], self.index) # catch-all for front-end routes, used by dcc.Location self._add_url( '{}<path:path>'.format(self.config['routes_pathname_prefix']), self.index) self._add_url( '{}_favicon.ico'.format(self.config['routes_pathname_prefix']), self._serve_default_favicon) self.server.before_first_request(self._setup_server) self._layout = None self._cached_layout = None self._dev_tools = _AttributeDict({'serve_dev_bundles': False}) # add a handler for components suites errors to return 404 self.server.errorhandler(exceptions.InvalidResourceError)( self._invalid_resources_handler)
def build_app(url=None, reaper_on=True, app_root=None, additional_templates=None, **kwargs): """ Builds :class:`flask:flask.Flask` application encapsulating endpoints for D-Tale's front-end :param url: optional parameter which sets the host & root for any internal endpoints (ex: pinging shutdown) :type url: str, optional :param reaper_on: whether to run auto-reaper subprocess :type reaper_on: bool :param app_root: Optional path to prepend to the routes of D-Tale. This is used when making use of Jupyterhub server proxy :type app_root: str, optional :param additional_templates: path(s) to any other jinja templates you would like to load. This comes into play if you're embedding D-Tale into your own Flask app :type: str, list, optional :return: :class:`flask:flask.Flask` application :rtype: :class:`dtale.app.DtaleFlask` """ app = DtaleFlask( "dtale", reaper_on=reaper_on, static_url_path="/dtale/static", url=url, instance_relative_config=False, app_root=app_root, ) app.config["SECRET_KEY"] = "Dtale" app.jinja_env.trim_blocks = True app.jinja_env.lstrip_blocks = True if app_root is not None: app.config["APPLICATION_ROOT"] = app_root app.jinja_env.globals["url_for"] = app.url_for app.jinja_env.globals["is_app_root_defined"] = is_app_root_defined if additional_templates: loaders = [app.jinja_loader] loaders += [ jinja2.FileSystemLoader(loc) for loc in make_list(additional_templates) ] my_loader = jinja2.ChoiceLoader(loaders) app.jinja_loader = my_loader app.register_blueprint(dtale) compress = Compress() compress.init_app(app) def _root(): return redirect("/dtale/{}".format(head_endpoint())) @app.route("/") def root(): return _root() @app.route("/dtale") def dtale_base(): """ :class:`flask:flask.Flask` routes which redirect to dtale/main :return: 302 - flask.redirect('/dtale/main') """ return _root() @app.route("/favicon.ico") def favicon(): """ :class:`flask:flask.Flask` routes which returns favicon :return: image/png """ return redirect(app.url_for("static", filename="images/favicon.ico")) @app.route("/missing-js") def missing_js(): missing_js_commands = ( ">> cd [location of your local dtale repo]\n" ">> yarn install\n" ">> yarn run build # or 'yarn run watch' if you're trying to develop" ) return render_template("dtale/errors/missing_js.html", missing_js_commands=missing_js_commands) @app.errorhandler(404) def page_not_found(e=None): """ :class:`flask:flask.Flask` routes which returns favicon :param e: exception :return: text/html with exception information """ return ( render_template( "dtale/errors/404.html", page="", error=e, stacktrace=str(traceback.format_exc()), ), 404, ) @app.errorhandler(500) def internal_server_error(e=None): """ :class:`flask:flask.Flask` route which returns favicon :param e: exception :return: text/html with exception information """ return ( render_template( "dtale/errors/500.html", page="", error=e, stacktrace=str(traceback.format_exc()), ), 500, ) def shutdown_server(): global ACTIVE_HOST, ACTIVE_PORT """ This function that checks if flask.request.environ['werkzeug.server.shutdown'] exists and if so, executes that function """ logger.info("Executing shutdown...") func = request.environ.get("werkzeug.server.shutdown") if func is None: raise RuntimeError("Not running with the Werkzeug Server") func() global_state.cleanup() ACTIVE_PORT = None ACTIVE_HOST = None @app.route("/shutdown") def shutdown(): """ :class:`flask:flask.Flask` route for initiating server shutdown :return: text/html with server shutdown message """ app.clear_reaper() shutdown_server() return "Server shutting down..." @app.before_request def before_request(): """ Logic executed before each :attr:`flask:flask.request` :return: text/html with server shutdown message """ app.build_reaper() @app.route("/site-map") def site_map(): """ :class:`flask:flask.Flask` route listing all available flask endpoints :return: JSON of all flask enpoints [ [endpoint1, function path1], ..., [endpointN, function pathN] ] """ def has_no_empty_params(rule): defaults = rule.defaults or () arguments = rule.arguments or () return len(defaults) >= len(arguments) links = [] for rule in app.url_map.iter_rules(): # Filter out rules we can't navigate to in a browser # and rules that require parameters if "GET" in rule.methods and has_no_empty_params(rule): url = app.url_for(rule.endpoint, **(rule.defaults or {})) links.append((url, rule.endpoint)) return jsonify(links) @app.route("/version-info") def version_info(): """ :class:`flask:flask.Flask` route for retrieving version information about D-Tale :return: text/html version information """ _, version = retrieve_meta_info_and_version("dtale") return str(version) @app.route("/health") def health_check(): """ :class:`flask:flask.Flask` route for checking if D-Tale is up and running :return: text/html 'ok' """ return "ok" with app.app_context(): from .dash_application import views as dash_views app = dash_views.add_dash(app) return app
def register_extensions(app): """ register extensions to the app """ app.jinja_env.add_extension('jinja2.ext.do') # Global values in jinja # Uncomment to enable profiler # See scripts/profile_analyzer.py to analyze output # app = setup_profiler(app) # Compress app responses with gzip compress = Compress() compress.init_app(app) # Influx db time-series database db.init_app(app) influx_db.init_app(app) # Limit authentication blueprint requests to 200 per minute limiter = Limiter(app, key_func=get_ip_address) limiter.limit("200/minute")(routes_authentication.blueprint) # Language translations babel = Babel(app) @babel.localeselector def get_locale(): try: user = User.query.filter( User.id == flask_login.current_user.id).first() if user and user.language != '': for key in LANGUAGES: if key == user.language: return key # Bypass endpoint test error "'AnonymousUserMixin' object has no attribute 'id'" except AttributeError: pass return request.accept_languages.best_match(LANGUAGES.keys()) # User login management login_manager = flask_login.LoginManager() login_manager.init_app(app) @login_manager.user_loader def user_loader(user_id): user = User.query.filter(User.id == user_id).first() if not user: return return user @login_manager.unauthorized_handler def unauthorized(): flash(gettext('Please log in to access this page'), "error") return redirect(url_for('routes_authentication.do_login')) # Create and populate database if it doesn't exist with app.app_context(): db.create_all() populate_db() # This is disabled because there's a bug that messes up user databases # The upgrade script will execute alembic to upgrade the database # alembic_upgrade_db() # Check user option to force all web connections to use SSL # Fail if the URI is empty (pytest is running) if app.config['SQLALCHEMY_DATABASE_URI'] != 'sqlite://': with session_scope( app.config['SQLALCHEMY_DATABASE_URI']) as new_session: misc = new_session.query(Misc).first() if misc and misc.force_https: SSLify(app)
from flask import Flask, abort, request, session from flask_compress import Compress # type: ignore from flask_socketio import SocketIO, emit # type: ignore from .constants import DEFAULT_GDB_EXECUTABLE, STATIC_DIR, TEMPLATE_DIR from .http_routes import blueprint from .http_util import is_cross_origin from .sessionmanager import SessionManager, DebugSession logger = logging.getLogger(__file__) # Create flask application and add some configuration keys to be used in various callbacks app = Flask(__name__, template_folder=str(TEMPLATE_DIR), static_folder=str(STATIC_DIR)) Compress( app ) # add gzip compression to Flask. see https://github.com/libwilliam/flask-compress app.register_blueprint(blueprint) app.config["initial_binary_and_args"] = [] app.config["gdb_path"] = DEFAULT_GDB_EXECUTABLE app.config["gdb_command"] = None app.config["TEMPLATES_AUTO_RELOAD"] = True app.config["project_home"] = None app.config["remap_sources"] = {} manager = SessionManager() app.config["_manager"] = manager app.secret_key = binascii.hexlify(os.urandom(24)).decode("utf-8") socketio = SocketIO(manage_session=False) @app.before_request
def create_app(config='CTFd.config.Config'): app = CTFdFlask(__name__) Compress(app) with app.app_context(): app.config.from_object(config) theme_loader = ThemeLoader(os.path.join(app.root_path, 'themes'), followlinks=True) app.jinja_loader = theme_loader from CTFd.models import db, Teams, Solves, Challenges, WrongKeys, Keys, Tags, Files, Tracking url = make_url(app.config['SQLALCHEMY_DATABASE_URI']) if url.drivername == 'postgres': url.drivername = 'postgresql' if url.drivername.startswith('mysql'): url.query['charset'] = 'utf8mb4' # Creates database if the database database does not exist if not database_exists(url): if url.drivername.startswith('mysql'): create_database(url, encoding='utf8mb4') else: create_database(url) # This allows any changes to the SQLALCHEMY_DATABASE_URI to get pushed back in # This is mostly so we can force MySQL's charset app.config['SQLALCHEMY_DATABASE_URI'] = str(url) # Register database db.init_app(app) # Register Flask-Migrate migrate.init_app(app, db) # Alembic sqlite support is lacking so we should just create_all anyway if url.drivername.startswith('sqlite'): db.create_all() else: if len(db.engine.table_names()) == 0: # This creates tables instead of db.create_all() # Allows migrations to happen properly migrate_upgrade() elif 'alembic_version' not in db.engine.table_names(): # There is no alembic_version because CTFd is from before it had migrations # Stamp it to the base migration if confirm_upgrade(): migrate_stamp(revision='cb3cfcc47e2f') run_upgrade() else: exit() app.db = db app.VERSION = __version__ cache.init_app(app) app.cache = cache update_check(force=True) version = utils.get_config('ctf_version') # Upgrading from an older version of CTFd if version and (StrictVersion(version) < StrictVersion(__version__)): if confirm_upgrade(): run_upgrade() else: exit() if not version: utils.set_config('ctf_version', __version__) if not utils.get_config('ctf_theme'): utils.set_config('ctf_theme', 'core') from CTFd.views import views from CTFd.challenges import challenges from CTFd.scoreboard import scoreboard from CTFd.auth import auth from CTFd.admin import admin, admin_statistics, admin_challenges, admin_pages, admin_scoreboard, admin_keys, admin_teams from CTFd.utils import init_utils, init_errors, init_logs init_utils(app) init_errors(app) init_logs(app) app.register_blueprint(views) app.register_blueprint(challenges) app.register_blueprint(scoreboard) app.register_blueprint(auth) app.register_blueprint(admin) app.register_blueprint(admin_statistics) app.register_blueprint(admin_challenges) app.register_blueprint(admin_teams) app.register_blueprint(admin_scoreboard) app.register_blueprint(admin_keys) app.register_blueprint(admin_pages) from CTFd.plugins import init_plugins init_plugins(app) return app
def setUp(self): self.app = Flask(__name__) self.app.testing = True Compress(self.app)
def create_flask_app(self): try: from flask import Flask, request from flask_compress import Compress # from flask_cors import CORS from flask_json import FlaskJSON, as_json, JsonError except ImportError: raise ImportError() app = Flask(__name__) #app.config['SWAGGER'] = { # 'title':'Colors API', # 'uiversion':3, # "openapi":"3.0.2" #} self.create_classify_worker() @app.route('/tts-classify', methods=['POST']) @as_json def tts_classify(): req_data = request.form if request.form else request.json # req_data['req_id'] = uuid.uuid1() # req_id = req_data['req_id'] texts = req_data['texts'] # text list if not isinstance(texts, list): texts = [texts] req_num = len(texts) text_ids = [] st = int(time.time() * 1000) for k in range(req_num): textid = uuid.uuid1().hex text_a = texts[k] text_b = None # input_item = DataItem(textid,text_a,None,None) text_ids.append(textid) input_item = { "guid":textid, "text_a":text_a, "text_b":text_b, } self.sender.send_json(jsonapi.dumps(input_item)) # self.ready_to_classify_que.put(input_item) self.logger.debug("put item:%s"%(textid)) req_time = time.time() req_data['req_time'] = req_time # self.ready_to_classify_que.put(req_data) collect_num = 0 pred_labels = [0]*req_num for k in range(req_num): while text_ids[k] not in self.classify_res: continue pred_labels[k] = self.classify_res[text_ids[k]] self.classify_res.pop(text_ids[k]) res_data = { "pred_labels":pred_labels } ed = int(time.time()*1000) cost = ed - st self.logger.debug("[timecost] %d ms"%(cost)) return res_data # CORS(app, origins=self.args.cors) FlaskJSON(app) Compress().init_app(app) return app
def test_delayed_init(self): compress = Compress() compress.init_app(self.app)
def test_constructor_init(self): Compress(self.app)
def create_app(settings_override=None): """ Create a Flask application using the app factory pattern. :param settings_override: Override settings :return: Flask app """ app = Flask(__name__, instance_relative_config=True) app.config.from_object('config.settings') app.config.from_pyfile('settings.py', silent=True) # Setting app server name and cookie domain if os.environ.get('PRODUCTION') == 'True': # Set the app server name app.config['SERVER_NAME'] = 'getschedulr.com' app.config['REMEMBER_COOKIE_DOMAIN'] = '.getschedulr.com' else: # Set the app server name SERVER_NAME = 'f691a605a823.ngrok.io' app.config['SERVER_NAME'] = SERVER_NAME app.config['REMEMBER_COOKIE_DOMAIN'] = '.' + SERVER_NAME # Disable CSRF in dev app.config['WTF_CSRF_ENABLED'] = False # Keeps the app from crashing on reload app.config['SQLALCHEMY_POOL_RECYCLE'] = 499 app.config['SQLALCHEMY_POOL_TIMEOUT'] = 120 app.static_folder = 'static' app.static_url_path = '/static' # CORS app.config['CORS_HEADERS'] = 'Content-Type' # Whitenoise # app.wsgi_app = WhiteNoise(app.wsgi_app, root='static/') if settings_override: app.config.update(settings_override) stripe.api_key = app.config.get('STRIPE_KEY') stripe.api_version = '2018-02-28' middleware(app) error_templates(app) exception_handler(app) app.register_blueprint(admin) app.register_blueprint(page) app.register_blueprint(contact) app.register_blueprint(user) app.register_blueprint(base) app.register_blueprint(calendar) app.register_blueprint(api) app.register_blueprint(billing) app.register_blueprint(errors) app.register_error_handler(404, page_not_found) app.register_error_handler(500, internal_error) template_processors(app) extensions(app) authentication(app, User) # Compress Flask app COMPRESS_MIMETYPES = ['text/html' 'text/css', 'application/json'] COMPRESS_LEVEL = 6 COMPRESS_MIN_SIZE = 500 Compress(app) @app.errorhandler(500) def error_502(e): return render_template('errors/500.html') @app.errorhandler(404) def error_404(e): return render_template('errors/404.html') @app.errorhandler(502) def error_502(e): return render_template('errors/500.html') return app
template_folder="../templates") try: import config c3bottles.config.from_object(config) except ImportError: c3bottles.config.update(SQLALCHEMY_DATABASE_URI="sqlite:///c3bottles.db", SQLALCHEMY_TRACK_MODIFICATIONS=False, SECRET_KEY=pwgen(64), BABEL_TRANSLATION_DIRECTORIES="../translations") print("\nWARNING: c3bottles is not configured properly and this\n" "instance fell back to the default configuration. This means\n" "that the secret key will change on every restart of the\n" "server and all users will be logged out forcibly!\n") Compress(c3bottles) db = SQLAlchemy(c3bottles, session_options={"autoflush": False}) lm = LoginManager(c3bottles) bcrypt = Bcrypt(c3bottles) csrf = CSRFProtect(c3bottles) babel = Babel(c3bottles) languages = ("en", "de") locales = {l: Locale(l) for l in languages} language_list = sorted([l for l in languages], key=lambda k: locales[k].get_display_name())
def __init__(self, name=None, server=None, filename=None, sharing=None, app_url=None, url_base_pathname='/', csrf_protect=True): # allow users to supply their own flask server if server is not None: self.server = server else: if name is None: name = 'dash' self.server = Flask(name) if self.server.secret_key is None: # If user supplied their own server, they might've supplied a # secret_key with it secret_key_name = 'dash_{}_secret_key'.format( # TODO - check for other illegal characters name.replace('.', '_')) secret_key = os.environ.get(secret_key_name, SeaSurf()._generate_token()) os.environ[secret_key_name] = secret_key self.server.secret_key = secret_key if filename is not None: fid = plotly_api.create_or_overwrite_dash_app( filename, sharing, app_url) self.fid = fid self.app_url = app_url self.sharing = sharing self.access_codes = self.create_access_codes() else: self.fid = None self.access_codes = None self.url_base_pathname = url_base_pathname # list of dependencies self.callback_map = {} # gzip Compress(self.server) # csrf protect if csrf_protect: self._csrf = SeaSurf(self.server) # static files from the packages self.css = Css() self.scripts = Scripts() self.registered_paths = {} # urls self.server.add_url_rule('{}_dash-login'.format( self.url_base_pathname), view_func=authentication.login, methods=['post']) self.server.add_url_rule('{}_dash-layout'.format( self.url_base_pathname), view_func=self.serve_layout) self.server.add_url_rule('{}_dash-dependencies'.format( self.url_base_pathname), view_func=self.dependencies) self.server.add_url_rule('{}_dash-update-component'.format( self.url_base_pathname), view_func=self.dispatch, methods=['POST']) self.server.add_url_rule( ('{}_dash-component-suites' '/<string:package_name>' '/<path:path_in_package_dist>').format(self.url_base_pathname), view_func=self.serve_component_suites) self.server.add_url_rule('{}_dash-routes'.format( self.url_base_pathname), view_func=self.serve_routes) self.server.add_url_rule(self.url_base_pathname, view_func=self.index) # catch-all for front-end routes self.server.add_url_rule('{}<path:path>'.format( self.url_base_pathname), view_func=self.index) self.server.before_first_request(self._setup_server) self._layout = None self.routes = []
from flexget.webserver import register_app, register_home log = logging.getLogger('webui') manager = None debug = False app_base = None ui_base = os.path.dirname(os.path.realpath(__file__)) ui_src = os.path.join(ui_base, 'src') ui_dist = os.path.join(ui_base, 'app') bower_components = os.path.join(ui_base, 'bower_components') webui_app = Flask(__name__) Compress(webui_app) webui_app.url_path = '/' @webui_app.route('/<path:path>') def serve_app(path): if debug: if path.startswith('bower_components'): return send_from_directory( bower_components, path.lstrip('bower_components').lstrip('/') ) if os.path.exists(os.path.join(ui_src, path)): return send_from_directory(ui_src, path) if not app_base:
from flask import Flask from flask_compress import Compress from models import db PUBLIC_KEY = 'i18183574422' PRIVATE_KEY = 'DWHmS0mwLkNTIUJJhP6bTmAN4WpKshVJomDSdeZ3' app = Flask(__name__) app.config.from_pyfile('app.cfg') db.init_app(app) compress = Compress(app) import views
def create_app(): # setup flask app = Flask("jazzband") # load decoupled config variables app.config.from_object("jazzband.config") @app.context_processor def app_context_processor(): return { "about": about_pages, "news": news_pages, "User": User, "Project": Project, "config": app.config, } @app.after_request def add_vary_header(response): response.vary.add("Cookie") response.headers["Jazzband"] = "We are all part of this." return response talisman.init_app( app, force_https=app.config["IS_PRODUCTION"], force_file_save=True, content_security_policy=app.config["CSP_RULES"], content_security_policy_report_only=app.config["CSP_REPORT_ONLY"], content_security_policy_report_uri=app.config["CSP_REPORT_URI"], feature_policy=app.config["FEATURE_POLICY"], ) postgres.init_app(app) redis.init_app(app) Migrate(app, postgres) cache.init_app(app) admin.init_app(app) cli.init_app(app) spinach.init_app(app) errors.init_app(app) if app.config["IS_PRODUCTION"]: app.wsgi_app = ProxyFix(app.wsgi_app) app.wsgi_app = WhiteNoise(app.wsgi_app, root="static/") mail.init_app(app) hooks.init_app(app) # setup session store session_store = RedisStore(redis) KVSessionExtension(session_store, app) Compress(app) about_pages.init_app(app) news_pages.init_app(app) login_manager.init_app(app) from . import blueprints # noqa blueprints.init_app(app) return app
login = LoginManager() # flask-login login.login_view = 'auth.login' login.login_message = _l('Please login to access this page.') mail = Mail() moment = Moment() gravatar = Gravatar(app=None, size=100, rating='g', default='robohash', force_default=False, force_lower=False, use_ssl=True, base_url=None) bootstrap = Bootstrap() # flask-bootstrap cache = Cache() # flask-caching compress = Compress() # flask-compress babel = Babel() # flask-babel def create_app(config_class=Config): app = Flask(__name__) app.config.from_object(config_class) db.init_app(app) migrate.init_app(app, db) login.init_app(app) mail.init_app(app) moment.init_app(app) gravatar.init_app(app) bootstrap.init_app(app) compress.init_app(app)
default=default or sort_choices[0], help='Sort by attribute', ) return pagination api_app = Flask(__name__, template_folder=os.path.join(__path__[0], 'templates')) api_app.config['REMEMBER_COOKIE_NAME'] = 'flexget.token' api_app.config['DEBUG'] = True api_app.config['ERROR_404_HELP'] = False api_app.url_map.strict_slashes = False CORS(api_app, expose_headers='Link, Total-Count, Count, ETag') Compress(api_app) api = API( api_app, title='Flexget API v{}'.format(__version__), version=__version__, description= 'View and manage flexget core operations and plugins. Open each endpoint view for usage information.' ' Navigate to http://flexget.com/API for more details.', format_checker=format_checker, ) base_message = { 'type': 'object', 'properties': { 'status_code': {
def build_app(reaper_on=True, hide_shutdown=False): """ Builds Flask application encapsulating endpoints for D-Tale's front-end :return: Flask application :rtype: :class:`dtale.app.DtaleFlask` """ app = DtaleFlask('dtale', reaper_on=reaper_on, static_url_path='') app.config['SECRET_KEY'] = 'Dtale' app.config['HIDE_SHUTDOWN'] = hide_shutdown app.jinja_env.trim_blocks = True app.jinja_env.lstrip_blocks = True app.register_blueprint(dtale) compress = Compress() compress.init_app(app) _, version = retrieve_meta_info_and_version('dtale') template = dict( info={ 'title': 'D-Tale', 'version': version, 'description': 'Web Client for Visualizing Pandas Objects', 'contact': { 'name': 'Man Alpha Technology', 'email': '*****@*****.**', 'url': 'https://github.com/man-group/dtale' }, }, host=socket.gethostname(), schemes=['http'], ) try: from flasgger import Swagger # flake8: NOQA Swagger(app, template=template) except ImportError: logger.debug( 'flasgger dependency not found, please install to enable feature') @app.route('/') @app.route('/dtale') @swag_from('swagger/dtale/root.yml') def root(): """ Flask routes which redirect to dtale/main :return: 302 - flask.redirect('/dtale/main') """ return redirect('/dtale/main') @app.route('/favicon.ico') def favicon(): """ Flask routes which returns favicon :return: image/png """ return redirect(url_for('static', filename='images/favicon.ico')) @app.errorhandler(404) def page_not_found(e=None): """ Flask routes which returns favicon :param e: exception :return: text/html with exception information """ logger.exception(e) return render_template('dtale/errors/404.html', page='', error=e, stacktrace=str(traceback.format_exc())), 404 @app.errorhandler(500) def internal_server_error(e=None): """ Flask route which returns favicon :param e: exception :return: text/html with exception information """ logger.exception(e) return render_template('dtale/errors/500.html', page='', error=e, stacktrace=str(traceback.format_exc())), 500 def shutdown_server(): """ This function that checks if flask.request.environ['werkzeug.server.shutdown'] exists and if so, executes that function """ logger.info('Executing shutdown...') func = request.environ.get('werkzeug.server.shutdown') if func is None: raise RuntimeError('Not running with the Werkzeug Server') func() cleanup(app.port) @app.route('/shutdown') @swag_from('swagger/dtale/shutdown.yml') def shutdown(): """ Flask route for initiating server shutdown :return: text/html with server shutdown message """ app.clear_reaper() shutdown_server() return 'Server shutting down...' @app.before_request def before_request(): """ Logic executed before each :attr:`flask:flask.request` :return: text/html with server shutdown message """ app.build_reaper() @app.route('/site-map') @swag_from('swagger/dtale/site-map.yml') def site_map(): """ Flask route listing all available flask endpoints :return: JSON of all flask enpoints [ [endpoint1, function path1], ..., [endpointN, function pathN] ] """ def has_no_empty_params(rule): defaults = rule.defaults or () arguments = rule.arguments or () return len(defaults) >= len(arguments) links = [] for rule in app.url_map.iter_rules(): # Filter out rules we can't navigate to in a browser # and rules that require parameters if "GET" in rule.methods and has_no_empty_params(rule): url = url_for(rule.endpoint, **(rule.defaults or {})) links.append((url, rule.endpoint)) return jsonify(links) @app.route('/version-info') @swag_from('swagger/dtale/version-info.yml') def version_info(): """ Flask route for retrieving version information about D-Tale :return: text/html version information """ _, version = retrieve_meta_info_and_version('dtale') return str(version) @app.route('/health') @swag_from('swagger/dtale/health.yml') def health_check(): """ Flask route for checking if D-Tale is up and running :return: text/html 'ok' """ return 'ok' return app
def create_app(): # Create flask app app = Flask(__name__) # Which config to use lzapi_mode = os.environ.get("LZAPI_MODE") if lzapi_mode is None: raise Exception( "No API mode designated. Set the LZAPI_MODE environment variable to 'dev' or 'prod'" ) # Config file given mode config_file = os.path.join(app.root_path, "../../etc/config-{}.py".format(lzapi_mode)) if not os.path.isfile(config_file): raise IOError( "Could not find configuration file {} for API mode {}".format( config_file, lzapi_mode)) # Load config app.config.from_pyfile(config_file) # Set mode app.config["LZAPI_MODE"] = lzapi_mode # Enable cross-domain headers on all routes CORS(app) # Enable compression support Compress(app) # Setup Postgres DB from . import db db.init_app(app) # Setup redis from . import redis_client redis_client.init_app(app) # Setup helpers from . import helpers helpers.init_app(app) # Setup error handlers from . import errors errors.init_app(app) # Register routes with app with app.app_context(): from . import routes app.register_blueprint(routes.bp) # JSON encoder for datetimes app.json_encoder = CustomJSONEncoder # If gunicorn is attached, route loggers there try: gunicorn_logger = logging.getLogger('gunicorn.error') app.logger.handlers = gunicorn_logger.handlers app.logger.setLevel(gunicorn_logger.level) except Exception as e: app.logger.warning("Could not attach to gunicorn logger: " + str(e)) app.logger.info("Flask app initialized") return app
def _init_sqlalchemy(): database = SQLAlchemy(application) database.init_app(application) application.session_interface = SqlAlchemySessionInterface( application, database, "test_sessions", "test_sess_") application.permanent_session_lifetime = datetime.timedelta(hours=1) _configure_logs() # NOTE: this needs to happen before starting the application # Load default config and override config from an environment variable application = Flask(__name__) _load_config() _init_sqlalchemy() Compress(application) cache = Cache(application, config={"CACHE_TYPE": "simple"}) mail = Mail(application) try: db = psycopg2.connect( host=application.config["DB_HOST"], database=application.config["DB_DATABASE"], user=application.config["DB_USER"], password=application.config["DB_PASSWORD"], port=application.config["DB_PORT"], ) c = db.cursor() c.execute("select external_id, internal_id from individuals") headers = [h[0] for h in c.description]
allow_origins = ['https://playground.daiiz.dev'] if os.environ.get('DEV_MODE', '0') == '1': allow_origins.append('http://localhost:3003') print('allow_origins:', allow_origins) app = Flask(__name__) CORS(app, resources={ r"/api/generate": { "origins": allow_origins, "methods": ['POST', 'OPTIONS'] } }) app.config["COMPRESS_MIMETYPES"] = ["image/png"] app.config["COMPRESS_ALGORITHM"] = ["gzip", "deflate"] compress = Compress() compress.init_app(app) def parse_thumbnail_size(request): size_range = [100, 2000] size = 1000 # default size try: size = min(int(request.args.get("size", "1000")), size_range[1]) if size < size_range[0]: size = size_range[0] except Exception as e: print(e) return size
""" Cache responses timeout. CACHE_DEFAULT_TIMEOUT : int """ CACHE.init_app(APP) APP.config.update( COMPRESS_LEVEL=3, COMPRESS_CACHE_KEY=lambda x: x.full_path, COMPRESS_CACHE_BACKEND=lambda: SimpleCache(default_timeout= # noqa CACHE_DEFAULT_TIMEOUT), ) Compress(APP) IMAGES_DIRECTORY = os.path.join(os.getcwd(), 'static', 'images') """ Images directory. IMAGES_DIRECTORY : unicode """ def _null_to_None(data): """ Converts *Javascript* originated *null* and *undefined* strings to `None`. Non-matching data will be passed untouched. Parameters
def build_app(url, host=None, reaper_on=True, hide_shutdown=False, github_fork=False): """ Builds :class:`flask:flask.Flask` application encapsulating endpoints for D-Tale's front-end :return: :class:`flask:flask.Flask` application :rtype: :class:`dtale.app.DtaleFlask` """ app = DtaleFlask('dtale', reaper_on=reaper_on, static_url_path='', url=url, instance_relative_config=False) app.config['SECRET_KEY'] = 'Dtale' app.config['HIDE_SHUTDOWN'] = hide_shutdown app.config['GITHUB_FORK'] = github_fork app.jinja_env.trim_blocks = True app.jinja_env.lstrip_blocks = True app.register_blueprint(dtale) compress = Compress() compress.init_app(app) @app.route('/') @app.route('/dtale') def root(): """ :class:`flask:flask.Flask` routes which redirect to dtale/main :return: 302 - flask.redirect('/dtale/main') """ return redirect('/dtale/main/{}'.format(head_data_id())) @app.route('/favicon.ico') def favicon(): """ :class:`flask:flask.Flask` routes which returns favicon :return: image/png """ return redirect(url_for('static', filename='images/favicon.ico')) @app.route('/missing-js') def missing_js(): missing_js_commands = ( '>> cd [location of your local dtale repo]\n' '>> yarn install\n' ">> yarn run build # or 'yarn run watch' if you're trying to develop" ) return render_template('dtale/errors/missing_js.html', missing_js_commands=missing_js_commands) @app.errorhandler(404) def page_not_found(e=None): """ :class:`flask:flask.Flask` routes which returns favicon :param e: exception :return: text/html with exception information """ return render_template('dtale/errors/404.html', page='', error=e, stacktrace=str(traceback.format_exc())), 404 @app.errorhandler(500) def internal_server_error(e=None): """ :class:`flask:flask.Flask` route which returns favicon :param e: exception :return: text/html with exception information """ return render_template('dtale/errors/500.html', page='', error=e, stacktrace=str(traceback.format_exc())), 500 def shutdown_server(): global ACTIVE_HOST, ACTIVE_PORT """ This function that checks if flask.request.environ['werkzeug.server.shutdown'] exists and if so, executes that function """ logger.info('Executing shutdown...') func = request.environ.get('werkzeug.server.shutdown') if func is None: raise RuntimeError('Not running with the Werkzeug Server') func() global_state.cleanup() ACTIVE_PORT = None ACTIVE_HOST = None @app.route('/shutdown') def shutdown(): """ :class:`flask:flask.Flask` route for initiating server shutdown :return: text/html with server shutdown message """ app.clear_reaper() shutdown_server() return 'Server shutting down...' @app.before_request def before_request(): """ Logic executed before each :attr:`flask:flask.request` :return: text/html with server shutdown message """ app.build_reaper() @app.route('/site-map') def site_map(): """ :class:`flask:flask.Flask` route listing all available flask endpoints :return: JSON of all flask enpoints [ [endpoint1, function path1], ..., [endpointN, function pathN] ] """ def has_no_empty_params(rule): defaults = rule.defaults or () arguments = rule.arguments or () return len(defaults) >= len(arguments) links = [] for rule in app.url_map.iter_rules(): # Filter out rules we can't navigate to in a browser # and rules that require parameters if "GET" in rule.methods and has_no_empty_params(rule): url = url_for(rule.endpoint, **(rule.defaults or {})) links.append((url, rule.endpoint)) return jsonify(links) @app.route('/version-info') def version_info(): """ :class:`flask:flask.Flask` route for retrieving version information about D-Tale :return: text/html version information """ _, version = retrieve_meta_info_and_version('dtale') return str(version) @app.route('/health') def health_check(): """ :class:`flask:flask.Flask` route for checking if D-Tale is up and running :return: text/html 'ok' """ return 'ok' with app.app_context(): from .dash_application import views as dash_views app = dash_views.add_dash(app) return app
def create_app(): """Flask application factory.""" app = Flask(__name__, static_folder="js") app.config["PROPAGATE_EXCEPTIONS"] = True app.config["TREE"] = os.getenv("TREE") app.config["GRAMPS_EXCLUDE_PRIVATE"] = Boolean( os.getenv("GRAMPS_EXCLUDE_PRIVATE")) app.config["GRAMPS_EXCLUDE_LIVING"] = Boolean( os.getenv("GRAMPS_EXCLUDE_LIVING")) app.config["TREE"] = os.getenv("TREE") if app.config["TREE"] is None or app.config["TREE"] == "": raise ValueError("You have to set the `TREE` environment variable.") app.config["GRAMPS_S3_BUCKET_NAME"] = os.getenv("GRAMPS_S3_BUCKET_NAME") app.config["PASSWORD"] = os.getenv("PASSWORD", "") app.config["GRAMPS_USER_DB_URI"] = os.getenv("GRAMPS_USER_DB_URI", "") app.config["GRAMPS_AUTH_PROVIDER"] = os.getenv("GRAMPS_AUTH_PROVIDER", "") if app.config["GRAMPS_AUTH_PROVIDER"] == "password": auth_provider = SingleUser(password=app.config["PASSWORD"]) elif app.config["GRAMPS_AUTH_PROVIDER"] == "none": auth_provider = None else: auth_provider = SQLAuth(db_uri=app.config["GRAMPS_USER_DB_URI"]) app.logger.setLevel(logging.INFO) app.logger.info("Opening family tree '{}'".format(app.config["TREE"])) limiter = Limiter(app, key_func=get_remote_address) # called once here in case Db's constructor raises Db(app.config["TREE"]) CORS(app) Compress(app) api = Api(app) cache = Cache(app, config={ "CACHE_TYPE": "filesystem", "CACHE_DIR": "appcache" }) app.config["JWT_TOKEN_LOCATION"] = ["headers", "query_string"] app.config["JWT_ACCESS_TOKEN_EXPIRES"] = datetime.timedelta(minutes=15) app.config["JWT_REFRESH_TOKEN_EXPIRES"] = datetime.timedelta(days=30) app.config["JWT_SECRET_KEY"] = get_jwt_secret_key() jwt = JWTManager(app) @app.route("/", methods=["GET", "POST"]) def send_js_index(): return send_from_directory(app.static_folder, "index.html") @app.route("/<path:path>", methods=["GET", "POST"]) def send_js(path): if path and os.path.exists(os.path.join(app.static_folder, path)): return send_from_directory(app.static_folder, path) else: return send_from_directory(app.static_folder, "index.html") @app.route("/api/login", methods=["POST"]) @limiter.limit("1/second") def login(): if app.config["GRAMPS_AUTH_PROVIDER"] == "none": ret = {"access_token": "1", "refresh_token": "1"} return jsonify(ret), 200 if not request.is_json: return jsonify({"msg": "Missing JSON in request"}), 400 username = request.json.get("username", None) password = request.json.get("password", None) from .auth import User if not auth_provider.authorized(username, password): return jsonify({"msg": "Wrong username or password"}), 401 ret = { "access_token": create_access_token(identity=username), "refresh_token": create_refresh_token(identity=username), } return jsonify(ret), 200 def jwt_required_ifauth(fn): """Check JWT unless authentication is disabled""" @wraps(fn) def wrapper(*args, **kwargs): if app.config["GRAMPS_AUTH_PROVIDER"] != "none": verify_jwt_in_request() return fn(*args, **kwargs) return wrapper def jwt_refresh_token_required_ifauth(fn): """Check JWT unless authentication is disabled""" @wraps(fn) def wrapper(*args, **kwargs): if app.config["GRAMPS_AUTH_PROVIDER"] != "none": verify_jwt_refresh_token_in_request() return fn(*args, **kwargs) return wrapper @app.route("/api/refresh", methods=["POST"]) @jwt_refresh_token_required_ifauth def refresh(): if app.config["GRAMPS_AUTH_PROVIDER"] == "none": ret = {"access_token": "1"} return jsonify(ret), 200 current_user = get_jwt_identity() ret = {"access_token": create_access_token(identity=current_user)} return jsonify(ret), 200 parser = reqparse.RequestParser() parser.add_argument("strings", type=str) parser.add_argument("fmt", type=str) @app.before_request def before_request(): if not get_db().dbstate.is_open(): get_db().open() app.teardown_appcontext(close_db) class ProtectedResource(Resource): method_decorators = [jwt_required_ifauth] class People(ProtectedResource): @cache.cached() def get(self): return get_people(get_db()) class Families(ProtectedResource): @cache.cached() def get(self): return get_families(get_db()) class Events(ProtectedResource): @cache.cached() def get(self): return get_events(get_db()) class Places(ProtectedResource): @cache.cached() def get(self): return get_places(get_db()) class Citations(ProtectedResource): @cache.cached() def get(self): return get_citations(get_db()) class Sources(ProtectedResource): @cache.cached() def get(self): return get_sources(get_db()) class Repositories(ProtectedResource): @cache.cached() def get(self): return get_repositories(get_db()) class MediaObjects(ProtectedResource): @cache.cached() def get(self): return get_media(get_db()) class DbInfo(ProtectedResource): @cache.cached() def get(self): return get_db_info(get_db()) class FullTree(ProtectedResource): @cache.cached() def get(self): return { "people": get_people(get_db()), "families": get_families(get_db()), "events": get_events(get_db()), "places": get_places(get_db()), "citations": get_citations(get_db()), "sources": get_sources(get_db()), "repositories": get_repositories(get_db()), "media": get_media(get_db()), "dbinfo": get_db_info(get_db()), } class Translate(Resource): @cache.cached() def get(self): args = parser.parse_args() try: strings = json.loads(args["strings"]) lang = args.get("lang") except (json.decoder.JSONDecodeError, TypeError, ValueError) as e: return {"error": str(e)} return {"data": get_translation(strings, lang=lang)} class Languages(Resource): @cache.cached() def get(self): return {"data": get_languages()} class Note(ProtectedResource): @cache.cached(query_string=True) def get(self, gramps_id): args = parser.parse_args() fmt = args.get("fmt") or "html" return get_note(get_db(), gramps_id, fmt=fmt) api.add_resource(People, "/api/people") api.add_resource(Families, "/api/families") api.add_resource(Events, "/api/events") api.add_resource(Places, "/api/places") api.add_resource(Citations, "/api/citations") api.add_resource(Sources, "/api/sources") api.add_resource(MediaObjects, "/api/mediaobjects") api.add_resource(Repositories, "/api/repositories") api.add_resource(Translate, "/api/translate") api.add_resource(Languages, "/api/languages") api.add_resource(DbInfo, "/api/dbinfo") api.add_resource(FullTree, "/api/tree") api.add_resource(Note, "/api/note/<string:gramps_id>") def get_media_handler(handle): info = get_media_info(get_db(), handle) if app.config["GRAMPS_S3_BUCKET_NAME"]: return S3Handler(handle, info, bucket_name=app.config["GRAMPS_S3_BUCKET_NAME"]) else: return FileHandler(handle, info) @app.route("/api/media/<string:handle>") @jwt_required_ifauth def show_image(handle): handler = get_media_handler(handle) return handler.send_file() @app.route("/api/thumbnail/<string:handle>/<int:size>") @jwt_required_ifauth @cache.cached() def show_thumbnail_square(handle, size): handler = get_media_handler(handle) return handler.send_thumbnail_square(size) @app.route( "/api/thumbnail/<string:handle>/<int:size>/<int:x1>/<int:y1>/<int:x2>/<int:y2>" ) @jwt_required_ifauth @cache.cached() def show_thumbnail_square_cropped(handle, size, x1, y1, x2, y2): handler = get_media_handler(handle) return handler.send_thumbnail_square_cropped(size, x1, y1, x2, y2) return app
import os from flask import Flask, request, jsonify, abort, make_response, redirect, url_for, send_from_directory, send_file from flask_restful import Api, Resource, reqparse from flask_httpauth import HTTPBasicAuth from flask_compress import Compress from util import Database from werkzeug.utils import secure_filename from requests.auth import HTTPDigestAuth import requests import hashlib from PIL import Image import io app = Flask(__name__, static_url_path="") api = Api(app) Compress(app) auth = HTTPBasicAuth() db = Database() @auth.get_password def get_password(username): return db.getPassword(username) @auth.error_handler def unauthorized(): # return 403 instead of 401 to prevent default browser dialog return make_response(jsonify({'message': 'Unauthorized access'}), 403)
def create_app(test_config=None): log = logging.getLogger(__name__) # a = connexion.FlaskApp(__name__, specification_dir='v1/spec/') # a.add_api('v1.yaml', arguments={ # "tokeninfo_url": discovery["introspection_endpoint"], # "authorization_url": discovery["authorization_endpoint"], # "accesstoken_url": discovery["token_endpoint"] # }) # app = a.app app = Flask(__name__) conf = config.Config() if test_config is None: app.config.update(conf.data) else: # load the test config if passed in app.config.update(conf.data) app.config.update(test_config) ##Routes## v1.Register(app) v2.Register(app) Compress(app) @app.before_request def before_request(): from timeit import default_timer as timer g.request_start_time = timer() g.request_time = lambda: "%s" % (timer() - g.request_start_time) resp = Response() resp.headers['Content-Type'] = ["application/json"] @app.after_request def after_request(response): set_cors_headers_on_response(response) log.debug('Rendered in %ss', g.request_time()) return response @app.errorhandler(HTTPStatus.NOT_FOUND) def not_found(param): content = jsonify({"error": "Not Found", "code": HTTPStatus.NOT_FOUND}) return make_response(content, HTTPStatus.NOT_FOUND) @app.errorhandler(HTTPStatus.INTERNAL_SERVER_ERROR) def internal_server_error(error): log.error("Internal Error %s - %s" % (request.remote_addr, str(error))) content = jsonify({ "error": "{error}", "code": HTTPStatus.INTERNAL_SERVER_ERROR }) log.error(request.get_data()) log.error(request.form) log.error(request.headers) return make_response(content, HTTPStatus.INTERNAL_SERVER_ERROR) @app.errorhandler(HTTPStatus.BAD_REQUEST) def bad_request_error(error): log.error("Bad Request %s - %s" % (request.remote_addr, str(error))) content = jsonify({ "error": "Bad Request", "code": HTTPStatus.BAD_REQUEST }) log.error(request.get_data()) log.error(request.form) log.error(request.headers) return make_response(content, HTTPStatus.BAD_REQUEST) @app.errorhandler(JoseError) def forbidden(error): log.error("Denied access %s - %s" % (request.remote_addr, str(error))) content = jsonify({"error": "Invalid Token"}) return make_response(content, HTTPStatus.UNAUTHORIZED) @app.errorhandler(ExpiredTokenError) def expired_token(error): content = jsonify({"error": "Token Expired"}) return make_response(content, HTTPStatus.UNAUTHORIZED) @app.route('/', methods=['GET'], strict_slashes=False) def index(): """ Returns a list of valid API version endpoints :return: JSON of valid API version endpoints """ return jsonify([url_for(".v1.get_status", _external=True)]) @app.route('/version', methods=['GET'], strict_slashes=False) def version(): """ Get the current version of the api """ from os import environ hash = "" if environ.get('GITHASH') is not None: hash = environ.get("GITHASH") # import pkg_resources # part of setuptools # print(pkg_resources) # v = pkg_resources.get_distribution("gwa-kong").version v = "" version = v if hash != "": version += "-" + hash responseObj = {"v": v, "hash": hash, "version": version} return jsonify(responseObj) return app