Source code for bokeh.io.saving

#-----------------------------------------------------------------------------
# Copyright (c) Anaconda, Inc., and Bokeh Contributors.
# All rights reserved.
#
# The full license is in the file LICENSE.txt, distributed with this software.
#-----------------------------------------------------------------------------
'''

'''

#-----------------------------------------------------------------------------
# Boilerplate
#-----------------------------------------------------------------------------
from __future__ import annotations

import logging # isort:skip
log = logging.getLogger(__name__)

#-----------------------------------------------------------------------------
# Imports
#-----------------------------------------------------------------------------

# Standard library imports
from os.path import abspath, expanduser
from typing import TYPE_CHECKING, Sequence

# External imports
from jinja2 import Template

# Bokeh imports
from ..core.templates import FILE
from ..resources import Resources
from ..settings import settings
from .state import curstate
from .util import default_filename

if TYPE_CHECKING:
    from ..core.types import PathLike
    from ..models.ui import UIElement
    from ..resources import ResourcesLike
    from ..themes import Theme
    from .state import State

#-----------------------------------------------------------------------------
# Globals and constants
#-----------------------------------------------------------------------------

DEFAULT_TITLE = "Bokeh Plot"

__all__ = (
    'save',
)

#-----------------------------------------------------------------------------
# General API
#-----------------------------------------------------------------------------

[docs] def save(obj: UIElement | Sequence[UIElement], filename: PathLike | None = None, resources: ResourcesLike | None = None, title: str | None = None, template: Template | str | None = None, state: State | None = None) -> str: ''' Save an HTML file with the data for the current document. Will fall back to the default output state (or an explicitly provided :class:`State` object) for ``filename``, ``resources``, or ``title`` if they are not provided. If the filename is not given and not provided via output state, it is derived from the script name (e.g. ``/foo/myplot.py`` will create ``/foo/myplot.html``) Args: obj (UIElement object) : a Layout (Row/Column), Plot or Widget object to display filename (PathLike, e.g. str, Path, optional) : filename to save document under (default: None) If None, use the default state configuration. resources (Resources or ResourcesMode, optional) : A Resources config to use (default: None) If None, use the default state configuration, if there is one. otherwise use ``resources.INLINE``. title (str, optional) : a title for the HTML document (default: None) If None, use the default state title value, if there is one. Otherwise, use "Bokeh Plot" template (Template, str, optional) : HTML document template (default: FILE) A Jinja2 Template, see bokeh.core.templates.FILE for the required template parameters state (State, optional) : A :class:`State` object. If None, then the current default implicit state is used. (default: None). Returns: str: the filename where the HTML file is saved. ''' if state is None: state = curstate() theme = state.document.theme filename, resources, title = _get_save_args(state, filename, resources, title) _save_helper(obj, filename, resources, title, template, theme) return abspath(expanduser(filename))
#----------------------------------------------------------------------------- # Dev API #----------------------------------------------------------------------------- #----------------------------------------------------------------------------- # Private API #----------------------------------------------------------------------------- def _get_save_args(state: State, filename: PathLike | None, resources: ResourcesLike | None, title: str | None) -> tuple[PathLike, Resources, str]: ''' ''' filename, is_default_filename = _get_save_filename(state, filename) resources = _get_save_resources(state, resources, is_default_filename) title = _get_save_title(state, title, is_default_filename) return filename, resources, title def _get_save_filename(state: State, filename: PathLike | None) -> tuple[PathLike, bool]: if filename is not None: return filename, False if state.file and not settings.ignore_filename(): return state.file.filename, False return default_filename("html"), True def _get_save_resources(state: State, resources: ResourcesLike | None, suppress_warning: bool) -> Resources: if resources is not None: if isinstance(resources, Resources): return resources else: return Resources(mode=resources) if state.file: return state.file.resources if not suppress_warning: from ..util.warnings import warn warn("save() called but no resources were supplied and output_file(...) was never called, defaulting to resources.CDN") return Resources(mode=settings.resources()) def _get_save_title(state: State, title: str | None, suppress_warning: bool) -> str: if title is not None: return title if state.file: return state.file.title if not suppress_warning: from ..util.warnings import warn warn("save() called but no title was supplied and output_file(...) was never called, using default title 'Bokeh Plot'") return DEFAULT_TITLE def _save_helper(obj: UIElement | Sequence[UIElement], filename: PathLike, resources: Resources | None, title: str | None, template: Template | str | None, theme: Theme | None = None) -> None: ''' ''' from ..embed import file_html html = file_html(obj, resources=resources, title=title, template=template or FILE, theme=theme) with open(filename, mode="w", encoding="utf-8") as f: f.write(html) #----------------------------------------------------------------------------- # Code #-----------------------------------------------------------------------------