def start_app(title, base_path, debug: bool, host, port, reloader=False, # pylint: disable=too-many-arguments unminified=False): global app, dash_app, dispatcher try: lang = locale.getlocale()[0].split("_")[0] locale.setlocale(locale.LC_TIME, ".".join(locale.getlocale())) # make sure LC_TIME is set locale_url = [f"https://cdn.plot.ly/plotly-locale-{lang}-latest.js"] except (IndexError, locale.Error): locale_url = None logger.warning("Can't get language") if unminified: locale_url = ["assets/plotly-with-meta.js"] app = Flask(__name__) app.wsgi_app = ProxyFix(app.wsgi_app) app.config["DEBUG"] = debug if base_path == "/": application = DispatcherMiddleware(app) requests_pathname_prefix = None else: application = DispatcherMiddleware(Flask('dummy_app'), {base_path: app}) requests_pathname_prefix = base_path + "/" dash_app = dash.Dash(external_stylesheets=[dbc.themes.BOOTSTRAP], external_scripts=locale_url, title=title, server=app, requests_pathname_prefix=requests_pathname_prefix) dash_app.enable_dev_tools(reloader) # keep this line import web.views # pylint: disable=unused-import,import-outside-toplevel return run_simple(host, port, application, use_reloader=reloader, use_debugger=debug)
def start_app(title, base_path, debug: bool, host, port): global app, dash_app, dispatcher try: lang = locale.getlocale()[0].split("_")[0] locale_url = [f"https://cdn.plot.ly/plotly-locale-{lang}-latest.js"] except: locale_url = None logger.warn("Can't get language") app = Flask(__name__) app.config["DEBUG"] = debug if base_path == "/": application = DispatcherMiddleware(app) requests_pathname_prefix = None else: application = DispatcherMiddleware(Flask('dummy_app'), {base_path: app}) requests_pathname_prefix = base_path + "/" dash_app = dash.Dash(external_stylesheets=[dbc.themes.BOOTSTRAP], external_scripts=locale_url, title=title, server=app, requests_pathname_prefix=requests_pathname_prefix) # keep this line import web.callback return run_simple(host, port, application, use_reloader=False, use_debugger=debug)
def config_flask( title, base_path, debug: bool, host, port, reloader=False, # pylint: disable=too-many-arguments unminified=False, view="web.view.views"): global app, dash_app reload_view = app is not None app = Flask(__name__) app.logger.addHandler(file_handler) try: lang = locale.getlocale()[0].split("_")[0] locale.setlocale(locale.LC_TIME, ".".join( locale.getlocale())) # make sure LC_TIME is set if lang != "en": locale_url = [ f"https://cdn.plot.ly/plotly-locale-{lang}-latest.js" ] else: locale_url = None except (IndexError, locale.Error): locale_url = None logger.warning("Can't get language") if unminified: locale_url = ["assets/plotly-with-meta.js"] app.config["DEBUG"] = debug if base_path == "/": application = DispatcherMiddleware(app) requests_pathname_prefix = None else: application = DispatcherMiddleware(Flask('dummy_app'), {base_path: app}) requests_pathname_prefix = base_path + "/" dash_app = DashCustom(external_stylesheets=[dbc.themes.BOOTSTRAP], external_scripts=locale_url, title=title, server=app, requests_pathname_prefix=requests_pathname_prefix, suppress_callback_exceptions=True, serve_locally=False) dash_app.enable_dev_tools(debug) app.wsgi_app = MyProxyFix(dash_app) # keep this line importlib.import_module(view) if reload_view: importlib.reload(view) return { "hostname": host, "port": port, "application": application, "use_reloader": reloader, "use_debugger": debug }
def __call__(self, environ, start_response): return DispatcherMiddleware( NotFound, { '/messageexchange': self.authenticated( DispatcherMiddleware( self.handshake, { '/inbox': self.inbox, '/count': self.count, '/outbox': self.outbox, '/update': self.update })), '/_fake_ndr': self._fake_ndr })(environ, start_response)
def main(): sys.setrecursionlimit(2**15) defaults = getDefaults() env = parseEnv() args = parseArgs(sys.argv[1:]) args = {**defaults, **env, **args} application = create_app(args) # Set the basepath if args['basepath']: logger.info( "Configure DispatcherMiddleware for basepath \"{}\"".format( args['basepath'])) def simple(env, resp): """A simple WSGI application. See also: http://werkzeug.pocoo.org/docs/0.14/middlewares/ """ resp('200 OK', [('Content-Type', 'text/plain')]) application.wsgi_app = DispatcherMiddleware( simple, {args['basepath']: application.wsgi_app}) application.run(debug=args['flask_debug'], use_reloader=False, host=args['host'], port=args['port'])
def create_app(): public_app = create_public_app() restricted_app = create_restricted_app() application = DispatcherMiddleware(public_app, {"/restricted": restricted_app}) return application
def test_dispatcher(): def null_application(environ, start_response): start_response("404 NOT FOUND", [("Content-Type", "text/plain")]) yield b"NOT FOUND" def dummy_application(environ, start_response): start_response("200 OK", [("Content-Type", "text/plain")]) yield _to_bytes(environ["SCRIPT_NAME"]) app = DispatcherMiddleware( null_application, { "/test1": dummy_application, "/test2/very": dummy_application }, ) tests = { "/test1": ("/test1", "/test1/asfd", "/test1/very"), "/test2/very": ("/test2/very", "/test2/very/long/path/after/script/name"), } for name, urls in tests.items(): for p in urls: environ = create_environ(p) app_iter, status, headers = run_wsgi_app(app, environ) assert status == "200 OK" assert b"".join(app_iter).strip() == _to_bytes(name) app_iter, status, headers = run_wsgi_app(app, create_environ("/missing")) assert status == "404 NOT FOUND" assert b"".join(app_iter).strip() == b"NOT FOUND"
def _start_web(port, sentry_dsn=None, blueprints=None): """ Starts a Flask app with optional error logging and blueprint registration. Args: port - str/int - port on which management application should listen for HTTP traffic. sentry_dsn - str - Sentry DSN for error logging. blueprints - list(flask.Blueprint)- blueprints to register. """ # Set up management application app = Flask(__name__) app.register_blueprint(lifecycle_blueprint) if blueprints: for blueprint in blueprints: app.register_blueprint(blueprint) if sentry_dsn: app = setup_sentry_wsgi(app, sentry_dsn) app_dispatch = DispatcherMiddleware(app, {'/metrics': make_wsgi_app()}) http_server = WSGIServer(('0.0.0.0', int(port)), app_dispatch) try: http_server.serve_forever() except KeyboardInterrupt: logger.info('Keyboard interrupt, executing shutdown hooks...') execute_shutdown_handlers()
def create_app(config_class=Config) -> Flask: """ Application factory. :param config_class: :return: Flask """ app = Flask(__name__) app.config.from_object(config_class) db.init_app(app) ma.init_app(app) # Order matters: Initialize SQLAlchemy before Marshmallow # In order to make sure that all the routes are prefixed with # APPLICATION_ROOT, we need to do some extra setup here. app.wsgi_app = DispatcherMiddleware( app=Flask('dummy_app'), mounts={f"/{app.config['APPLICATION_ROOT']}": app.wsgi_app}) from .entrance import entrance_bp app.register_blueprint(entrance_bp) # Authentication-related stuff from .utils import verify_password_or_access_token from .api import api_bp app.register_blueprint(api_bp) # Create and initialize the database db.create_all(app=app) return app
def cached_app(config=None, session=None, testing=False): global app, appbuilder if not app or not appbuilder: base_url = urlparse(conf.get('webserver', 'base_url'))[2] if not base_url or base_url == '/': base_url = "" app, _ = create_app(config, session, testing) app = DispatcherMiddleware(root_app, {base_url: app}) if conf.getboolean('webserver', 'ENABLE_PROXY_FIX'): app = ProxyFix(app, x_for=conf.getint("webserver", "PROXY_FIX_X_FOR", fallback=1), x_proto=conf.getint("webserver", "PROXY_FIX_X_PROTO", fallback=1), x_host=conf.getint("webserver", "PROXY_FIX_X_HOST", fallback=1), x_port=conf.getint("webserver", "PROXY_FIX_X_PORT", fallback=1), x_prefix=conf.getint("webserver", "PROXY_FIX_X_PREFIX", fallback=1)) return app
def create_app(): app = Flask(__name__) if os.environ.get('SENTRY_DSN'): sentry_sdk.init(dsn=os.environ.get('SENTRY_DSN'), integrations=[FlaskIntegration()], environment=os.environ.get('SENTRY_ENV', 'production')) app.wsgi_app = DispatcherMiddleware(app.wsgi_app, {'/cbeci': app}) from blueprints import charts, contribute, download, text_pages, reports, sponsors, data app.register_blueprint(charts.bp, url_prefix='/api/charts') app.register_blueprint(text_pages.bp, url_prefix='/api/text_pages') app.register_blueprint(reports.bp, url_prefix='/api/reports') app.register_blueprint(sponsors.bp, url_prefix='/api/sponsors') app.register_blueprint(contribute.bp, url_prefix='/api/contribute') app.register_blueprint(download.bp, url_prefix='/api/<string:version>/download') app.register_blueprint(data.bp, url_prefix='/api/data') swaggerui_bp = get_swaggerui_blueprint('/cbeci' + SWAGGER_URL, '/cbeci' + SWAGGER_SPEC_URL, config={'app_name': "Cbeci API"}) app.register_blueprint(swaggerui_bp, url_prefix=SWAGGER_URL) doc_bp = get_swaggerui_blueprint('/cbeci/api/docs', '/cbeci/api/docs/spec/index.yaml', blueprint_name='docs') app.register_blueprint(doc_bp, url_prefix='/api/docs') return app
def _setup_prometheus(app): # This environment variable MUST be declared before importing the # prometheus modules (or unit tests fail) # More details on this awkwardness: https://github.com/prometheus/client_python/issues/250 os.environ["prometheus_multiproc_dir"] = PROMETHEUS_TMP_COUNTER_DIR.name from prometheus_client import ( CollectorRegistry, multiprocess, make_wsgi_app, ) from prometheus_flask_exporter import Counter from prometheus_flask_exporter.multiprocess import ( UWsgiPrometheusMetrics, ) app.prometheus_registry = CollectorRegistry() multiprocess.MultiProcessCollector(app.prometheus_registry) UWsgiPrometheusMetrics(app) # Add prometheus wsgi middleware to route /metrics requests app.wsgi_app = DispatcherMiddleware( app.wsgi_app, {"/metrics": make_wsgi_app(registry=app.prometheus_registry)}) # set up counters app.prometheus_counters["pre_signed_url_req"] = Counter( "pre_signed_url_req", "tracking presigned url requests", ["requested_protocol"], )
def apply_middlewares(flask_app: Flask): # Apply DispatcherMiddleware base_url = urlparse(conf.get('webserver', 'base_url'))[2] if not base_url or base_url == '/': base_url = "" if base_url: flask_app.wsgi_app = DispatcherMiddleware( # type: ignore root_app, mounts={base_url: flask_app.wsgi_app}) # Apply ProxyFix middleware if conf.getboolean('webserver', 'ENABLE_PROXY_FIX'): flask_app.wsgi_app = ProxyFix( # type: ignore flask_app.wsgi_app, x_for=conf.getint("webserver", "PROXY_FIX_X_FOR", fallback=1), x_proto=conf.getint("webserver", "PROXY_FIX_X_PROTO", fallback=1), x_host=conf.getint("webserver", "PROXY_FIX_X_HOST", fallback=1), x_port=conf.getint("webserver", "PROXY_FIX_X_PORT", fallback=1), x_prefix=conf.getint("webserver", "PROXY_FIX_X_PREFIX", fallback=1))
def __init__( self, app, secret, exempt=[], *, prefix="/auth", login_methods=("POST", ), ): auth_api = API() auth_api.route("/login/", methods=login_methods, func=functools.partial(self._login)) auth_api.route("/renew/", methods=("POST", ), func=functools.partial(self._renew)) self.app = DispatcherMiddleware(app, {prefix: auth_api}) self.exempt = (exempt + [(method, prefix + "/login/") for method in login_methods] + [("POST", prefix + "/renew/")]) self.secret = secret
def create_dispatcher() -> DispatcherMiddleware: """ App factory for dispatcher middleware managing multiple WSGI apps """ main_app = create_app(config=CONFIG) return DispatcherMiddleware(main_app.wsgi_app, {"/metrics": make_wsgi_app()})
def load_apps(app: Flask): """ Load all applications and combine them together using ``DispatcherMiddleware``. """ apps: List[Dict] = app.config.get("APPS", []) mounts = {} for a in apps: if not isinstance(a, dict): a = {"name": a} name = a["name"] path = a.get("path", "/" + name) help = a.get("help", "") yourapp: Flask = import_attr(name + ".wsgi.app") @click.command(name) def cli(): build_repl(yourapp) cli.help = help app.cli.add_command(cli, name) mounts[path] = yourapp app.wsgi_app = DispatcherMiddleware(app.wsgi_app, mounts)
def run_forever(self): host = self.args.host port = self.args.port addr = (host, port) display_host = host if host == '0.0.0.0': display_host = 'localhost' logger.info('Serving RPC server at {}:{}, pid={}'.format( *addr, os.getpid())) logger.info('Supported methods: {}'.format( sorted(self.task_manager.methods()))) logger.info('Send requests to http://{}:{}/jsonrpc'.format( display_host, port)) app = DispatcherMiddleware(self.handle_request, { '/jsonrpc': self.handle_jsonrpc_request, }) # we have to run in threaded mode if we want to share subprocess # handles, which is the easiest way to implement `kill` (it makes # `ps` easier as well). The alternative involves tracking # metadata+state in a multiprocessing.Manager, adds polling the # manager to the request task handler and in general gets messy # fast. run_simple( host, port, app, threaded=not self.task_manager.single_threaded(), )
def loader(app: Flask): """ Load all applications and combine them together using ``DispatcherMiddleware``. """ apps: List[Dict] = app.config.get("APPS", []) mounts = {} for a in apps: if not isinstance(a, dict): a = {"name": a} name = a["name"] path = a.get("path", "/" + name) help = a.get("help", f"{name.title()} App") yourapp: Flask = import_attr(name + ".wsgi.app") @click.command(name, context_settings=dict(ignore_unknown_options=True)) @click.option("-r", "--repl", is_flag=True, help="Activates REPL mode.") @click.argument("args", nargs=-1, type=click.UNPROCESSED) def cli(repl, args): os.environ["FLASK_APP"] = yourapp.import_name if repl: build_repl(yourapp) else: subprocess.call(["flask"] + list(args)) cli.help = help app.cli.add_command(cli) mounts[path] = yourapp app.wsgi_app = DispatcherMiddleware(app.wsgi_app, mounts)
def klangbecken_api( secret, data_dir, player_socket, *, upload_analyzers=DEFAULT_UPLOAD_ANALYZERS, update_analyzers=DEFAULT_UPDATE_ANALYZERS, processors=DEFAULT_PROCESSORS, ): """Construct the Klangbecken API WSGI application. This combines the two APIs for the playlists and the player with the authorization middleware. """ playlist = playlist_api(data_dir, upload_analyzers, update_analyzers, processors) player = player_api(player_socket, data_dir) app = API() app.GET("/")(lambda request: f"Welcome to the Klangbecken API version {__version__}") app = DispatcherMiddleware(app, {"/playlist": playlist, "/player": player}) auth_exempts = [ ("GET", "/player/"), ("GET", "/player/queue/"), ] app = JWTAuthorizationMiddleware(app, secret, exempt=auth_exempts) return app
def main(): logging.basicConfig( format='%(message)s', stream=sys.stdout, level=logging.DEBUG ) structlog.configure( processors=[ structlog.stdlib.add_log_level, structlog.stdlib.add_logger_name, structlog.processors.KeyValueRenderer( key_order=["event", "request_id"] ) ], context_class=structlog.threadlocal.wrap_dict(dict), logger_factory=structlog.stdlib.LoggerFactory() ) app = create_app() # allows us to view metrics on /metrics dispatcher = DispatcherMiddleware(app.wsgi_app, {'/metrics': make_wsgi_app()}) run_simple( 'localhost', 5000, dispatcher, use_reloader=True, )
def __init__( self, app, secret, exempt=[], *, prefix="/auth", login_methods=("POST", ), ): auth_api = API() auth_api.route("/login/", methods=login_methods, func=functools.partial(self._login)) auth_api.route("/renew/", methods=("POST", ), func=functools.partial(self._renew)) self.app = DispatcherMiddleware(app, {prefix: auth_api}) self.exempt = (exempt + [(method, prefix + "/login/") for method in login_methods] + [("POST", prefix + "/renew/")]) # remove consecutive repetitions secret = "".join(c for c, it in itertools.groupby(secret)) if len(secret) < 10: raise ValueError(f"Secret string to short: {len(secret)} < 10") self.secret = secret
def _make_indico_dispatcher(wsgi_app, path): path = path.rstrip('/') if not path: # Nothing to dispatch return wsgi_app else: return DispatcherMiddleware(NotFound(), {path: wsgi_app})
def monitor(app, path="/metrics", http_server=False, port=9090, addr=""): FLASK_REQUEST_COUNT = Counter( "{}_flask_request_count".format(app.name), "{} - Flask Request Count".format(app.name), ["method", "endpoint", "http_status"], ) FLASK_REQUEST_LATENCY = Histogram( "{}_flask_request_latency_seconds".format(app.name), "{} - Flask Request Latency".format(app.name), ["method", "endpoint"], ) def before_request(): request.start_time = time.time() def after_request(response): request_latency = time.time() - request.start_time FLASK_REQUEST_LATENCY.labels(request.method, request.path).observe(request_latency) FLASK_REQUEST_COUNT.labels(request.method, request.path, response.status_code).inc() return response app.before_request(before_request) app.after_request(after_request) if http_server: start_http_server(port, addr) else: prometheus_app = make_wsgi_app() return DispatcherMiddleware(app.wsgi_app, {path: prometheus_app})
def main() -> None: args = parse_arguments() if args.print_version: print('{}, version {}'.format(os.path.basename(sys.argv[0]), __version__)) sys.exit(0) elif args.print_default_config: Config.write_default_config(sys.stdout) sys.exit(0) config.read_config(args.config_filename) app = setup_app() if config.debug: if config.server_prefix != '/': app = DispatcherMiddleware( Flask('debugging_frontend'), {config.server_prefix: app}) # type: ignore run_simple(config.socket_host, config.socket_port, app, use_debugger=True, use_reloader=True) # type: ignore else: wsgi_server = wsgi.Server( (config.socket_host, config.socket_port), wsgi.PathInfoDispatcher({config.server_prefix: app})) wsgi_server.safe_start()
def create_app(): app = flask.Flask(__name__) app.add_url_rule("/", "ping", app_ping, methods=["GET"]) app.add_url_rule("/", "refresh_tasks", app_refresh_tasks, methods=["POST"]) app.add_url_rule( "/feed_update_callback", "feed_update_callback", app_feed_update_callback, methods=["POST"], ) # Add prometheus wsgi middleware to route /metrics requests app.wsgi_app = DispatcherMiddleware( app.wsgi_app, {"/metrics": prometheus.make_wsgi_app()}) logger.setLevel(logging.INFO) handler = logging.StreamHandler() logger.addHandler(handler) formatter = logging.Formatter( "%(asctime)s TS %(levelname)-5s [%(module)s] %(message)s") handler.setFormatter(formatter) logger.info("Launching scheduler") scheduler.start() feed_auto_update_registry.initialize() transiter_registry.initialize() metrics_populator.refresh() logger.info("Launching HTTP server") return app
def main( filenames: Tuple[str], port: int, host: str, prefix: str, incognito: bool, debug: bool, profile: bool, profile_dir: str, ) -> None: # pragma: no cover """Start Fava for FILENAMES on http://<host>:<port>. If the `BEANCOUNT_FILE` environment variable is set, Fava will use the files (space-delimited) specified there in addition to FILENAMES. Note you can also specify command-line options via environment variables. For example, `--host=0.0.0.0` is equivalent to setting the environment variable `FAVA_HOST=0.0.0.0`. """ if profile: debug = True env_filename = os.environ.get("BEANCOUNT_FILE") all_filenames = (filenames + tuple(env_filename.split()) if env_filename else filenames) if not all_filenames: raise click.UsageError("No file specified") app.config["BEANCOUNT_FILES"] = all_filenames app.config["INCOGNITO"] = incognito if prefix: app.wsgi_app = DispatcherMiddleware( # type: ignore simple_wsgi, {prefix: app.wsgi_app}) if not debug: server = Server((host, port), app) print(f"Running Fava on http://{host}:{port}") server.safe_start() else: if profile: app.config["PROFILE"] = True app.wsgi_app = ProfilerMiddleware( # type: ignore app.wsgi_app, restrictions=(30, ), profile_dir=profile_dir if profile_dir else None, ) app.jinja_env.auto_reload = True try: app.run(host, port, debug) except OSError as error: if error.errno == errno.EADDRINUSE: raise click.UsageError( "Can not start webserver because the port is already in " "use. Please choose another port with the '-p' option.") raise
def client(): app = Flask(__name__) app.wsgi_app = DispatcherMiddleware(app.wsgi_app, {"/health": util.health}) client = app.test_client() yield client
def _server_thread(self): log.info(f'Starting webserver on {self.bind_hostname}:{self.bind_port}') app = self._handler app = DispatcherMiddleware(app, self.mount_map) app = WSGILogger(app) self.server = WSGIServer((self.bind_hostname, self.bind_port), app) self.server.stats['Enabled'] = True self.server.start()
def sentry_exporter(): sentry = SentryAPI(BASE_URL, AUTH_TOKEN) log.info("exporter: cleaning registry collectors...") clean_registry() REGISTRY.register( SentryCollector(sentry, ORG_SLUG, get_metric_config(), PROJECTS_SLUG)) exporter = DispatcherMiddleware(app.wsgi_app, {"/metrics": make_wsgi_app()}) return exporter
def cached_app(config=None, testing=False): global app if not app: base_url = urlparse(configuration.conf.get('webserver', 'base_url'))[2] if not base_url or base_url == '/': base_url = "" app = create_app(config, testing) app = DispatcherMiddleware(root_app, {base_url: app}) return app