''' Control global configuration options with environment variables.
'''
from __future__ import absolute_import
import codecs
import logging
import os
from os.path import join, abspath, isdir
from .util.paths import ROOT_DIR, bokehjsdir
class Settings(object):
''' A class to collect global, overridable Bokeh configuration settings.
'''
_prefix = "BOKEH_"
debugjs = False
@property
def _environ(self):
return os.environ
def _get(self, key, default=None):
return self._environ.get(self._prefix + key, default)
@property
def _is_dev(self):
return self._get_bool("DEV", False)
@property
def dev(self):
return self._is_dev
def _dev_or_default(self, default, dev):
return dev if dev is not None and self._is_dev else default
def _get_str(self, key, default, dev=None):
return self._get(key, self._dev_or_default(default, dev))
def _get_int(self, key, default, dev=None):
return int(self._get(key, self._dev_or_default(default, dev)))
def _get_bool(self, key, default, dev=None):
value = self._get(key)
if value is None:
value = self._dev_or_default(default, dev)
elif value.lower() in ["true", "yes", "on", "1"]:
value = True
elif value.lower() in ["false", "no", "off", "0"]:
value = False
else:
raise ValueError("invalid value %r for boolean property %s%s" % (value, self._prefix, key))
return value
def browser(self, default=None):
''' Set the default browser that Bokeh should use to show documents
with.
'''
return self._get_str("BROWSER", default, "none")
def resources(self, default=None):
''' Set (override) the type of resources that Bokeh should use when
outputting documents.
'''
return self._get_str("RESOURCES", default, "absolute-dev")
def rootdir(self, default=None):
''' Set the root directory for "relative" resources.
'''
return self._get_str("ROOTDIR", default)
def version(self, default=None):
''' Set (override) the standard reported Bokeh version.
'''
return self._get_str("VERSION", default)
def docs_cdn(self, default=None):
''' Set the version of BokehJS should use for CDN resources when
building the docs.
'''
return self._get_str("DOCS_CDN", default)
def docs_version(self, default=None):
''' Set the version to use for building the docs.
'''
return self._get_str("DOCS_VERSION", default)
def docs_missing_api_key_ok(self, default=False):
''' Control whether a missing google API key should cause the
docs build to fail immediately.
'''
return self._get_str("DOCS_MISSING_API_KEY_OK", default)
def minified(self, default=None):
''' Set whether Bokeh should use minified BokehJS resources.
'''
return self._get_bool("MINIFIED", default, False)
def log_level(self, default=None):
''' Set the log level for JavaScript BokehJS code.
'''
return self._get_str("LOG_LEVEL", default, "debug")
def py_log_level(self, default='none'):
''' Set the log level for python Bokeh code.
'''
level = self._get_str("PY_LOG_LEVEL", default, "debug")
LEVELS = {'trace': logging.TRACE,
'debug': logging.DEBUG,
'info' : logging.INFO,
'warn' : logging.WARNING,
'error': logging.ERROR,
'fatal': logging.CRITICAL,
'none' : None}
return LEVELS[level]
def pretty(self, default=None):
''' Set whether JSON strings should be pretty-printed.
'''
return self._get_bool("PRETTY", default, True)
def simple_ids(self, default=None):
''' Set whether Bokeh should generate simple numeric model IDs.
'''
return self._get_bool("SIMPLE_IDS", default, True)
def strict(self, default=None):
''' Set whether validation should be performed strictly.
'''
return self._get_bool("STRICT", default, False)
def secret_key(self, default=None):
''' Set the secret key.
Should be a long, cryptographically-random secret unique the
Bokeh deployment.
'''
return self._get_str("SECRET_KEY", default)
def secret_key_bytes(self):
''' Return the secret_key, converted to bytes and cached.
'''
if not hasattr(self, '_secret_key_bytes'):
key = self.secret_key()
if key is None:
self._secret_key_bytes = None
else:
self._secret_key_bytes = codecs.encode(key, "utf-8")
return self._secret_key_bytes
def sign_sessions(self, default=False):
''' Set whether the server should only allow sessions signed with
our secret key.
If True, BOKEH_SECRET_KEY must also be set.
'''
return self._get_bool("SIGN_SESSIONS", default)
def perform_document_validation(self, default=True):
''' Set whether Bokeh should perform validation checks on documents.
'''
return self._get_bool("VALIDATE_DOC", default)
# Server settings go here:
def bokehjssrcdir(self):
''' The absolute path of the BokehJS source code in the installed
Bokeh source tree.
'''
if self._is_dev or self.debugjs:
bokehjssrcdir = abspath(join(ROOT_DIR, '..', 'bokehjs', 'src'))
if isdir(bokehjssrcdir):
return bokehjssrcdir
return None
def bokehjsdir(self):
'''
'''
return bokehjsdir(self._is_dev or self.debugjs)
def js_files(self):
''' The JS files in the BokehJS directory.
'''
bokehjsdir = self.bokehjsdir()
js_files = []
for root, dirnames, files in os.walk(bokehjsdir):
for fname in files:
if fname.endswith(".js"):
js_files.append(join(root, fname))
return js_files
def css_files(self):
''' The CSS files in the BokehJS directory.
'''
bokehjsdir = self.bokehjsdir()
js_files = []
for root, dirnames, files in os.walk(bokehjsdir):
for fname in files:
if fname.endswith(".css"):
js_files.append(join(root, fname))
return js_files
def nodejs_path(self, default=None):
return self._get_str("NODEJS_PATH", default)
def phantomjs_path(self, default=None):
return self._get_str("PHANTOMJS_PATH", default)
def ignore_filename(self):
return self._get_bool("IGNORE_FILENAME", False)
#: A global settings object that other parts of Bokeh can refer to.
#:
#:
#: ``BOKEH_BROWSER`` --- What browser to use when opening plots.
#:
#: Valid values are any of the browser names understood by the python
#: standard library webbrowser_ module.
#:
#: ``BOKEH_DEV`` --- Whether to use development mode.
#:
#: This uses absolute paths to development (non-minified) BokehJS components,
#: sets logging to ``debug``, makes generated HTML and JSON human-readable,
#: etc.
#:
#: This is a meta variable equivalent to the following environment variables:
#:
#: - ``BOKEH_BROWSER=none``
#: - ``BOKEH_LOG_LEVEL=debug``
#: - ``BOKEH_MINIFIED=false``
#: - ``BOKEH_PRETTY=true``
#: - ``BOKEH_PY_LOG_LEVEL=debug``
#: - ``BOKEH_RESOURCES=absolute-dev``
#: - ``BOKEH_SIMPLE_IDS=true``
#:
#: Accepted values are ``yes``/``no``, ``true``/``false`` or ``0``/``1``.
#:
#: ``BOKEH_DOCS_CDN`` --- What version of BokehJS to use when building sphinx
#: `~bokeh.resources.Resources` class reference for full details.
#:
#: ``BOKEH_DOCS_VERSION`` --- What version of Bokeh to show when building sphinx docs locally.
#:
#: Useful for re-deployment purposes.
#:
#: Set to ``"local"`` to use a locally built dev version of BokehJS.
#:
#: .. note::
#: This variable is only used when building documentation from the
#: development version.
#:
#: ``BOKEH_DOCS_CSS_SERVER`` --- Where to get the CSS stylesheet from.
#:
#: By default use CSS from bokehplots.com
#:
#: .. note::
#: This variable is only used when building documentation from the
#: development version.
#:
#: Set to ``"local"`` to use a locally built dev version of BokehJS.
#:
#: ``BOKEH_DOCS_MISSING_API_KEY_OK`` --- Whether the docs build should fail without GOOGLE_API_KEY set.
#:
#: By default, set to `no`, which means the docs build will stop immediately
#: if the GOOGLE_API_KEY environment variable is missing. Set to `yes` to
#: enable docs builds to proceed (but with non-functional Google Maps examples).
#: Useful for development.
#:
#: ``BOKEH_LOG_LEVEL`` --- The BokehJS console logging level to use.
#:
#: Valid values are, in order of increasing severity:
#:
#: - ``trace``
#: - ``debug``
#: - ``info``
#: - ``warn``
#: - ``error``
#: - ``fatal``
#:
#: The default logging level is ``info``.
#:
#: .. note::
#: When running server examples, it is the value of this
#: ``BOKEH_LOG_LEVEL`` that is set for the server that matters.
#:
#: ``BOKEH_MINIFIED`` --- Whether to emit minified JavaScript for ``bokeh.js``.
#:
#: Accepted values are ``yes``/``no``, ``true``/``false`` or ``0``/``1``.
#:
#: ``BOKEH_PRETTY`` --- Whether to emit "pretty printed" JSON.
#:
#: Accepted values are ``yes``/``no``, ``true``/``false`` or ``0``/``1``.
#:
#: ``BOKEH_PY_LOG_LEVEL`` --- The Python logging level to set.
#:
#: As in the JS side, valid values are, in order of increasing severity:
#:
#: - ``trace``
#: - ``debug``
#: - ``info``
#: - ``warn``
#: - ``error``
#: - ``fatal``
#: - ``none``
#:
#: The default logging level is ``none``.
#:
#: ``BOKEH_RESOURCES`` --- What kind of BokehJS resources to configure.
#:
#: For example: ``inline``, ``cdn``, ``server``. See the
#: :class:`~bokeh.core.resources.Resources` class reference for full details.
#:
#: ``BOKEH_ROOTDIR`` --- Root directory to use with ``relative`` resources.
#:
#: See the :class:`~bokeh.resources.Resources` class reference for full
#: details.
#:
#: ``BOKEH_SIMPLE_IDS`` --- Whether to generate human-friendly object IDs.
#:
#: Accepted values are ``yes``/``no``, ``true``/``false`` or ``0``/``1``.
#: Normally Bokeh generates UUIDs for object identifiers. Setting this variable
#: to an affirmative value will result in more friendly simple numeric IDs
#: counting up from 1000.
#:
#: ``BOKEH_VERSION`` --- What version of BokehJS to use with ``cdn`` resources.
#:
#: See the :class:`~bokeh.resources.Resources` class reference for full details.
#:
#: .. _webbrowser: https://docs.python.org/2/library/webbrowser.html
settings = Settings()
del Settings
if settings.secret_key() is not None:
if len(settings.secret_key()) < 32:
import warnings
warnings.warn("BOKEH_SECRET_KEY is recommended to have at least 32 bytes of entropy chosen with a cryptographically-random algorithm")
if settings.sign_sessions() and settings.secret_key() is None:
import warnings
warnings.warn("BOKEH_SECRET_KEY must be set if BOKEH_SIGN_SESSIONS is set to true")