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 os.path import abspath 23from warnings import warn 24 25# Bokeh imports 26from ..settings import settings 27from .state import curstate 28from .util import default_filename 29 30#----------------------------------------------------------------------------- 31# Globals and constants 32#----------------------------------------------------------------------------- 33 34DEFAULT_TITLE = "Bokeh Plot" 35 36__all__ = ( 37 'save', 38) 39 40#----------------------------------------------------------------------------- 41# General API 42#----------------------------------------------------------------------------- 43 44def save(obj, filename=None, resources=None, title=None, template=None, state=None, **kwargs): 45 ''' Save an HTML file with the data for the current document. 46 47 Will fall back to the default output state (or an explicitly provided 48 :class:`State` object) for ``filename``, ``resources``, or ``title`` if they 49 are not provided. If the filename is not given and not provided via output state, 50 it is derived from the script name (e.g. ``/foo/myplot.py`` will create 51 ``/foo/myplot.html``) 52 53 Args: 54 obj (LayoutDOM object) : a Layout (Row/Column), Plot or Widget object to display 55 56 filename (str, optional) : filename to save document under (default: None) 57 If None, use the default state configuration. 58 59 resources (Resources, optional) : A Resources config to use (default: None) 60 If None, use the default state configuration, if there is one. 61 otherwise use ``resources.INLINE``. 62 63 title (str, optional) : a title for the HTML document (default: None) 64 If None, use the default state title value, if there is one. 65 Otherwise, use "Bokeh Plot" 66 67 template (Template, optional) : HTML document template (default: FILE) 68 A Jinja2 Template, see bokeh.core.templates.FILE for the required template 69 parameters 70 71 state (State, optional) : 72 A :class:`State` object. If None, then the current default 73 implicit state is used. (default: None). 74 75 Returns: 76 str: the filename where the HTML file is saved. 77 78 ''' 79 80 if state is None: 81 state = curstate() 82 83 theme = state.document.theme 84 85 filename, resources, title = _get_save_args(state, filename, resources, title) 86 _save_helper(obj, filename, resources, title, template, theme) 87 return abspath(filename) 88 89#----------------------------------------------------------------------------- 90# Dev API 91#----------------------------------------------------------------------------- 92 93#----------------------------------------------------------------------------- 94# Private API 95#----------------------------------------------------------------------------- 96 97def _get_save_args(state, filename, resources, title): 98 ''' 99 100 ''' 101 filename, is_default_filename = _get_save_filename(state, filename) 102 103 resources = _get_save_resources(state, resources, is_default_filename) 104 105 title = _get_save_title(state, title, is_default_filename) 106 107 return filename, resources, title 108 109def _get_save_filename(state, filename): 110 if filename is not None: 111 return filename, False 112 113 if state.file and not settings.ignore_filename(): 114 return state.file['filename'], False 115 116 return default_filename("html"), True 117 118def _get_save_resources(state, resources, suppress_warning): 119 if resources is not None: 120 return resources 121 122 if state.file: 123 return state.file['resources'] 124 125 if not suppress_warning: 126 warn("save() called but no resources were supplied and output_file(...) was never called, defaulting to resources.CDN") 127 128 from ..resources import Resources 129 return Resources(mode=settings.resources()) 130 131def _get_save_title(state, title, suppress_warning): 132 if title is not None: 133 return title 134 135 if state.file: 136 return state.file['title'] 137 138 if not suppress_warning: 139 warn("save() called but no title was supplied and output_file(...) was never called, using default title 'Bokeh Plot'") 140 141 return DEFAULT_TITLE 142 143def _save_helper(obj, filename, resources, title, template, theme=None): 144 ''' 145 146 ''' 147 from ..embed import file_html 148 html = file_html(obj, resources, title=title, template=template, theme=theme) 149 150 with open(filename, mode="w", encoding="utf-8") as f: 151 f.write(html) 152 153#----------------------------------------------------------------------------- 154# Code 155#----------------------------------------------------------------------------- 156