mirror of
https://github.com/jupyter/notebook.git
synced 2025-02-11 12:30:51 +08:00
Merge pull request #1527 from SylvainCorlay/traitlets_api
Update traitlets API
This commit is contained in:
commit
869d5d9ffc
@ -78,7 +78,7 @@ from .services.sessions.sessionmanager import SessionManager
|
||||
|
||||
from .auth.login import LoginHandler
|
||||
from .auth.logout import LogoutHandler
|
||||
from .base.handlers import FileFindHandler, IPythonHandler
|
||||
from .base.handlers import FileFindHandler
|
||||
|
||||
from traitlets.config import Config
|
||||
from traitlets.config.application import catch_config_error, boolean_flag
|
||||
@ -91,7 +91,7 @@ from jupyter_client.session import Session
|
||||
from nbformat.sign import NotebookNotary
|
||||
from traitlets import (
|
||||
Dict, Unicode, Integer, List, Bool, Bytes, Instance,
|
||||
TraitError, Type, Float
|
||||
TraitError, Type, Float, observe, default, validate
|
||||
)
|
||||
from ipython_genutils import py3compat
|
||||
from jupyter_core.paths import jupyter_runtime_dir, jupyter_path
|
||||
@ -144,7 +144,7 @@ def load_handlers(name):
|
||||
|
||||
class NotebookWebApplication(web.Application):
|
||||
|
||||
def __init__(self, ipython_app, kernel_manager, contents_manager,
|
||||
def __init__(self, jupyter_app, kernel_manager, contents_manager,
|
||||
session_manager, kernel_spec_manager,
|
||||
config_manager, log,
|
||||
base_url, default_url, settings_overrides, jinja_env_options):
|
||||
@ -157,14 +157,14 @@ class NotebookWebApplication(web.Application):
|
||||
log.info(DEV_NOTE_NPM)
|
||||
|
||||
settings = self.init_settings(
|
||||
ipython_app, kernel_manager, contents_manager,
|
||||
jupyter_app, kernel_manager, contents_manager,
|
||||
session_manager, kernel_spec_manager, config_manager, log, base_url,
|
||||
default_url, settings_overrides, jinja_env_options)
|
||||
handlers = self.init_handlers(settings)
|
||||
|
||||
super(NotebookWebApplication, self).__init__(handlers, **settings)
|
||||
|
||||
def init_settings(self, ipython_app, kernel_manager, contents_manager,
|
||||
def init_settings(self, jupyter_app, kernel_manager, contents_manager,
|
||||
session_manager, kernel_spec_manager,
|
||||
config_manager,
|
||||
log, base_url, default_url, settings_overrides,
|
||||
@ -172,7 +172,7 @@ class NotebookWebApplication(web.Application):
|
||||
|
||||
_template_path = settings_overrides.get(
|
||||
"template_path",
|
||||
ipython_app.template_file_path,
|
||||
jupyter_app.template_file_path,
|
||||
)
|
||||
if isinstance(_template_path, py3compat.string_types):
|
||||
_template_path = (_template_path,)
|
||||
@ -191,7 +191,7 @@ class NotebookWebApplication(web.Application):
|
||||
# reset the cache on server restart
|
||||
version_hash = datetime.datetime.now().strftime("%Y%m%d%H%M%S")
|
||||
|
||||
if ipython_app.ignore_minified_js:
|
||||
if jupyter_app.ignore_minified_js:
|
||||
log.warn("""The `ignore_minified_js` flag is deprecated and no
|
||||
longer works. Alternatively use `npm run build:watch` when
|
||||
working on the notebook's Javascript and LESS""")
|
||||
@ -203,8 +203,8 @@ class NotebookWebApplication(web.Application):
|
||||
base_url=base_url,
|
||||
default_url=default_url,
|
||||
template_path=template_path,
|
||||
static_path=ipython_app.static_file_path,
|
||||
static_custom_path=ipython_app.static_custom_path,
|
||||
static_path=jupyter_app.static_file_path,
|
||||
static_custom_path=jupyter_app.static_custom_path,
|
||||
static_handler_class = FileFindHandler,
|
||||
static_url_prefix = url_path_join(base_url,'/static/'),
|
||||
static_handler_args = {
|
||||
@ -212,19 +212,19 @@ class NotebookWebApplication(web.Application):
|
||||
'no_cache_paths': [url_path_join(base_url, 'static', 'custom')],
|
||||
},
|
||||
version_hash=version_hash,
|
||||
ignore_minified_js=ipython_app.ignore_minified_js,
|
||||
ignore_minified_js=jupyter_app.ignore_minified_js,
|
||||
|
||||
# rate limits
|
||||
iopub_msg_rate_limit=ipython_app.iopub_msg_rate_limit,
|
||||
iopub_data_rate_limit=ipython_app.iopub_data_rate_limit,
|
||||
rate_limit_window=ipython_app.rate_limit_window,
|
||||
iopub_msg_rate_limit=jupyter_app.iopub_msg_rate_limit,
|
||||
iopub_data_rate_limit=jupyter_app.iopub_data_rate_limit,
|
||||
rate_limit_window=jupyter_app.rate_limit_window,
|
||||
|
||||
# authentication
|
||||
cookie_secret=ipython_app.cookie_secret,
|
||||
cookie_secret=jupyter_app.cookie_secret,
|
||||
login_url=url_path_join(base_url,'/login'),
|
||||
login_handler_class=ipython_app.login_handler_class,
|
||||
logout_handler_class=ipython_app.logout_handler_class,
|
||||
password=ipython_app.password,
|
||||
login_handler_class=jupyter_app.login_handler_class,
|
||||
logout_handler_class=jupyter_app.logout_handler_class,
|
||||
password=jupyter_app.password,
|
||||
|
||||
# managers
|
||||
kernel_manager=kernel_manager,
|
||||
@ -234,13 +234,13 @@ class NotebookWebApplication(web.Application):
|
||||
config_manager=config_manager,
|
||||
|
||||
# IPython stuff
|
||||
jinja_template_vars=ipython_app.jinja_template_vars,
|
||||
nbextensions_path=ipython_app.nbextensions_path,
|
||||
websocket_url=ipython_app.websocket_url,
|
||||
mathjax_url=ipython_app.mathjax_url,
|
||||
mathjax_config=ipython_app.mathjax_config,
|
||||
config=ipython_app.config,
|
||||
config_dir=ipython_app.config_dir,
|
||||
jinja_template_vars=jupyter_app.jinja_template_vars,
|
||||
nbextensions_path=jupyter_app.nbextensions_path,
|
||||
websocket_url=jupyter_app.websocket_url,
|
||||
mathjax_url=jupyter_app.mathjax_url,
|
||||
mathjax_config=jupyter_app.mathjax_config,
|
||||
config=jupyter_app.config,
|
||||
config_dir=jupyter_app.config_dir,
|
||||
jinja2_env=env,
|
||||
terminals_available=False, # Set later if terminals are available
|
||||
)
|
||||
@ -426,14 +426,17 @@ class NotebookApp(JupyterApp):
|
||||
|
||||
_log_formatter_cls = LogFormatter
|
||||
|
||||
def _log_level_default(self):
|
||||
@default('log_level')
|
||||
def _default_log_level(self):
|
||||
return logging.INFO
|
||||
|
||||
def _log_datefmt_default(self):
|
||||
@default('log_datefmt')
|
||||
def _default_log_datefmt(self):
|
||||
"""Exclude date from default date format"""
|
||||
return "%H:%M:%S"
|
||||
|
||||
def _log_format_default(self):
|
||||
@default('log_format')
|
||||
def _default_log_format(self):
|
||||
"""override default log format to include time"""
|
||||
return u"%(color)s[%(levelname)1.1s %(asctime)s.%(msecs).03d %(name)s]%(end_color)s %(message)s"
|
||||
|
||||
@ -484,7 +487,9 @@ class NotebookApp(JupyterApp):
|
||||
ip = Unicode('localhost', config=True,
|
||||
help="The IP address the notebook server will listen on."
|
||||
)
|
||||
def _ip_default(self):
|
||||
|
||||
@default('ip')
|
||||
def _default_ip(self):
|
||||
"""Return localhost if available, 127.0.0.1 otherwise.
|
||||
|
||||
On some (horribly broken) systems, localhost cannot be bound.
|
||||
@ -499,12 +504,17 @@ class NotebookApp(JupyterApp):
|
||||
s.close()
|
||||
return 'localhost'
|
||||
|
||||
def _ip_changed(self, name, old, new):
|
||||
if new == u'*': self.ip = u''
|
||||
@validate('ip')
|
||||
def _valdate_ip(self, proposal):
|
||||
value = proposal['value']
|
||||
if value == u'*':
|
||||
value = u''
|
||||
return value
|
||||
|
||||
port = Integer(8888, config=True,
|
||||
help="The port the notebook server will listen on."
|
||||
)
|
||||
|
||||
port_retries = Integer(50, config=True,
|
||||
help="The number of additional ports to try if the specified port is not available."
|
||||
)
|
||||
@ -524,7 +534,9 @@ class NotebookApp(JupyterApp):
|
||||
cookie_secret_file = Unicode(config=True,
|
||||
help="""The file where the cookie secret is stored."""
|
||||
)
|
||||
def _cookie_secret_file_default(self):
|
||||
|
||||
@default('cookie_secret_file')
|
||||
def _default_cookie_secret_file(self):
|
||||
return os.path.join(self.runtime_dir, 'notebook_cookie_secret')
|
||||
|
||||
cookie_secret = Bytes(b'', config=True,
|
||||
@ -536,7 +548,9 @@ class NotebookApp(JupyterApp):
|
||||
cookie_secret stored in plaintext (you can read the value from a file).
|
||||
"""
|
||||
)
|
||||
def _cookie_secret_default(self):
|
||||
|
||||
@default('cookie_secret')
|
||||
def _default_cookie_secret(self):
|
||||
if os.path.exists(self.cookie_secret_file):
|
||||
with io.open(self.cookie_secret_file, 'rb') as f:
|
||||
return f.read()
|
||||
@ -599,9 +613,11 @@ class NotebookApp(JupyterApp):
|
||||
webapp_settings = Dict(config=True,
|
||||
help="DEPRECATED, use tornado_settings"
|
||||
)
|
||||
def _webapp_settings_changed(self, name, old, new):
|
||||
|
||||
@observe('webapp_settings')
|
||||
def _update_webapp_settings(self, change):
|
||||
self.log.warning("\n webapp_settings is deprecated, use tornado_settings.\n")
|
||||
self.tornado_settings = new
|
||||
self.tornado_settings = change['new']
|
||||
|
||||
tornado_settings = Dict(config=True,
|
||||
help="Supply overrides for the tornado.web.Application that the "
|
||||
@ -636,9 +652,11 @@ class NotebookApp(JupyterApp):
|
||||
When disabled, equations etc. will appear as their untransformed TeX source.
|
||||
"""
|
||||
)
|
||||
def _enable_mathjax_changed(self, name, old, new):
|
||||
|
||||
@observe('enable_mathjax')
|
||||
def _update_enable_mathjax(self, change):
|
||||
"""set mathjax url to empty if mathjax is disabled"""
|
||||
if not new:
|
||||
if not change['new']:
|
||||
self.mathjax_url = u''
|
||||
|
||||
base_url = Unicode('/', config=True,
|
||||
@ -647,16 +665,22 @@ class NotebookApp(JupyterApp):
|
||||
Leading and trailing slashes can be omitted,
|
||||
and will automatically be added.
|
||||
''')
|
||||
def _base_url_changed(self, name, old, new):
|
||||
if not new.startswith('/'):
|
||||
self.base_url = '/'+new
|
||||
elif not new.endswith('/'):
|
||||
self.base_url = new+'/'
|
||||
|
||||
@validate('base_url')
|
||||
def _update_base_url(self, proposal):
|
||||
value = proposal['value']
|
||||
if not value.startswith('/'):
|
||||
value = '/' + value
|
||||
elif not value.endswith('/'):
|
||||
value = value + '/'
|
||||
return value
|
||||
|
||||
base_project_url = Unicode('/', config=True, help="""DEPRECATED use base_url""")
|
||||
def _base_project_url_changed(self, name, old, new):
|
||||
|
||||
@observe('base_project_url')
|
||||
def _update_base_project_url(self, change):
|
||||
self.log.warning("base_project_url is deprecated, use base_url")
|
||||
self.base_url = new
|
||||
self.base_url = change['new']
|
||||
|
||||
extra_static_paths = List(Unicode(), config=True,
|
||||
help="""Extra paths to search for serving static files.
|
||||
@ -673,7 +697,9 @@ class NotebookApp(JupyterApp):
|
||||
static_custom_path = List(Unicode(),
|
||||
help="""Path to search for custom.js, css"""
|
||||
)
|
||||
def _static_custom_path_default(self):
|
||||
|
||||
@default('static_custom_path')
|
||||
def _default_static_custom_path(self):
|
||||
return [
|
||||
os.path.join(d, 'custom') for d in (
|
||||
self.config_dir,
|
||||
@ -715,16 +741,21 @@ class NotebookApp(JupyterApp):
|
||||
Should be in the form of an HTTP origin: ws[s]://hostname[:port]
|
||||
"""
|
||||
)
|
||||
|
||||
mathjax_url = Unicode("", config=True,
|
||||
help="""The url for MathJax.js."""
|
||||
)
|
||||
def _mathjax_url_default(self):
|
||||
|
||||
@default('mathjax_url')
|
||||
def _default_mathjax_url(self):
|
||||
if not self.enable_mathjax:
|
||||
return u''
|
||||
static_url_prefix = self.tornado_settings.get("static_url_prefix", "static")
|
||||
return url_path_join(static_url_prefix, 'components', 'MathJax', 'MathJax.js')
|
||||
|
||||
def _mathjax_url_changed(self, name, old, new):
|
||||
@observe('mathjax_url')
|
||||
def _update_mathjax_url(self, change):
|
||||
new = change['new']
|
||||
if new and not self.enable_mathjax:
|
||||
# enable_mathjax=False overrides mathjax_url
|
||||
self.mathjax_url = u''
|
||||
@ -735,8 +766,9 @@ class NotebookApp(JupyterApp):
|
||||
help="""The MathJax.js configuration file that is to be used."""
|
||||
)
|
||||
|
||||
def _mathjax_config_changed(self, name, old, new):
|
||||
self.log.info("Using MathJax configuration file: %s", new)
|
||||
@observe('mathjax_config')
|
||||
def _update_mathjax_config(self, change):
|
||||
self.log.info("Using MathJax configuration file: %s", change['new'])
|
||||
|
||||
contents_manager_class = Type(
|
||||
default_value=FileContentsManager,
|
||||
@ -744,11 +776,13 @@ class NotebookApp(JupyterApp):
|
||||
config=True,
|
||||
help='The notebook manager class to use.'
|
||||
)
|
||||
|
||||
kernel_manager_class = Type(
|
||||
default_value=MappingKernelManager,
|
||||
config=True,
|
||||
help='The kernel manager class to use.'
|
||||
)
|
||||
|
||||
session_manager_class = Type(
|
||||
default_value=SessionManager,
|
||||
config=True,
|
||||
@ -796,7 +830,8 @@ class NotebookApp(JupyterApp):
|
||||
|
||||
info_file = Unicode()
|
||||
|
||||
def _info_file_default(self):
|
||||
@default('info_file')
|
||||
def _default_info_file(self):
|
||||
info_file = "nbserver-%s.json" % os.getpid()
|
||||
return os.path.join(self.runtime_dir, info_file)
|
||||
|
||||
@ -805,10 +840,12 @@ class NotebookApp(JupyterApp):
|
||||
DISABLED: use %pylab or %matplotlib in the notebook to enable matplotlib.
|
||||
"""
|
||||
)
|
||||
def _pylab_changed(self, name, old, new):
|
||||
|
||||
@observe('pylab')
|
||||
def _update_pylab(self, change):
|
||||
"""when --pylab is specified, display a warning and exit"""
|
||||
if new != 'warn':
|
||||
backend = ' %s' % new
|
||||
backend = ' %s' % change['new']
|
||||
else:
|
||||
backend = ''
|
||||
self.log.error("Support for specifying --pylab on the command line has been removed.")
|
||||
@ -821,21 +858,22 @@ class NotebookApp(JupyterApp):
|
||||
help="The directory to use for notebooks and kernels."
|
||||
)
|
||||
|
||||
def _notebook_dir_default(self):
|
||||
@default('notebook_dir')
|
||||
def _default_notebook_dir(self):
|
||||
if self.file_to_run:
|
||||
return os.path.dirname(os.path.abspath(self.file_to_run))
|
||||
else:
|
||||
return py3compat.getcwd()
|
||||
|
||||
def _notebook_dir_validate(self, value, trait):
|
||||
@validate('notebook_dir')
|
||||
def _notebook_dir_validate(self, proposal):
|
||||
value = proposal['value']
|
||||
# Strip any trailing slashes
|
||||
# *except* if it's root
|
||||
_, path = os.path.splitdrive(value)
|
||||
if path == os.sep:
|
||||
return value
|
||||
|
||||
value = value.rstrip(os.sep)
|
||||
|
||||
if not os.path.isabs(value):
|
||||
# If we receive a non-absolute path, make it absolute.
|
||||
value = os.path.abspath(value)
|
||||
@ -843,9 +881,11 @@ class NotebookApp(JupyterApp):
|
||||
raise TraitError("No such notebook dir: %r" % value)
|
||||
return value
|
||||
|
||||
def _notebook_dir_changed(self, name, old, new):
|
||||
@observe('notebook_dir')
|
||||
def _update_notebook_dir(self, change):
|
||||
"""Do a bit of validation of the notebook dir."""
|
||||
# setting App.notebook_dir implies setting notebook and kernel dirs as well
|
||||
new = change['new']
|
||||
self.config.FileContentsManager.root_dir = new
|
||||
self.config.MappingKernelManager.root_dir = new
|
||||
|
||||
@ -853,9 +893,11 @@ class NotebookApp(JupyterApp):
|
||||
server_extensions = List(Unicode(), config=True,
|
||||
help=("DEPRECATED use the nbserver_extensions dict instead")
|
||||
)
|
||||
def _server_extensions_changed(self, name, old, new):
|
||||
|
||||
@observe('server_extensions')
|
||||
def _update_server_extensions(self, change):
|
||||
self.log.warning("server_extensions is deprecated, use nbserver_extensions")
|
||||
self.server_extensions = new
|
||||
self.server_extensions = change['new']
|
||||
|
||||
nbserver_extensions = Dict({}, config=True,
|
||||
help=("Dict of Python modules to load as notebook server extensions."
|
||||
|
@ -7,7 +7,7 @@ import os.path
|
||||
|
||||
from traitlets.config.manager import BaseJSONConfigManager, recursive_update
|
||||
from jupyter_core.paths import jupyter_config_dir, jupyter_config_path
|
||||
from traitlets import Unicode, Instance, List
|
||||
from traitlets import Unicode, Instance, List, observe, default
|
||||
from traitlets.config import LoggingConfigurable
|
||||
|
||||
|
||||
@ -35,16 +35,23 @@ class ConfigManager(LoggingConfigurable):
|
||||
# Private API
|
||||
|
||||
read_config_path = List(Unicode())
|
||||
def _read_config_path_default(self):
|
||||
|
||||
@default('read_config_path')
|
||||
def _default_read_config_path(self):
|
||||
return [os.path.join(p, 'nbconfig') for p in jupyter_config_path()]
|
||||
|
||||
write_config_dir = Unicode()
|
||||
def _write_config_dir_default(self):
|
||||
|
||||
@default('write_config_dir')
|
||||
def _default_write_config_dir(self):
|
||||
return os.path.join(jupyter_config_dir(), 'nbconfig')
|
||||
|
||||
write_config_manager = Instance(BaseJSONConfigManager)
|
||||
def _write_config_manager_default(self):
|
||||
|
||||
@default('write_config_manager')
|
||||
def _default_write_config_manager(self):
|
||||
return BaseJSONConfigManager(config_dir=self.write_config_dir)
|
||||
|
||||
def _write_config_dir_changed(self, name, old, new):
|
||||
@observe('write_config_dir')
|
||||
def _update_write_config_dir(self, change):
|
||||
self.write_config_manager = BaseJSONConfigManager(config_dir=self.write_config_dir)
|
||||
|
@ -17,9 +17,8 @@ from .filecheckpoints import FileCheckpoints
|
||||
from .fileio import FileManagerMixin
|
||||
from .manager import ContentsManager
|
||||
|
||||
|
||||
from ipython_genutils.importstring import import_item
|
||||
from traitlets import Any, Unicode, Bool, TraitError
|
||||
from traitlets import Any, Unicode, Bool, TraitError, observe, default, validate
|
||||
from ipython_genutils.py3compat import getcwd, string_types
|
||||
from . import tz
|
||||
from notebook.utils import (
|
||||
@ -59,14 +58,17 @@ class FileContentsManager(FileManagerMixin, ContentsManager):
|
||||
|
||||
root_dir = Unicode(config=True)
|
||||
|
||||
def _root_dir_default(self):
|
||||
@default('root_dir')
|
||||
def _default_root_dir(self):
|
||||
try:
|
||||
return self.parent.notebook_dir
|
||||
except AttributeError:
|
||||
return getcwd()
|
||||
|
||||
save_script = Bool(False, config=True, help='DEPRECATED, use post_save_hook. Will be removed in Notebook 5.0')
|
||||
def _save_script_changed(self):
|
||||
|
||||
@observe('save_script')
|
||||
def _update_save_script(self):
|
||||
self.log.warning("""
|
||||
`--script` is deprecated and will be removed in notebook 5.0.
|
||||
|
||||
@ -101,12 +103,15 @@ class FileContentsManager(FileManagerMixin, ContentsManager):
|
||||
- contents_manager: this ContentsManager instance
|
||||
"""
|
||||
)
|
||||
def _post_save_hook_changed(self, name, old, new):
|
||||
if new and isinstance(new, string_types):
|
||||
self.post_save_hook = import_item(self.post_save_hook)
|
||||
elif new:
|
||||
if not callable(new):
|
||||
raise TraitError("post_save_hook must be callable")
|
||||
|
||||
@validate('post_save_hook')
|
||||
def _validate_post_save_hook(self, proposal):
|
||||
value = proposal['value']
|
||||
if isinstance(value, string_types):
|
||||
value = import_item(value)
|
||||
if not callable(value):
|
||||
raise TraitError("post_save_hook must be callable")
|
||||
return value
|
||||
|
||||
def run_post_save_hook(self, model, os_path):
|
||||
"""Run the post-save hook if defined, and log errors"""
|
||||
@ -117,14 +122,16 @@ class FileContentsManager(FileManagerMixin, ContentsManager):
|
||||
except Exception:
|
||||
self.log.error("Post-save hook failed on %s", os_path, exc_info=True)
|
||||
|
||||
def _root_dir_changed(self, name, old, new):
|
||||
@validate('root_dir')
|
||||
def _validate_root_dir(self, proposal):
|
||||
"""Do a bit of validation of the root_dir."""
|
||||
if not os.path.isabs(new):
|
||||
value = proposal['value']
|
||||
if not os.path.isabs(value):
|
||||
# If we receive a non-absolute path, make it absolute.
|
||||
self.root_dir = os.path.abspath(new)
|
||||
return
|
||||
if not os.path.isdir(new):
|
||||
raise TraitError("%r is not a directory" % new)
|
||||
value = os.path.abspath(value)
|
||||
if not os.path.isdir(value):
|
||||
raise TraitError("%r is not a directory" % value)
|
||||
return value
|
||||
|
||||
def _checkpoints_class_default(self):
|
||||
return FileCheckpoints
|
||||
|
@ -24,6 +24,8 @@ from traitlets import (
|
||||
TraitError,
|
||||
Type,
|
||||
Unicode,
|
||||
validate,
|
||||
default,
|
||||
)
|
||||
from ipython_genutils.py3compat import string_types
|
||||
|
||||
@ -91,12 +93,15 @@ class ContentsManager(LoggingConfigurable):
|
||||
- contents_manager: this ContentsManager instance
|
||||
"""
|
||||
)
|
||||
def _pre_save_hook_changed(self, name, old, new):
|
||||
if new and isinstance(new, string_types):
|
||||
self.pre_save_hook = import_item(self.pre_save_hook)
|
||||
elif new:
|
||||
if not callable(new):
|
||||
raise TraitError("pre_save_hook must be callable")
|
||||
|
||||
@validate('pre_save_hook')
|
||||
def _validate_pre_save_hook(self, proposal):
|
||||
value = proposal['value']
|
||||
if isinstance(value, string_types):
|
||||
value = import_item(self.pre_save_hook)
|
||||
if not callable(value):
|
||||
raise TraitError("pre_save_hook must be callable")
|
||||
return value
|
||||
|
||||
def run_pre_save_hook(self, model, path, **kwargs):
|
||||
"""Run the pre-save hook if defined, and log errors"""
|
||||
@ -111,10 +116,12 @@ class ContentsManager(LoggingConfigurable):
|
||||
checkpoints = Instance(Checkpoints, config=True)
|
||||
checkpoints_kwargs = Dict(config=True)
|
||||
|
||||
def _checkpoints_default(self):
|
||||
@default('checkpoints')
|
||||
def _default_checkpoints(self):
|
||||
return self.checkpoints_class(**self.checkpoints_kwargs)
|
||||
|
||||
def _checkpoints_kwargs_default(self):
|
||||
@default('checkpoints_kwargs')
|
||||
def _default_checkpoints_kwargs(self):
|
||||
return dict(
|
||||
parent=self,
|
||||
log=self.log,
|
||||
|
@ -14,7 +14,7 @@ from tornado.concurrent import Future
|
||||
from tornado.ioloop import IOLoop
|
||||
|
||||
from jupyter_client.multikernelmanager import MultiKernelManager
|
||||
from traitlets import List, Unicode, TraitError
|
||||
from traitlets import List, Unicode, TraitError, default, validate
|
||||
|
||||
from notebook.utils import to_os_path
|
||||
from ipython_genutils.py3compat import getcwd
|
||||
@ -23,27 +23,31 @@ from ipython_genutils.py3compat import getcwd
|
||||
class MappingKernelManager(MultiKernelManager):
|
||||
"""A KernelManager that handles notebook mapping and HTTP error handling"""
|
||||
|
||||
def _kernel_manager_class_default(self):
|
||||
@default('kernel_manager_class')
|
||||
def _default_kernel_manager_class(self):
|
||||
return "jupyter_client.ioloop.IOLoopKernelManager"
|
||||
|
||||
kernel_argv = List(Unicode())
|
||||
|
||||
root_dir = Unicode(config=True)
|
||||
|
||||
def _root_dir_default(self):
|
||||
@default('root_dir')
|
||||
def _default_root_dir(self):
|
||||
try:
|
||||
return self.parent.notebook_dir
|
||||
except AttributeError:
|
||||
return getcwd()
|
||||
|
||||
def _root_dir_changed(self, name, old, new):
|
||||
@validate('root_dir')
|
||||
def _update_root_dir(self, proposal):
|
||||
"""Do a bit of validation of the root dir."""
|
||||
if not os.path.isabs(new):
|
||||
value = proposal['value']
|
||||
if not os.path.isabs(value):
|
||||
# If we receive a non-absolute path, make it absolute.
|
||||
self.root_dir = os.path.abspath(new)
|
||||
return
|
||||
if not os.path.exists(new) or not os.path.isdir(new):
|
||||
raise TraitError("kernel root dir %r is not a directory" % new)
|
||||
value = os.path.abspath(value)
|
||||
if not os.path.exists(value) or not os.path.isdir(value):
|
||||
raise TraitError("kernel root dir %r is not a directory" % value)
|
||||
return value
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# Methods for managing kernels and sessions
|
||||
|
4
setup.py
4
setup.py
@ -78,7 +78,7 @@ for more information.
|
||||
version = version,
|
||||
scripts = glob(pjoin('scripts', '*')),
|
||||
packages = find_packages(),
|
||||
package_data = find_package_data(),
|
||||
package_data = find_package_data(),
|
||||
author = 'Jupyter Development Team',
|
||||
author_email = 'jupyter@googlegroups.com',
|
||||
url = 'http://jupyter.org',
|
||||
@ -146,7 +146,7 @@ install_requires = [
|
||||
'jinja2',
|
||||
'tornado>=4',
|
||||
'ipython_genutils',
|
||||
'traitlets',
|
||||
'traitlets>=4.2.1',
|
||||
'jupyter_core',
|
||||
'jupyter_client',
|
||||
'nbformat',
|
||||
|
Loading…
Reference in New Issue
Block a user