Skip to content

Commit

Permalink
config: make uis a traitlet application
Browse files Browse the repository at this point in the history
  • Loading branch information
oliver-sanders committed Feb 24, 2021
1 parent 100ffa0 commit d277638
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 47 deletions.
40 changes: 7 additions & 33 deletions cylc/uiserver/config_defaults.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,48 +21,22 @@
from cylc.uiserver import __file__ as uis_pkg


DIST = Path(uis_pkg).parents[3] / 'cylc-ui/dist'


# --- Extra arguments to be passed to the single-user server.

# Some spawners allow shell-style expansion here, allowing you to use
# environment variables here. Most, including the default, do not. Consult the
# documentation for your spawner to verify!
c.Spawner.args = ['-s', str(DIST)]

# Some spawners allow shell-style expansion here, allowing you to use
# environment variables. Most, including the default, do not. Consult the
# documentation for your spawner to verify!
# the command the hub should spawn (i.e. the cylc uiserver itself)
c.Spawner.cmd = ['cylc', 'uiserver']


# --- The class to use for spawning single-user servers.

# Should be a subclass of Spawner.
# the spawner to invoke this command
c.JupyterHub.spawner_class = 'jupyterhub.spawner.LocalProcessSpawner'

# this auto-spawns uiservers without user interaction
c.JupyterHub.implicit_spawn_seconds = 0.01

# --- Cylc-ise Jupyterhub

# TODO: move logo to a shared location
# https://github.com/cylc/cylc-admin/issues/69
c.JupyterHub.logo_file = str(DIST.joinpath(Path('img/logo.svg')))
# use ISO8601 (expanded) date format for logging
c.JupyterHub.log_datefmt = '%Y-%m-%dT%H:%M:%S'
# specify custom HTML templates
# apply cylc styling to jupyterhub
c.JupyterHub.logo_file = str(Path(uis_pkg).parent / 'logo.svg')
c.JupyterHub.log_datefmt = '%Y-%m-%dT%H:%M:%S' # ISO8601 (expanded)
c.JupyterHub.template_paths = [
# custom HTML templates
pkg_resources.resource_filename(
'cylc.uiserver',
'templates'
)
]
c.JupyterHub.tornado_settings = {
'headers': {
# 'Access-Control-Allow-Origin': '*',
# 'Access-Control-Allow-Headers': '*',
# 'Access-Control-Allow-Methods': '*',
'Server': ''
},
}
19 changes: 19 additions & 0 deletions cylc/uiserver/logo.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
72 changes: 59 additions & 13 deletions cylc/uiserver/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,18 @@
from functools import partial
from logging.config import dictConfig
from os.path import join, abspath, dirname
from pathlib import Path
from typing import Any, Tuple, Type

from tornado import web, ioloop
from traitlets import (
HasTraits,
Unicode,
default,
)
from traitlets.config import (
Application
)

from cylc.flow.network.graphql import (
CylcGraphQLBackend, IgnoreFieldMiddleware
Expand All @@ -33,6 +42,12 @@
from graphene_tornado.tornado_graphql_handler import TornadoGraphQLHandler
from jupyterhub.services.auth import HubOAuthCallbackHandler
from jupyterhub.utils import url_path_join

from cylc.uiserver import (
__version__,
__file__ as uis_pkg
)
from cylc.uiserver.config import __file__ as CONFIG_FILE
from .data_store_mgr import DataStoreMgr
from .handlers import *
from .resolvers import Resolvers
Expand Down Expand Up @@ -64,22 +79,54 @@ def try_exit(self, uis):
logger.info('exit success')


class CylcUIServer(object):
class CylcUIServer(Application):

ui_path = Unicode(config=True)

@default('ui_path')
def _dev_ui_path(self):
return str(Path(uis_pkg).parents[3] / 'cylc-ui/dist')

def __init__(self, port, static, jupyter_hub_service_prefix):
def __init__(self, port, jupyter_hub_service_prefix, static=None):
self._load_config()
self._set_static_path(static)
self._port = port
if os.path.isabs(static):
self._static = static
else:
script_dir = os.path.dirname(__file__)
self._static = os.path.abspath(os.path.join(script_dir, static))
self._jupyter_hub_service_prefix = jupyter_hub_service_prefix
self.workflows_mgr = WorkflowsManager(self)
self.data_store_mgr = DataStoreMgr(self.workflows_mgr)
self.resolvers = Resolvers(
self.data_store_mgr,
workflows_mgr=self.workflows_mgr)

def _load_config(self):
"""Load the UIS config file."""
# this environment variable enables loading of the config
os.environ['CYLC_HUB_VERSION'] = __version__
try:
self.load_config_file(CONFIG_FILE)
finally:
del os.environ['CYLC_HUB_VERSION']
# set traitlets values from the config
for key, value in self.config.UIServer.items():
print(f'# {key}={value}')
setattr(self, key, value)

def _set_static_path(self, static):
"""Set the path to static files.
Args:
static: Command line override of the ui_path traitlet.
"""
if static:
if os.path.isabs(static):
self.ui_path = static
else:
script_dir = os.path.dirname(__file__)
self.ui_path = os.path.abspath(os.path.join(
script_dir,
static
))

def _create_static_handler(
self,
path: str
Expand All @@ -95,7 +142,7 @@ def _create_static_handler(
return (
rf"{self._jupyter_hub_service_prefix}({path})",
StaticHandler,
{"path": self._static}
{"path": self.ui_path}
)

def _create_handler(
Expand Down Expand Up @@ -152,15 +199,15 @@ def _make_app(self, debug: bool):
Args:
debug (bool): flag to set debugging in the Tornado application
"""
logger.info(self._static)
logger.info(self.ui_path)
# subscription/websockets server
subscription_server = TornadoSubscriptionServer(
schema,
backend=CylcGraphQLBackend(),
middleware=[IgnoreFieldMiddleware],
)
return MyApplication(
static_path=self._static,
static_path=self.ui_path,
debug=debug,
handlers=[
# static content
Expand Down Expand Up @@ -191,7 +238,7 @@ def _make_app(self, debug: bool):
(
rf"{self._jupyter_hub_service_prefix}?",
MainHandler,
{"path": self._static}
{"path": self.ui_path}
)
],
# always generate a new cookie secret on launch
Expand Down Expand Up @@ -226,8 +273,7 @@ def main():
)
parser.add_argument('-p', '--port', action="store", dest="port", type=int,
default=8888)
parser.add_argument('-s', '--static', action="store", dest="static",
required=True)
parser.add_argument('-s', '--static', action="store", dest="static")
parser.add_argument('--debug', action="store_true", dest="debug",
default=False)
here = abspath(dirname(__file__))
Expand Down
3 changes: 2 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,8 @@ def find_version(*file_paths):
packages=find_namespace_packages(include=["cylc.*"]),
package_data={
'cylc.uiserver': [
'logging_config.json'
'logging_config.json',
'logo.svg'
]
},
install_requires=install_requires,
Expand Down

0 comments on commit d277638

Please sign in to comment.