__init__.py 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. """Tornado handlers for the Lab view."""
  2. # Copyright (c) Jupyter Development Team.
  3. # Distributed under the terms of the Modified BSD License.
  4. import glob
  5. import json
  6. import os
  7. from tornado import web
  8. from notebook.base.handlers import IPythonHandler, FileFindHandler
  9. from jinja2 import FileSystemLoader
  10. from notebook.utils import url_path_join as ujoin
  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. BUILT_FILES = os.path.join(HERE, 'build')
  24. PREFIX = '/lab'
  25. EXTENSION_PREFIX = '/labextension'
  26. __version__ = None
  27. def get_labextension_manifest_data_by_folder(folder):
  28. """Get the manifest data for a given lab extension folder
  29. """
  30. manifest_files = glob.glob(os.path.join(folder, '*.manifest'))
  31. manifests = {}
  32. for file in manifest_files:
  33. with open(file) as fid:
  34. manifest = json.load(fid)
  35. manifests[manifest['name']] = manifest
  36. return manifests
  37. def get_labextension_manifest_data_by_name(name):
  38. """Get the manifest data for a given lab extension folder
  39. """
  40. from .labextensions import _labextension_dirs
  41. for exts in _labextension_dirs():
  42. full_dest = os.path.join(exts, name)
  43. if os.path.exists(full_dest):
  44. return get_labextension_manifest_data_by_folder(full_dest)
  45. class LabHandler(IPythonHandler):
  46. """Render the Jupyter Lab View."""
  47. @web.authenticated
  48. def get(self):
  49. static_prefix = ujoin(self.base_url, PREFIX)
  50. labextensions = self.application.labextensions
  51. data = get_labextension_manifest_data_by_folder(BUILT_FILES)
  52. css_files = [ujoin(static_prefix, 'main.css'),
  53. ujoin(static_prefix, 'extensions.css')]
  54. main = data['main']['entry']
  55. bundles = [ujoin(static_prefix, name + '.bundle.js') for name in
  56. ['loader', 'main', 'extensions']]
  57. entries = [data['extensions']['entry']]
  58. # Gather the lab extension files and entry points.
  59. for name in labextensions:
  60. data = get_labextension_manifest_data_by_name(name)
  61. if data is None:
  62. self.log.warn('Could not locate extension: ' + name)
  63. continue
  64. for value in data.values():
  65. if value.get('entry', None):
  66. entries.append(value['entry'])
  67. bundles.append('%s/%s/%s' % (
  68. EXTENSION_PREFIX, name, value['files'][0]
  69. ))
  70. for fname in value['files']:
  71. if os.path.splitext(fname)[1] == '.css':
  72. css_files.append('%s/%s/%s' % (
  73. EXTENSION_PREFIX, name, fname
  74. ))
  75. self.write(self.render_template('lab.html',
  76. static_prefix=static_prefix,
  77. page_title='JupyterLab Alpha Preview',
  78. terminals_available=self.settings['terminals_available'],
  79. mathjax_url=self.mathjax_url,
  80. jupyterlab_main=main,
  81. jupyterlab_css=css_files,
  82. jupyterlab_bundles=bundles,
  83. plugin_entries=entries,
  84. mathjax_config='TeX-AMS_HTML-full,Safe',
  85. #mathjax_config=self.mathjax_config # for the next release of the notebook
  86. ))
  87. def get_template(self, name):
  88. return FILE_LOADER.load(self.settings['jinja2_env'], name)
  89. #-----------------------------------------------------------------------------
  90. # URL to handler mappings
  91. #-----------------------------------------------------------------------------
  92. default_handlers = [
  93. (PREFIX + r'/?', LabHandler),
  94. (PREFIX + r"/(.*)", FileFindHandler,
  95. {'path': BUILT_FILES}),
  96. ]
  97. def _jupyter_server_extension_paths():
  98. return [{
  99. "module": "jupyterlab"
  100. }]
  101. def load_jupyter_server_extension(nbapp):
  102. from jupyter_core.paths import jupyter_path
  103. from .labapp import get_labextensions
  104. base_dir = os.path.realpath(os.path.join(HERE, '..'))
  105. dev_mode = os.path.exists(os.path.join(base_dir, '.git'))
  106. if dev_mode:
  107. nbapp.log.info(DEV_NOTE_NPM)
  108. nbapp.log.info('JupyterLab alpha preview extension loaded from %s' % HERE)
  109. webapp = nbapp.web_app
  110. webapp.labextensions = get_labextensions(parent=nbapp)
  111. base_url = webapp.settings['base_url']
  112. webapp.add_handlers(".*$",
  113. [(ujoin(base_url, h[0]),) + h[1:] for h in default_handlers])
  114. labextension_handler = (
  115. r"%s/(.*)" % EXTENSION_PREFIX, FileFindHandler, {
  116. 'path': jupyter_path('labextensions'),
  117. 'no_cache_paths': ['/'], # don't cache anything in labbextensions
  118. }
  119. )
  120. webapp.add_handlers(".*$", [labextension_handler])