extension.py 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. # coding: utf-8
  2. """A tornado based Jupyter lab server."""
  3. # Copyright (c) Jupyter Development Team.
  4. # Distributed under the terms of the Modified BSD License.
  5. import os
  6. from tornado import web
  7. from notebook.base.handlers import IPythonHandler, FileFindHandler
  8. from jinja2 import FileSystemLoader
  9. from notebook.utils import url_path_join as ujoin
  10. from jupyter_core.paths import ENV_JUPYTER_PATH
  11. #-----------------------------------------------------------------------------
  12. # Module globals
  13. #-----------------------------------------------------------------------------
  14. DEV_NOTE_NPM = """It looks like you're running JupyterLab from source.
  15. If you're working on the TypeScript sources of JupyterLab, try running
  16. npm run watch
  17. from the JupyterLab repo directory in another terminal window to have the
  18. system incrementally watch and build JupyterLab's TypeScript for you, as you
  19. make changes.
  20. """
  21. HERE = os.path.dirname(__file__)
  22. FILE_LOADER = FileSystemLoader(HERE)
  23. PREFIX = '/lab'
  24. class LabHandler(IPythonHandler):
  25. """Render the JupyterLab View."""
  26. def initialize(self, page_config_data, built_files):
  27. self.page_config_data = page_config_data
  28. self.built_files = built_files
  29. @web.authenticated
  30. def get(self):
  31. config = self._get_lab_config()
  32. self.write(self.render_template('lab.html', **config))
  33. def _get_lab_config(self):
  34. """Get the config data for the page template."""
  35. static_prefix = ujoin(self.base_url, PREFIX)
  36. bundles = [ujoin(static_prefix, name + '.bundle.js') for name in
  37. ['main']]
  38. # Only load CSS files if they exist.
  39. css_files = []
  40. for css_file in ['main.css']:
  41. if os.path.isfile(os.path.join(self.built_files, css_file)):
  42. css_files.append(ujoin(static_prefix, css_file))
  43. configData = dict(self.page_config_data)
  44. configData.update(dict(
  45. terminalsAvailable=self.settings.get('terminals_available', False),
  46. ))
  47. mathjax_config = self.settings.get('mathjax_config',
  48. 'TeX-AMS_HTML-full,Safe')
  49. config = dict(
  50. static_prefix=static_prefix,
  51. page_title='JupyterLab Alpha Preview',
  52. mathjax_url=self.mathjax_url,
  53. mathjax_config=mathjax_config,
  54. jupyterlab_css=css_files,
  55. jupyterlab_bundles=bundles,
  56. )
  57. config['jupyterlab_config'] = configData
  58. return config
  59. def get_template(self, name):
  60. return FILE_LOADER.load(self.settings['jinja2_env'], name)
  61. def add_handlers(web_app):
  62. """Add the appropriate handlers to the web app.
  63. """
  64. base_url = web_app.settings['base_url']
  65. prefix = ujoin(base_url, PREFIX)
  66. page_config_data = web_app.settings.get('page_config_data', {})
  67. built_files = os.path.join(ENV_JUPYTER_PATH[0], 'lab', 'build')
  68. # Check for dev mode.
  69. dev_mode = os.environ.get('JUPYTERLAB_DEV', False)
  70. if not os.path.exists(built_files) or dev_mode:
  71. built_files = os.path.join(HERE, 'build')
  72. handlers = [
  73. (prefix + r'/?', LabHandler, {
  74. 'page_config_data': page_config_data,
  75. 'built_files': built_files
  76. }),
  77. (prefix + r"/(.*)", FileFindHandler, {
  78. 'path': built_files
  79. })
  80. ]
  81. web_app.add_handlers(".*$", handlers)
  82. def load_jupyter_server_extension(nbapp):
  83. """Load the JupyterLab server extension.
  84. """
  85. # Print messages.
  86. nbapp.log.info('JupyterLab alpha preview extension loaded from %s' % HERE)
  87. base_dir = os.path.realpath(os.path.join(HERE, '..'))
  88. dev_mode = os.path.exists(os.path.join(base_dir, '.git'))
  89. if dev_mode:
  90. nbapp.log.info(DEV_NOTE_NPM)
  91. add_handlers(nbapp.web_app)