handlers.py 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. """Kernelspecs API Handlers."""
  2. import mimetypes
  3. from jupyter_core.utils import ensure_async
  4. from tornado import web
  5. from jupyter_server.auth.decorator import authorized
  6. from ..base.handlers import JupyterHandler
  7. from ..services.kernelspecs.handlers import kernel_name_regex
  8. AUTH_RESOURCE = "kernelspecs"
  9. class KernelSpecResourceHandler(web.StaticFileHandler, JupyterHandler):
  10. """A Kernelspec resource handler."""
  11. SUPPORTED_METHODS = ("GET", "HEAD")
  12. auth_resource = AUTH_RESOURCE
  13. def initialize(self):
  14. """Initialize a kernelspec resource handler."""
  15. web.StaticFileHandler.initialize(self, path="")
  16. @web.authenticated
  17. @authorized
  18. async def get(self, kernel_name, path, include_body=True):
  19. """Get a kernelspec resource."""
  20. ksm = self.kernel_spec_manager
  21. if path.lower().endswith(".png"):
  22. self.set_header("Cache-Control", f"max-age={60*60*24*30}")
  23. ksm = self.kernel_spec_manager
  24. if hasattr(ksm, "get_kernel_spec_resource"):
  25. # If the kernel spec manager defines a method to get kernelspec resources,
  26. # then use that instead of trying to read from disk.
  27. kernel_spec_res = await ksm.get_kernel_spec_resource(kernel_name, path)
  28. if kernel_spec_res is not None:
  29. # We have to explicitly specify the `absolute_path` attribute so that
  30. # the underlying StaticFileHandler methods can calculate an etag.
  31. self.absolute_path = path
  32. mimetype: str = mimetypes.guess_type(path)[0] or "text/plain"
  33. self.set_header("Content-Type", mimetype)
  34. self.finish(kernel_spec_res)
  35. return None
  36. else:
  37. self.log.warning(
  38. f"Kernelspec resource '{path}' for '{kernel_name}' not found. Kernel spec manager may"
  39. " not support resource serving. Falling back to reading from disk"
  40. )
  41. try:
  42. kspec = await ensure_async(ksm.get_kernel_spec(kernel_name))
  43. self.root = kspec.resource_dir
  44. except KeyError as e:
  45. raise web.HTTPError(404, "Kernel spec %s not found" % kernel_name) from e
  46. self.log.debug("Serving kernel resource from: %s", self.root)
  47. return await web.StaticFileHandler.get(self, path, include_body=include_body)
  48. @web.authenticated
  49. @authorized
  50. async def head(self, kernel_name, path):
  51. """Get the head info for a kernel resource."""
  52. return await ensure_async(self.get(kernel_name, path, include_body=False))
  53. default_handlers = [
  54. (r"/kernelspecs/%s/(?P<path>.*)" % kernel_name_regex, KernelSpecResourceHandler),
  55. ]