#!/usr/bin/env python3 """ Run the Flask backend server. """ import os import threading import urllib.request import time import glob from flask import url_for # --------------------------------------------------------------------- # monitor extra files for changes base_dir = os.path.abspath( os.path.join( os.path.dirname(__file__), "asl_articles" ) ) extra_files = [] for fspec in ["config","static","templates"] : fspec = os.path.join( base_dir, fspec ) if os.path.isdir( fspec ): files = [ os.path.join(fspec,f) for f in os.listdir(fspec) ] files = [ f for f in files if os.path.isfile(f) and os.path.splitext(f)[1] not in [".swp"] ] else: files = glob.glob( fspec ) extra_files.extend( files ) # initialize from asl_articles import app flask_host = app.config.get( "FLASK_HOST", "localhost" ) flask_port = app.config.get( "FLASK_PORT_NO", 5000 ) flask_debug = app.config.get( "FLASK_DEBUG", False ) # FUDGE! Startup can take some time (e.g. because we have to build the search index over a large database), # and since we do that on first request, it's annoying to have started the server up, if we don't do that # first request immediately, the server sits there idling, when it could be doing that startup initialization, # and we then have to wait when we eventually do that first request. # We fix this by doing the first request ourself here (something harmless). def _force_init(): time.sleep( 5 ) try: # figure out the URL for the request we're going to make with app.test_request_context() as req: url = url_for( "ping" ) host = req.request.host_url if host.endswith( "/" ): host = host[:-1] url = "{}:{}{}".format( host, flask_port, url ) # make the request with urllib.request.urlopen( url ) as resp: _ = resp.read() except Exception as ex: #pylint: disable=broad-except print( "WARNING: Startup ping failed: {}".format( ex ) ) threading.Thread( target=_force_init ).start() # run the server if flask_debug: # NOTE: It's useful to run the webapp using the Flask development server, since it will # automatically reload itself when the source files change. app.run( host=flask_host, port=flask_port, debug=flask_debug, extra_files=extra_files ) else: import waitress # FUDGE! Browsers tend to send a max. of 6-8 concurrent requests per server, so we increase # the number of worker threads to avoid task queue warnings :-/ nthreads = app.config.get( "WAITRESS_THREADS", 8 ) waitress.serve( app, host=flask_host, port=flask_port, threads=nthreads )