Use waitress to serve the webapp.

master
Pacman Ghost 2 years ago
parent 2fc57b88ac
commit 2946b2d10f
  1. 1
      requirements.txt
  2. 15
      vasl_templates/main.py
  3. 3
      vasl_templates/webapp/__init__.py
  4. 39
      vasl_templates/webapp/run_server.py
  5. 11
      vasl_templates/webapp/vo_notes.py

@ -4,4 +4,5 @@ flask==2.0.1
pyyaml==5.4.1
pillow==8.3.2
selenium==3.141.0
waitress==2.0.0
click==8.0.1

@ -143,11 +143,18 @@ def _do_main( template_pack, default_scenario, remote_debugging, debug ): #pylin
return 2
# start the webapp server
port = webapp.config[ "FLASK_PORT_NO" ]
flask_port = webapp.config[ "FLASK_PORT_NO" ]
def webapp_thread():
"""Run the webapp server."""
try:
webapp.run( host="localhost", port=port, use_reloader=False )
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 = webapp.config.get( "WAITRESS_THREADS", 8 )
waitress.serve( webapp,
host="localhost", port=flask_port,
threads=nthreads
)
except Exception as ex: #pylint: disable=broad-except
logging.critical( "WEBAPP SERVER EXCEPTION: %s", ex )
logging.critical( traceback.format_exc() )
@ -172,7 +179,7 @@ def _do_main( template_pack, default_scenario, remote_debugging, debug ): #pylin
if _webapp_error:
break
try:
url = "http://localhost:{}/ping".format( port )
url = "http://localhost:{}/ping".format( flask_port )
with urllib.request.urlopen( url ) as resp:
resp_data = resp.read().decode( "utf-8" )
# we got a response - figure out if we connected to ourself or another instance
@ -210,7 +217,7 @@ def _do_main( template_pack, default_scenario, remote_debugging, debug ): #pylin
disable_browser = webapp.config.get( "DISABLE_WEBENGINEVIEW" )
# run the application
url = "http://localhost:{}".format( port )
url = "http://localhost:{}".format( flask_port )
from vasl_templates.main_window import MainWindow #pylint: disable=cyclic-import
main_window = MainWindow( url, disable_browser )
main_window.show()

@ -185,9 +185,6 @@ def _on_sigint( signum, stack ): #pylint: disable=unused-argument
# ---------------------------------------------------------------------
# disable the Flask startup banner
flask.cli.show_server_banner = lambda *args: None
# initialize Flask
app = Flask( __name__ )
if _is_flask_child_process():

@ -20,23 +20,23 @@ def main( bind_addr, force_init_delay, flask_debug ):
# initialize
from vasl_templates.webapp import app
port = None
flask_port = None
if bind_addr:
words = bind_addr.split( ":" )
host = words[0]
flask_host = words[0]
if len(words) > 1:
port = words[1]
flask_port = words[1]
else:
host = app.config.get( "FLASK_HOST", "localhost" )
if not port:
port = app.config.get( "FLASK_PORT_NO" )
flask_host = app.config.get( "FLASK_HOST", "localhost" )
if not flask_port:
flask_port = app.config.get( "FLASK_PORT_NO" )
if not flask_debug:
flask_debug = app.config.get( "FLASK_DEBUG", False )
# validate the configuration
if not host:
if not flask_host:
raise RuntimeError( "The server host was not set." )
if not port:
if not flask_port:
raise RuntimeError( "The server port was not set." )
# monitor extra files for changes
@ -61,15 +61,30 @@ def main( bind_addr, force_init_delay, flask_debug ):
# it's useful to send a request (any request), since this will trigger "first request" initialization
# (in particular, starting the download thread).
time.sleep( force_init_delay )
url = "http://{}:{}/ping".format( host, port )
url = "http://{}:{}/ping".format( flask_host, flask_port )
with urllib.request.urlopen( url ) as resp:
_ = resp.read()
threading.Thread( target=_start_server, daemon=True ).start()
# run the server
app.run( host=host, port=port, debug=flask_debug,
extra_files = extra_files
)
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
)
# ---------------------------------------------------------------------

@ -319,7 +319,16 @@ def get_vo_note( vo_type, nat, key ):
# we have a cached copy - compare the timestamps of the source HTML and the cached image
# NOTE: We should also check the HTML for any associated images, and check their timestamps, as well.
if os.path.getmtime( cached_fname ) >= os.path.getmtime( vo_note["filename"] ):
resp = send_file( cached_fname )
# FUDGE! We get errors on Windows when using waitress to serve the webapp, when the tests end
# and ControlTestsServicer tries to clean up its TemporaryDirectory ("not a directory" errors
# for something that is a file :-/). TemporaryDirectory added a ignore_cleanup_errors argument
# in Python 3.10, but for now, we work-around this problem by reading the file ourself and
# serving it from memory.
with open( cached_fname, "rb" ) as fp:
buf = fp.read()
resp = send_file( io.BytesIO( buf ),
download_name = os.path.basename( cached_fname )
)
resp.headers[ "X-WasCached" ] = 1
return resp
with WebDriver.get_instance( "vo_note" ) as webdriver:

Loading…
Cancel
Save