app.py 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. """JupyterLab Server Application"""
  2. # Copyright (c) Jupyter Development Team.
  3. # Distributed under the terms of the Modified BSD License.
  4. from glob import glob
  5. from os.path import relpath
  6. from typing import Any
  7. from jupyter_server.extension.application import ExtensionApp, ExtensionAppJinjaMixin
  8. from jupyter_server.utils import url_path_join as ujoin
  9. from traitlets import Dict, Integer, Unicode, observe
  10. from ._version import __version__
  11. from .handlers import LabConfig, add_handlers
  12. class LabServerApp(ExtensionAppJinjaMixin, LabConfig, ExtensionApp):
  13. """A Lab Server Application that runs out-of-the-box"""
  14. name = "jupyterlab_server"
  15. extension_url = "/lab"
  16. app_name = "JupyterLab Server Application" # type:ignore[assignment]
  17. file_url_prefix = "/lab/tree" # type:ignore[assignment]
  18. @property
  19. def app_namespace(self) -> str: # type:ignore[override]
  20. return self.name
  21. default_url = Unicode("/lab", help="The default URL to redirect to from `/`")
  22. # Should your extension expose other server extensions when launched directly?
  23. load_other_extensions = True
  24. app_version = Unicode("", help="The version of the application.").tag(default=__version__)
  25. blacklist_uris = Unicode(
  26. "", config=True, help="Deprecated, use `LabServerApp.blocked_extensions_uris`"
  27. )
  28. blocked_extensions_uris = Unicode(
  29. "",
  30. config=True,
  31. help="""
  32. A list of comma-separated URIs to get the blocked extensions list
  33. .. versionchanged:: 2.0.0
  34. `LabServerApp.blacklist_uris` renamed to `blocked_extensions_uris`
  35. """,
  36. )
  37. whitelist_uris = Unicode(
  38. "", config=True, help="Deprecated, use `LabServerApp.allowed_extensions_uris`"
  39. )
  40. allowed_extensions_uris = Unicode(
  41. "",
  42. config=True,
  43. help="""
  44. "A list of comma-separated URIs to get the allowed extensions list
  45. .. versionchanged:: 2.0.0
  46. `LabServerApp.whitetlist_uris` renamed to `allowed_extensions_uris`
  47. """,
  48. )
  49. listings_refresh_seconds = Integer(
  50. 60 * 60, config=True, help="The interval delay in seconds to refresh the lists"
  51. )
  52. listings_request_options = Dict(
  53. {},
  54. config=True,
  55. help="The optional kwargs to use for the listings HTTP requests \
  56. as described on https://2.python-requests.org/en/v2.7.0/api/#requests.request",
  57. )
  58. _deprecated_aliases = {
  59. "blacklist_uris": ("blocked_extensions_uris", "1.2"),
  60. "whitelist_uris": ("allowed_extensions_uris", "1.2"),
  61. }
  62. # Method copied from
  63. # https://github.com/jupyterhub/jupyterhub/blob/d1a85e53dccfc7b1dd81b0c1985d158cc6b61820/jupyterhub/auth.py#L143-L161
  64. @observe(*list(_deprecated_aliases))
  65. def _deprecated_trait(self, change: Any) -> None:
  66. """observer for deprecated traits"""
  67. old_attr = change.name
  68. new_attr, version = self._deprecated_aliases.get(old_attr) # type:ignore[misc]
  69. new_value = getattr(self, new_attr)
  70. if new_value != change.new:
  71. # only warn if different
  72. # protects backward-compatible config from warnings
  73. # if they set the same value under both names
  74. self.log.warning(
  75. "%s.%s is deprecated in JupyterLab %s, use %s.%s instead",
  76. self.__class__.__name__,
  77. old_attr,
  78. version,
  79. self.__class__.__name__,
  80. new_attr,
  81. )
  82. setattr(self, new_attr, change.new)
  83. def initialize_settings(self) -> None:
  84. """Initialize the settings:
  85. set the static files as immutable, since they should have all hashed name.
  86. """
  87. immutable_cache = set(self.settings.get("static_immutable_cache", []))
  88. # Set lab static files as immutables
  89. immutable_cache.add(self.static_url_prefix)
  90. # Set extensions static files as immutables
  91. for extension_path in self.labextensions_path + self.extra_labextensions_path:
  92. extensions_url = [
  93. ujoin(self.labextensions_url, relpath(path, extension_path))
  94. for path in glob(f"{extension_path}/**/static", recursive=True)
  95. ]
  96. immutable_cache.update(extensions_url)
  97. self.settings.update({"static_immutable_cache": list(immutable_cache)})
  98. if self.serverapp:
  99. untracked_message_types = getattr(
  100. self.serverapp.kernel_manager, "untracked_message_types", None
  101. )
  102. if untracked_message_types:
  103. web_app = self.serverapp.web_app
  104. page_config_data = web_app.settings.setdefault("page_config_data", {})
  105. page_config_data["untracked_message_types"] = list(untracked_message_types)
  106. def initialize_templates(self) -> None:
  107. """Initialize templates."""
  108. self.static_paths = [self.static_dir]
  109. self.template_paths = [self.templates_dir]
  110. def initialize_handlers(self) -> None:
  111. """Initialize handlers."""
  112. add_handlers(self.handlers, self)
  113. main = launch_new_instance = LabServerApp.launch_instance