Source code for bokeh.command.bootstrap
#-----------------------------------------------------------------------------
# Copyright (c) Anaconda, Inc., and Bokeh Contributors.
# All rights reserved.
#
# The full license is in the file LICENSE.txt, distributed with this software.
#-----------------------------------------------------------------------------
''' Provide a ``main`` function to run bokeh commands.
The following are equivalent:
* Running the ``bokeh`` command line script:
  .. code-block:: sh
      bokeh serve --show app.py
* Using ``python -m bokeh``:
  .. code-block:: sh
      python -m bokeh serve --show app.py
* Executing ``main`` programmatically:
  .. code-block:: python
      from bokeh.command.bootstrap import main
      main(["bokeh", "serve", "--show", "app.py"])
'''
#-----------------------------------------------------------------------------
# Boilerplate
#-----------------------------------------------------------------------------
from __future__ import annotations
import logging # isort:skip
log = logging.getLogger(__name__)
#-----------------------------------------------------------------------------
# Imports
#-----------------------------------------------------------------------------
# Standard library imports
import argparse
import sys
from typing import Sequence
# Bokeh imports
from bokeh import __version__
from bokeh.settings import settings
from bokeh.util.strings import nice_join
# Bokeh imports
from . import subcommands
from .util import die
#-----------------------------------------------------------------------------
# Globals and constants
#-----------------------------------------------------------------------------
__all__ = (
    'main',
)
#-----------------------------------------------------------------------------
# General API
#-----------------------------------------------------------------------------
[docs]
def main(argv: Sequence[str]) -> None:
    ''' Execute the Bokeh command.
    Args:
        argv (seq[str]) : a list of command line arguments to process
    Returns:
        None
    The first item in ``argv`` is typically "bokeh", and the second should
    be the name of one of the available subcommands:
    * :ref:`build <bokeh.command.subcommands.build>`
    * :ref:`file_output <bokeh.command.subcommands.file_output>`
    * :ref:`info <bokeh.command.subcommands.info>`
    * :ref:`init <bokeh.command.subcommands.init>`
    * :ref:`json <bokeh.command.subcommands.json>`
    * :ref:`secret <bokeh.command.subcommands.secret>`
    * :ref:`serve <bokeh.command.subcommands.serve>`
    * :ref:`static <bokeh.command.subcommands.static>`
    '''
    if len(argv) == 1:
        die(f"ERROR: Must specify subcommand, one of: {nice_join(x.name for x in subcommands.all)}")
    parser = argparse.ArgumentParser(
        prog=argv[0],
        epilog="See '<command> --help' to read about a specific subcommand.")
    parser.add_argument('-v', '--version', action='version', version=__version__)
    subs = parser.add_subparsers(help="Sub-commands")
    for cls in subcommands.all:
        subparser = subs.add_parser(cls.name, help=cls.help)
        subcommand = cls(parser=subparser)
        subparser.set_defaults(invoke=subcommand.invoke)
    args = parser.parse_args(argv[1:])
    try:
        ret = args.invoke(args)
    except Exception as e:
        if settings.dev:
            raise
        else:
            die("ERROR: " + str(e))
    if ret is False:
        sys.exit(1)
    elif ret is not True and isinstance(ret, int) and ret != 0:
        sys.exit(ret) 
#-----------------------------------------------------------------------------
# Dev API
#-----------------------------------------------------------------------------
#-----------------------------------------------------------------------------
# Private API
#-----------------------------------------------------------------------------
#-----------------------------------------------------------------------------
# Code
#-----------------------------------------------------------------------------