handlers.py 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. """Tornado handlers for kernel specifications.
  2. Preliminary documentation at https://github.com/ipython/ipython/wiki/IPEP-25%3A-Registry-of-installed-kernels#rest-api
  3. """
  4. # Copyright (c) Jupyter Development Team.
  5. # Distributed under the terms of the Modified BSD License.
  6. import glob
  7. import json
  8. import os
  9. pjoin = os.path.join
  10. from tornado import web
  11. from ...base.handlers import APIHandler
  12. from ...utils import url_path_join, url_unescape
  13. def kernelspec_model(handler, name, spec_dict, resource_dir):
  14. """Load a KernelSpec by name and return the REST API model"""
  15. d = {
  16. 'name': name,
  17. 'spec': spec_dict,
  18. 'resources': {}
  19. }
  20. # Add resource files if they exist
  21. resource_dir = resource_dir
  22. for resource in ['kernel.js', 'kernel.css']:
  23. if os.path.exists(pjoin(resource_dir, resource)):
  24. d['resources'][resource] = url_path_join(
  25. handler.base_url,
  26. 'kernelspecs',
  27. name,
  28. resource
  29. )
  30. for logo_file in glob.glob(pjoin(resource_dir, 'logo-*')):
  31. fname = os.path.basename(logo_file)
  32. no_ext, _ = os.path.splitext(fname)
  33. d['resources'][no_ext] = url_path_join(
  34. handler.base_url,
  35. 'kernelspecs',
  36. name,
  37. fname
  38. )
  39. return d
  40. class MainKernelSpecHandler(APIHandler):
  41. @web.authenticated
  42. def get(self):
  43. ksm = self.kernel_spec_manager
  44. km = self.kernel_manager
  45. model = {}
  46. model['default'] = km.default_kernel_name
  47. model['kernelspecs'] = specs = {}
  48. for kernel_name, kernel_info in ksm.get_all_specs().items():
  49. try:
  50. d = kernelspec_model(self, kernel_name, kernel_info['spec'],
  51. kernel_info['resource_dir'])
  52. except Exception:
  53. self.log.error("Failed to load kernel spec: '%s'", kernel_name, exc_info=True)
  54. continue
  55. specs[kernel_name] = d
  56. self.set_header("Content-Type", 'application/json')
  57. self.finish(json.dumps(model))
  58. class KernelSpecHandler(APIHandler):
  59. @web.authenticated
  60. def get(self, kernel_name):
  61. ksm = self.kernel_spec_manager
  62. kernel_name = url_unescape(kernel_name)
  63. try:
  64. spec = ksm.get_kernel_spec(kernel_name)
  65. except KeyError:
  66. raise web.HTTPError(404, u'Kernel spec %s not found' % kernel_name)
  67. model = kernelspec_model(self, kernel_name, spec.to_dict(), spec.resource_dir)
  68. self.set_header("Content-Type", 'application/json')
  69. self.finish(json.dumps(model))
  70. # URL to handler mappings
  71. kernel_name_regex = r"(?P<kernel_name>[\w\.\-%]+)"
  72. default_handlers = [
  73. (r"/api/kernelspecs", MainKernelSpecHandler),
  74. (r"/api/kernelspecs/%s" % kernel_name_regex, KernelSpecHandler),
  75. ]