mirror of
https://github.com/jupyter/notebook.git
synced 2024-12-27 04:20:22 +08:00
Merge pull request #7283 from minrk/kernel-spec-model
add resource URLs to kernelspec model
This commit is contained in:
commit
c1d9f4d436
@ -2,11 +2,43 @@
|
||||
|
||||
# Copyright (c) IPython Development Team.
|
||||
# Distributed under the terms of the Modified BSD License.
|
||||
|
||||
import glob
|
||||
import json
|
||||
import os
|
||||
pjoin = os.path.join
|
||||
|
||||
from tornado import web
|
||||
|
||||
from ...base.handlers import IPythonHandler, json_errors
|
||||
from ...utils import url_path_join
|
||||
|
||||
def kernelspec_model(handler, name):
|
||||
"""Load a KernelSpec by name and return the REST API model"""
|
||||
ksm = handler.kernel_spec_manager
|
||||
spec = ksm.get_kernel_spec(name)
|
||||
d = {'name': name}
|
||||
d['spec'] = spec.to_dict()
|
||||
d['resources'] = resources = {}
|
||||
resource_dir = spec.resource_dir
|
||||
for resource in ['kernel.js', 'kernel.css']:
|
||||
if os.path.exists(pjoin(resource_dir, resource)):
|
||||
resources[resource] = url_path_join(
|
||||
handler.base_url,
|
||||
'kernelspecs',
|
||||
name,
|
||||
resource
|
||||
)
|
||||
for logo_file in glob.glob(pjoin(resource_dir, 'logo-*')):
|
||||
fname = os.path.basename(logo_file)
|
||||
no_ext, _ = os.path.splitext(fname)
|
||||
resources[no_ext] = url_path_join(
|
||||
handler.base_url,
|
||||
'kernelspecs',
|
||||
name,
|
||||
fname
|
||||
)
|
||||
return d
|
||||
|
||||
class MainKernelSpecHandler(IPythonHandler):
|
||||
SUPPORTED_METHODS = ('GET',)
|
||||
@ -21,13 +53,11 @@ class MainKernelSpecHandler(IPythonHandler):
|
||||
model['kernelspecs'] = specs = {}
|
||||
for kernel_name in ksm.find_kernel_specs():
|
||||
try:
|
||||
d = ksm.get_kernel_spec(kernel_name).to_dict()
|
||||
d = kernelspec_model(self, kernel_name)
|
||||
except Exception:
|
||||
self.log.error("Failed to load kernel spec: '%s'", kernel_name, exc_info=True)
|
||||
continue
|
||||
d['name'] = kernel_name
|
||||
specs[kernel_name] = d
|
||||
|
||||
self.set_header("Content-Type", 'application/json')
|
||||
self.finish(json.dumps(model))
|
||||
|
||||
@ -38,13 +68,12 @@ class KernelSpecHandler(IPythonHandler):
|
||||
@web.authenticated
|
||||
@json_errors
|
||||
def get(self, kernel_name):
|
||||
ksm = self.kernel_spec_manager
|
||||
try:
|
||||
kernelspec = ksm.get_kernel_spec(kernel_name)
|
||||
model = kernelspec_model(self, kernel_name)
|
||||
except KeyError:
|
||||
raise web.HTTPError(404, u'Kernel spec %s not found' % kernel_name)
|
||||
self.set_header("Content-Type", 'application/json')
|
||||
self.finish(kernelspec.to_json())
|
||||
self.finish(json.dumps(model))
|
||||
|
||||
|
||||
# URL to handler mappings
|
||||
|
@ -99,17 +99,20 @@ class APITest(NotebookTestBase):
|
||||
self.assertGreaterEqual(len(specs), 2)
|
||||
|
||||
def is_sample_kernelspec(s):
|
||||
return s['name'] == 'sample' and s['display_name'] == 'Test kernel'
|
||||
return s['name'] == 'sample' and s['spec']['display_name'] == 'Test kernel'
|
||||
|
||||
def is_default_kernelspec(s):
|
||||
return s['name'] == NATIVE_KERNEL_NAME and s['display_name'].startswith("IPython")
|
||||
return s['name'] == NATIVE_KERNEL_NAME and s['spec']['display_name'].startswith("IPython")
|
||||
|
||||
assert any(is_sample_kernelspec(s) for s in specs.values()), specs
|
||||
assert any(is_default_kernelspec(s) for s in specs.values()), specs
|
||||
|
||||
def test_get_kernelspec(self):
|
||||
spec = self.ks_api.kernel_spec_info('Sample').json() # Case insensitive
|
||||
self.assertEqual(spec['display_name'], 'Test kernel')
|
||||
model = self.ks_api.kernel_spec_info('Sample').json() # Case insensitive
|
||||
self.assertEqual(model['name'].lower(), 'sample')
|
||||
self.assertIsInstance(model['spec'], dict)
|
||||
self.assertEqual(model['spec']['display_name'], 'Test kernel')
|
||||
self.assertIsInstance(model['resources'], dict)
|
||||
|
||||
def test_get_nonexistant_kernelspec(self):
|
||||
with assert_http_error(404):
|
||||
|
@ -35,8 +35,8 @@ define([
|
||||
var change_kernel_submenu = $("#menu-change-kernel-submenu");
|
||||
var keys = Object.keys(data.kernelspecs).sort(function (a, b) {
|
||||
// sort by display_name
|
||||
var da = data.kernelspecs[a].display_name;
|
||||
var db = data.kernelspecs[b].display_name;
|
||||
var da = data.kernelspecs[a].spec.display_name;
|
||||
var db = data.kernelspecs[b].spec.display_name;
|
||||
if (da === db) {
|
||||
return 0;
|
||||
} else if (da > db) {
|
||||
@ -50,7 +50,7 @@ define([
|
||||
var ks_submenu_entry = $("<li>").attr("id", "kernel-submenu-"+ks.name).append($('<a>')
|
||||
.attr('href', '#')
|
||||
.click($.proxy(this.change_kernel, this, ks.name))
|
||||
.text(ks.display_name));
|
||||
.text(ks.spec.display_name));
|
||||
change_kernel_submenu.append(ks_submenu_entry);
|
||||
}
|
||||
};
|
||||
@ -59,25 +59,17 @@ define([
|
||||
/**
|
||||
* TODO, have a methods to set kernel spec directly ?
|
||||
**/
|
||||
var that = this;
|
||||
if (kernel_name === this.current_selection) {
|
||||
return;
|
||||
}
|
||||
var ks = this.kernelspecs[kernel_name];
|
||||
var new_mode_url = 'kernelspecs/'+ks.name+'/kernel';
|
||||
|
||||
var css_url = this.notebook.base_url+new_mode_url+'.css';
|
||||
$.ajax({
|
||||
type: 'HEAD',
|
||||
url: css_url,
|
||||
success: function(){
|
||||
$('#kernel-css')
|
||||
.attr('href',css_url);
|
||||
},
|
||||
error:function(){
|
||||
console.info("No custom kernel.css at URL:", css_url)
|
||||
}
|
||||
});
|
||||
|
||||
var css_url = ks.resources['kernel.css'];
|
||||
if (css_url) {
|
||||
$('#kernel-css').attr('href', css_url);
|
||||
} else {
|
||||
$('#kernel-css').attr('href', '');
|
||||
}
|
||||
|
||||
try {
|
||||
this.notebook.start_session(kernel_name);
|
||||
@ -92,26 +84,23 @@ define([
|
||||
return;
|
||||
}
|
||||
this.events.trigger('spec_changed.Kernel', ks);
|
||||
|
||||
|
||||
// load new mode kernel.js if exist
|
||||
require([new_mode_url],
|
||||
// if new mode has custom.js
|
||||
function(new_mode){
|
||||
that.lock_switch();
|
||||
if(new_mode && new_mode.onload){
|
||||
new_mode.onload();
|
||||
} else {
|
||||
console.warn("The current kernel defined a kernel.js file but does not contain "+
|
||||
"any asynchronous module definition. This is undefined behavior "+
|
||||
"which is not recommended");
|
||||
|
||||
if (ks.resources['kernel.js']) {
|
||||
require([ks.resources['kernel.js']],
|
||||
function (kernel_mod) {
|
||||
if (kernel_mod && kernel_mod.onload) {
|
||||
kernel_mod.onload();
|
||||
} else {
|
||||
console.warn("Kernel " + ks.name + " has a kernel.js file that does not contain "+
|
||||
"any asynchronous module definition. This is undefined behavior "+
|
||||
"and not recommended.");
|
||||
}
|
||||
}, function (err) {
|
||||
console.warn("Failed to load kernel.js from ", ks.resources['kernel.js'], err);
|
||||
}
|
||||
},
|
||||
function(err){
|
||||
// if new mode does not have custom.js
|
||||
console.info("No custom kernel.css at URL:", new_mode_url)
|
||||
}
|
||||
);
|
||||
);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
KernelSelector.prototype.lock_switch = function() {
|
||||
@ -123,10 +112,16 @@ define([
|
||||
|
||||
KernelSelector.prototype.bind_events = function() {
|
||||
var that = this;
|
||||
var logo_img = this.element.find("img.current_kernel_logo");
|
||||
this.events.on('spec_changed.Kernel', function(event, data) {
|
||||
that.current_selection = data.name;
|
||||
$("#kernel_indicator").find('.kernel_indicator_name').text(data.display_name);
|
||||
that.element.find("img.current_kernel_logo").attr("src", that.notebook.base_url + "kernelspecs/" + data.name + "/logo-64x64.png");
|
||||
$("#kernel_indicator").find('.kernel_indicator_name').text(data.spec.display_name);
|
||||
if (data.resources['logo-64x64']) {
|
||||
logo_img.attr("src", data.resources['logo-64x64']);
|
||||
logo_img.show();
|
||||
} else {
|
||||
logo_img.hide();
|
||||
}
|
||||
});
|
||||
|
||||
this.events.on('kernel_created.Session', function(event, data) {
|
||||
@ -139,7 +134,6 @@ define([
|
||||
}
|
||||
});
|
||||
|
||||
var logo_img = this.element.find("img.current_kernel_logo");
|
||||
logo_img.on("load", function() {
|
||||
logo_img.show();
|
||||
});
|
||||
|
@ -247,7 +247,7 @@ define([
|
||||
|
||||
this.events.on('spec_changed.Kernel', function(event, data) {
|
||||
that.metadata.kernelspec =
|
||||
{name: data.name, display_name: data.display_name};
|
||||
{name: data.name, display_name: data.spec.display_name};
|
||||
});
|
||||
|
||||
this.events.on('kernel_ready.Kernel', function(event, data) {
|
||||
|
Loading…
Reference in New Issue
Block a user