1#-----------------------------------------------------------------------------
2# Copyright (c) 2012 - 2021, Anaconda, Inc., and Bokeh Contributors.
3# All rights reserved.
4#
5# The full license is in the file LICENSE.txt, distributed with this software.
6#-----------------------------------------------------------------------------
7'''
8
9'''
10
11#-----------------------------------------------------------------------------
12# Boilerplate
13#-----------------------------------------------------------------------------
14import logging # isort:skip
15log = logging.getLogger(__name__)
16
17#-----------------------------------------------------------------------------
18# Imports
19#-----------------------------------------------------------------------------
20
21# Standard library imports
22from typing import Optional, Tuple, Union
23
24# Bokeh imports
25from ..core.json_encoder import serialize_json
26from ..core.templates import DOC_NB_JS
27from ..document import Document
28from ..model import Model
29from ..themes import Theme
30from .elements import div_for_render_item
31from .util import FromCurdoc, OutputDocumentFor, standalone_docs_json_and_render_items
32
33#-----------------------------------------------------------------------------
34# Globals and constants
35#-----------------------------------------------------------------------------
36
37__all__ = (
38    'notebook_content'
39)
40
41#-----------------------------------------------------------------------------
42# General API
43#-----------------------------------------------------------------------------
44
45#-----------------------------------------------------------------------------
46# Dev API
47#-----------------------------------------------------------------------------
48
49ThemeSource = Union[Theme, FromCurdoc, None]
50
51def notebook_content(model: Model, notebook_comms_target: Optional[str] = None, theme: ThemeSource = FromCurdoc) -> Tuple[str, str, Document]:
52    ''' Return script and div that will display a Bokeh plot in a Jupyter
53    Notebook.
54
55    The data for the plot is stored directly in the returned HTML.
56
57    Args:
58        model (Model) : Bokeh object to render
59
60        notebook_comms_target (str, optional) :
61            A target name for a Jupyter Comms object that can update
62            the document that is rendered to this notebook div
63
64        theme (Theme, optional) :
65            Defaults to the ``Theme`` instance in the current document.
66            Setting this to ``None`` uses the default theme or the theme
67            already specified in the document. Any other value must be an
68            instance of the ``Theme`` class.
69
70    Returns:
71        script, div, Document
72
73    .. note::
74        Assumes :func:`~bokeh.io.notebook.load_notebook` or the equivalent
75        has already been executed.
76
77    '''
78
79    if not isinstance(model, Model):
80        raise ValueError("notebook_content expects a single Model instance")
81
82    # Comms handling relies on the fact that the new_doc returned here
83    # has models with the same IDs as they were started with
84    with OutputDocumentFor([model], apply_theme=theme, always_new=True) as new_doc:
85        (docs_json, [render_item]) = standalone_docs_json_and_render_items([model])
86
87    div = div_for_render_item(render_item)
88
89    render_item = render_item.to_json()
90    if notebook_comms_target:
91        render_item["notebook_comms_target"] = notebook_comms_target
92
93    script = DOC_NB_JS.render(
94        docs_json=serialize_json(docs_json),
95        render_items=serialize_json([render_item]),
96    )
97
98    return script, div, new_doc
99
100#-----------------------------------------------------------------------------
101# Private API
102#-----------------------------------------------------------------------------
103
104#-----------------------------------------------------------------------------
105# Code
106#-----------------------------------------------------------------------------
107