Example #1
0
def modify_document(self, doc):
    from bokeh.io.doc import set_curdoc as bk_set_curdoc
    from ..config import config

    if config.autoreload:
        path = self._runner.path
        argv = self._runner._argv
        handler = type(self)(filename=path, argv=argv)
        self._runner = handler._runner

    module = self._runner.new_module()

    # If no module was returned it means the code runner has some permanent
    # unfixable problem, e.g. the configured source code has a syntax error
    if module is None:
        return

    # One reason modules are stored is to prevent the module
    # from being gc'd before the document is. A symptom of a
    # gc'd module is that its globals become None. Additionally
    # stored modules are used to provide correct paths to
    # custom models resolver.
    sys.modules[module.__name__] = module
    doc._modules.append(module)

    old_doc = curdoc()
    bk_set_curdoc(doc)
    old_io = self._monkeypatch_io()

    if config.autoreload:
        set_curdoc(doc)
        state.onload(autoreload_watcher)

    try:

        def post_check():
            newdoc = curdoc()
            # script is supposed to edit the doc not replace it
            if newdoc is not doc:
                raise RuntimeError("%s at '%s' replaced the output document" %
                                   (self._origin, self._runner.path))

        def handle_exception(handler, e):
            from bokeh.application.handlers.handler import handle_exception
            from ..pane import HTML

            # Clean up
            del sys.modules[module.__name__]
            doc._modules.remove(module)
            bokeh.application.handlers.code_runner.handle_exception = handle_exception
            tb = html.escape(traceback.format_exc())

            # Serve error
            HTML(
                f'<b>{type(e).__name__}</b>: {e}</br><pre style="overflow-y: scroll">{tb}</pre>',
                css_classes=['alert', 'alert-danger'],
                sizing_mode='stretch_width').servable()

        if config.autoreload:
            bokeh.application.handlers.code_runner.handle_exception = handle_exception
        self._runner.run(module, post_check)
    finally:
        self._unmonkeypatch_io(old_io)
        bk_set_curdoc(old_doc)
def modify_document(self, doc):
    from bokeh.io.doc import set_curdoc as bk_set_curdoc
    from ..config import config

    logger.info(LOG_SESSION_LAUNCHING, id(doc))

    if config.autoreload:
        path = self._runner.path
        argv = self._runner._argv
        handler = type(self)(filename=path, argv=argv)
        self._runner = handler._runner

    module = self._runner.new_module()

    # If no module was returned it means the code runner has some permanent
    # unfixable problem, e.g. the configured source code has a syntax error
    if module is None:
        return

    # One reason modules are stored is to prevent the module
    # from being gc'd before the document is. A symptom of a
    # gc'd module is that its globals become None. Additionally
    # stored modules are used to provide correct paths to
    # custom models resolver.
    sys.modules[module.__name__] = module
    doc.modules._modules.append(module)

    old_doc = curdoc()
    bk_set_curdoc(doc)

    if config.autoreload:
        set_curdoc(doc)
        state.onload(autoreload_watcher)

    sessions = []

    try:

        def post_check():
            newdoc = curdoc()
            # Do not let curdoc track modules when autoreload is enabled
            # otherwise it will erroneously complain that there is
            # a memory leak
            if config.autoreload:
                newdoc.modules._modules = []

            # script is supposed to edit the doc not replace it
            if newdoc is not doc:
                raise RuntimeError("%s at '%s' replaced the output document" %
                                   (self._origin, self._runner.path))

        def handle_exception(handler, e):
            from bokeh.application.handlers.handler import handle_exception
            from ..pane import HTML

            # Clean up
            del sys.modules[module.__name__]

            if hasattr(doc, 'modules'):
                doc.modules._modules.remove(module)
            else:
                doc._modules.remove(module)
            bokeh.application.handlers.code_runner.handle_exception = handle_exception
            tb = html.escape(traceback.format_exc())

            # Serve error
            HTML(
                f'<b>{type(e).__name__}</b>: {e}</br><pre style="overflow-y: scroll">{tb}</pre>',
                css_classes=['alert', 'alert-danger'],
                sizing_mode='stretch_width').servable()

        if config.autoreload:
            bokeh.application.handlers.code_runner.handle_exception = handle_exception

        state._launching.append(doc)
        with _monkeypatch_io(self._loggers):
            with patch_curdoc(doc):
                with profile_ctx(config.profiler) as sessions:
                    self._runner.run(module, post_check)

        def _log_session_destroyed(session_context):
            logger.info(LOG_SESSION_DESTROYED, id(doc))

        doc.on_session_destroyed(_log_session_destroyed)
    finally:
        state._launching.remove(doc)
        if config.profiler:
            try:
                path = doc.session_context.request.path
                state._profiles[(path, config.profiler)] += sessions
                state.param.trigger('_profiles')
            except Exception:
                pass
        bk_set_curdoc(old_doc)