This docs on this page refers to a PREVIOUS VERSION. For the latest stable release, go to https://docs.bokeh.org/

Archived docs for versions <= 1.0.4 have had to be modified from their original published configuration, and may be missing some features (e.g. source listing)

All users are encourage to update to version 1.1 or later, as soon as they are able.

bokeh.command.subcommands.file_output — Bokeh 1.0.3 documentation

Source code for bokeh.command.subcommands.file_output

#-----------------------------------------------------------------------------
# Copyright (c) 2012 - 2018, Anaconda, Inc. All rights reserved.
#
# Powered by the Bokeh Development Team.
#
# The full license is in the file LICENSE.txt, distributed with this software.
#-----------------------------------------------------------------------------
''' Abstract base class for subcommands that output to a file (or stdout).

'''

#-----------------------------------------------------------------------------
# Boilerplate
#-----------------------------------------------------------------------------
from __future__ import absolute_import, division, print_function, unicode_literals

import logging
log = logging.getLogger(__name__)

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

# Standard library imports
from abc import abstractmethod
import argparse
import io

# External imports

# Bokeh imports
from bokeh.util.string import decode_utf8

from ..subcommand import Subcommand
from ..util import build_single_handler_applications, die

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

__all__ = (
    'FileOutputSubcommand',
)

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

#-----------------------------------------------------------------------------
# Dev API
#-----------------------------------------------------------------------------

[docs]class FileOutputSubcommand(Subcommand): ''' Abstract subcommand to output applications as some type of file. ''' extension = None # subtype must set this to file extension
[docs] @classmethod def files_arg(cls, output_type_name): ''' Returns a positional arg for ``files`` to specify file inputs to the command. Subclasses should include this to their class ``args``. Example: .. code-block:: python class Foo(FileOutputSubcommand): args = ( FileOutputSubcommand.files_arg("FOO"), # more args for Foo ) + FileOutputSubcommand.other_args() ''' return ('files', dict( metavar='DIRECTORY-OR-SCRIPT', nargs='+', help=("The app directories or scripts to generate %s for" % (output_type_name)), default=None ))
[docs] @classmethod def other_args(cls): ''' Return args for ``-o`` / ``--output`` to specify where output should be written, and for a ``--args`` to pass on any additional command line args to the subcommand. Subclasses should append these to their class ``args``. Example: .. code-block:: python class Foo(FileOutputSubcommand): args = ( FileOutputSubcommand.files_arg("FOO"), # more args for Foo ) + FileOutputSubcommand.other_args() ''' return ( (('-o', '--output'), dict( metavar='FILENAME', action='append', type=str, help="Name of the output file or - for standard output." )), ('--args', dict( metavar='COMMAND-LINE-ARGS', nargs=argparse.REMAINDER, help="Any command line arguments remaining are passed on to the application handler", )), )
[docs] def filename_from_route(self, route, ext): ''' ''' if route == "/": base = "index" else: base = route[1:] return "%s.%s" % (base, ext)
[docs] def invoke(self, args): ''' ''' argvs = { f : args.args for f in args.files} applications = build_single_handler_applications(args.files, argvs) if args.output is None: outputs = [] else: outputs = list(args.output) # copy so we can pop from it if len(outputs) > len(applications): die("--output/-o was given too many times (%d times for %d applications)" % (len(outputs), len(applications))) for (route, app) in applications.items(): doc = app.create_document() if len(outputs) > 0: filename = outputs.pop(0) else: filename = self.filename_from_route(route, self.extension) self.write_file(args, filename, doc)
[docs] def write_file(self, args, filename, doc): ''' ''' contents = self.file_contents(args, doc) if filename == '-': print(decode_utf8(contents)) else: with io.open(filename, "w", encoding="utf-8") as file: file.write(decode_utf8(contents)) self.after_write_file(args, filename, doc)
# can be overridden optionally
[docs] def after_write_file(self, args, filename, doc): ''' ''' pass
[docs] @abstractmethod def file_contents(self, args, doc): ''' Subtypes must override this to return the contents of the output file for the given doc. ''' raise NotImplementedError("file_contents")
#----------------------------------------------------------------------------- # Private API #----------------------------------------------------------------------------- #----------------------------------------------------------------------------- # Code #-----------------------------------------------------------------------------