Switch to bokeh wrapper for app serving
This commit is contained in:
parent
3458a6c755
commit
dc397062ad
17
pyzebra/app/app_hooks.py
Normal file
17
pyzebra/app/app_hooks.py
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
import logging
|
||||||
|
import sys
|
||||||
|
from io import StringIO
|
||||||
|
|
||||||
|
|
||||||
|
def on_server_loaded(_server_context):
|
||||||
|
formatter = logging.Formatter(
|
||||||
|
fmt="%(asctime)s %(levelname)s: %(message)s", datefmt="%Y-%m-%d %H:%M:%S"
|
||||||
|
)
|
||||||
|
|
||||||
|
sys.stdout = StringIO()
|
||||||
|
|
||||||
|
bokeh_handler = logging.StreamHandler(StringIO())
|
||||||
|
bokeh_handler.setFormatter(formatter)
|
||||||
|
bokeh_logger = logging.getLogger("bokeh")
|
||||||
|
bokeh_logger.setLevel(logging.WARNING)
|
||||||
|
bokeh_logger.addHandler(bokeh_handler)
|
@ -1,77 +1,11 @@
|
|||||||
import argparse
|
|
||||||
import logging
|
|
||||||
import os
|
import os
|
||||||
|
import subprocess
|
||||||
from bokeh.application.application import Application
|
import sys
|
||||||
from bokeh.application.handlers import ScriptHandler
|
|
||||||
from bokeh.server.server import Server
|
|
||||||
|
|
||||||
from pyzebra import ANATRIC_PATH, SXTAL_REFGEN_PATH
|
|
||||||
from pyzebra.app.handler import PyzebraHandler
|
|
||||||
|
|
||||||
logging.basicConfig(format="%(asctime)s %(message)s", level=logging.INFO)
|
|
||||||
logger = logging.getLogger(__name__)
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
"""The pyzebra command line interface.
|
app_path = os.path.join(os.path.dirname(os.path.abspath(__file__)))
|
||||||
|
subprocess.run(["bokeh", "serve", app_path, *sys.argv[1:]], check=True)
|
||||||
This is a wrapper around a bokeh server that provides an interface to launch the application,
|
|
||||||
bundled with the pyzebra package.
|
|
||||||
"""
|
|
||||||
app_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "app.py")
|
|
||||||
|
|
||||||
parser = argparse.ArgumentParser(
|
|
||||||
prog="pyzebra", formatter_class=argparse.ArgumentDefaultsHelpFormatter
|
|
||||||
)
|
|
||||||
|
|
||||||
parser.add_argument(
|
|
||||||
"--port", type=int, default=5006, help="port to listen on for HTTP requests"
|
|
||||||
)
|
|
||||||
|
|
||||||
parser.add_argument(
|
|
||||||
"--allow-websocket-origin",
|
|
||||||
metavar="HOST[:PORT]",
|
|
||||||
type=str,
|
|
||||||
action="append",
|
|
||||||
default=None,
|
|
||||||
help="hostname that can connect to the server websocket",
|
|
||||||
)
|
|
||||||
|
|
||||||
parser.add_argument(
|
|
||||||
"--anatric-path", type=str, default=ANATRIC_PATH, help="path to anatric executable"
|
|
||||||
)
|
|
||||||
|
|
||||||
parser.add_argument(
|
|
||||||
"--sxtal-refgen-path",
|
|
||||||
type=str,
|
|
||||||
default=SXTAL_REFGEN_PATH,
|
|
||||||
help="path to Sxtal_Refgen executable",
|
|
||||||
)
|
|
||||||
|
|
||||||
parser.add_argument("--spind-path", type=str, default=None, help="path to spind scripts folder")
|
|
||||||
|
|
||||||
parser.add_argument(
|
|
||||||
"--args",
|
|
||||||
nargs=argparse.REMAINDER,
|
|
||||||
default=[],
|
|
||||||
help="command line arguments for the pyzebra application",
|
|
||||||
)
|
|
||||||
|
|
||||||
args = parser.parse_args()
|
|
||||||
|
|
||||||
logger.info(app_path)
|
|
||||||
|
|
||||||
pyzebra_handler = PyzebraHandler(args.anatric_path, args.spind_path)
|
|
||||||
handler = ScriptHandler(filename=app_path, argv=args.args)
|
|
||||||
server = Server(
|
|
||||||
{"/": Application(pyzebra_handler, handler)},
|
|
||||||
port=args.port,
|
|
||||||
allow_websocket_origin=args.allow_websocket_origin,
|
|
||||||
)
|
|
||||||
|
|
||||||
server.start()
|
|
||||||
server.io_loop.start()
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
@ -1,31 +0,0 @@
|
|||||||
from bokeh.application.handlers import Handler
|
|
||||||
|
|
||||||
|
|
||||||
class PyzebraHandler(Handler):
|
|
||||||
"""Provides a mechanism for generic bokeh applications to build up new streamvis documents."""
|
|
||||||
|
|
||||||
def __init__(self, anatric_path, spind_path):
|
|
||||||
"""Initialize a pyzebra handler for bokeh applications.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
args (Namespace): Command line parsed arguments.
|
|
||||||
"""
|
|
||||||
super().__init__() # no-op
|
|
||||||
|
|
||||||
self.anatric_path = anatric_path
|
|
||||||
self.spind_path = spind_path
|
|
||||||
|
|
||||||
def modify_document(self, doc):
|
|
||||||
"""Modify an application document with pyzebra specific features.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
doc (Document) : A bokeh Document to update in-place
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
Document
|
|
||||||
"""
|
|
||||||
doc.title = "pyzebra"
|
|
||||||
doc.anatric_path = self.anatric_path
|
|
||||||
doc.spind_path = self.spind_path
|
|
||||||
|
|
||||||
return doc
|
|
@ -1,6 +1,6 @@
|
|||||||
|
import argparse
|
||||||
import logging
|
import logging
|
||||||
import sys
|
import sys
|
||||||
from io import StringIO
|
|
||||||
|
|
||||||
from bokeh.io import curdoc
|
from bokeh.io import curdoc
|
||||||
from bokeh.layouts import column, row
|
from bokeh.layouts import column, row
|
||||||
@ -20,16 +20,33 @@ from pyzebra.app import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
doc = curdoc()
|
doc = curdoc()
|
||||||
|
doc.title = "pyzebra"
|
||||||
|
|
||||||
sys.stdout = StringIO()
|
parser = argparse.ArgumentParser()
|
||||||
stdout_textareainput = TextAreaInput(title="print output:")
|
|
||||||
|
|
||||||
bokeh_stream = StringIO()
|
parser.add_argument(
|
||||||
bokeh_handler = logging.StreamHandler(bokeh_stream)
|
"--anatric-path", type=str, default=pyzebra.ANATRIC_PATH, help="path to anatric executable"
|
||||||
bokeh_handler.setFormatter(logging.Formatter(logging.BASIC_FORMAT))
|
)
|
||||||
bokeh_logger = logging.getLogger("bokeh")
|
|
||||||
bokeh_logger.setLevel(logging.WARNING)
|
parser.add_argument(
|
||||||
bokeh_logger.addHandler(bokeh_handler)
|
"--sxtal-refgen-path",
|
||||||
|
type=str,
|
||||||
|
default=pyzebra.SXTAL_REFGEN_PATH,
|
||||||
|
help="path to Sxtal_Refgen executable",
|
||||||
|
)
|
||||||
|
|
||||||
|
parser.add_argument("--spind-path", type=str, default=None, help="path to spind scripts folder")
|
||||||
|
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
doc.anatric_path = args.anatric_path
|
||||||
|
doc.spind_path = args.spind_path
|
||||||
|
doc.sxtal_refgen_path = args.sxtal_refgen_path
|
||||||
|
|
||||||
|
# In app_hooks.py a StreamHandler was added to "bokeh" logger
|
||||||
|
bokeh_stream = logging.getLogger("bokeh").handlers[0].stream
|
||||||
|
|
||||||
|
log_textareainput = TextAreaInput(title="logging output:")
|
||||||
bokeh_log_textareainput = TextAreaInput(title="server output:")
|
bokeh_log_textareainput = TextAreaInput(title="server output:")
|
||||||
|
|
||||||
|
|
||||||
@ -77,13 +94,13 @@ doc.add_root(
|
|||||||
panel_spind.create(),
|
panel_spind.create(),
|
||||||
]
|
]
|
||||||
),
|
),
|
||||||
row(stdout_textareainput, bokeh_log_textareainput, sizing_mode="scale_both"),
|
row(log_textareainput, bokeh_log_textareainput, sizing_mode="scale_both"),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def update_stdout():
|
def update_stdout():
|
||||||
stdout_textareainput.value = sys.stdout.getvalue()
|
log_textareainput.value = sys.stdout.getvalue()
|
||||||
bokeh_log_textareainput.value = bokeh_stream.getvalue()
|
bokeh_log_textareainput.value = bokeh_stream.getvalue()
|
||||||
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
|||||||
source /opt/miniconda3/etc/profile.d/conda.sh
|
source /opt/miniconda3/etc/profile.d/conda.sh
|
||||||
|
|
||||||
conda activate test
|
conda activate test
|
||||||
python /opt/pyzebra/pyzebra/app/cli.py --port=5010 --allow-websocket-origin=pyzebra.psi.ch:5010 --spind-path=/opt/spind
|
python /opt/pyzebra/pyzebra/app/cli.py --port=5010 --allow-websocket-origin=pyzebra.psi.ch:5010 --args --spind-path=/opt/spind
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
source /opt/miniconda3/etc/profile.d/conda.sh
|
source /opt/miniconda3/etc/profile.d/conda.sh
|
||||||
|
|
||||||
conda activate prod
|
conda activate prod
|
||||||
pyzebra --port=80 --allow-websocket-origin=pyzebra.psi.ch:80 --spind-path=/opt/spind
|
pyzebra --port=80 --allow-websocket-origin=pyzebra.psi.ch:80 --args --spind-path=/opt/spind
|
||||||
|
Loading…
x
Reference in New Issue
Block a user