Documention for CLI and its development
This commit is contained in:
parent
d9f0fb1667
commit
3c2d2b579d
7 changed files with 162 additions and 22 deletions
31
docs/modules/cli.rst
Normal file
31
docs/modules/cli.rst
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
.. _sec-modules-cli:
|
||||
|
||||
octoprint.cli
|
||||
-------------
|
||||
|
||||
.. automodule:: octoprint.cli
|
||||
:members:
|
||||
|
||||
.. _sec-modules-cli-devel:
|
||||
|
||||
octoprint.cli.devel
|
||||
-------------------
|
||||
|
||||
.. automodule:: octoprint.cli.devel
|
||||
:members:
|
||||
|
||||
.. _sec-modules-cli-plugins:
|
||||
|
||||
octoprint.cli.plugins
|
||||
---------------------
|
||||
|
||||
.. automodule:: octoprint.cli.plugins
|
||||
:members:
|
||||
|
||||
.. _sec-modules-cli-server:
|
||||
|
||||
octoprint.cli.server
|
||||
--------------------
|
||||
|
||||
.. automodule:: octoprint.cli.server
|
||||
:members:
|
||||
|
|
@ -7,6 +7,7 @@ Internal Modules
|
|||
.. toctree::
|
||||
:maxdepth: 3
|
||||
|
||||
cli.rst
|
||||
filemanager.rst
|
||||
plugin.rst
|
||||
printer.rst
|
||||
|
|
|
|||
|
|
@ -46,20 +46,87 @@ octoprint.cli.commands
|
|||
|
||||
By providing a handler for this hook plugins may register commands on OctoPrint's command line interface (CLI).
|
||||
|
||||
.. todo::
|
||||
Handlers are expected to return a list of callables annotated as `Click commands <http://click.pocoo.org/5/>`_ to register with the
|
||||
CLI.
|
||||
|
||||
* More documentation
|
||||
* Example
|
||||
The custom ``MultiCommand`` instance :class:`~octoprint.cli.plugins.OctoPrintPluginCommands` is provided
|
||||
as parameter. Via that object handlers may access the *global* :class:`~octoprint.settings.Settings`
|
||||
and the :class:`~octoprint.plugin.core.PluginManager` instance as ``cli_group.settings`` and ``cli_group.plugin_manager``.
|
||||
|
||||
**Example:**
|
||||
|
||||
Registers two new commands, ``custom_cli_command:greet`` and ``custom_cli_command:random`` with
|
||||
OctoPrint:
|
||||
|
||||
.. onlineinclude:: https://raw.githubusercontent.com/OctoPrint/Plugin-Examples/master/custom_cli_command.py
|
||||
:linenos:
|
||||
:tab-width: 4
|
||||
:caption: `custom_cli_command.py <https://github.com/OctoPrint/Plugin-Examples/blob/master/custom_cli_command.py>`_
|
||||
|
||||
Calling ``octoprint --help`` shows the two new commands:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
$ octoprint --help
|
||||
Usage: octoprint [OPTIONS] COMMAND [ARGS]...
|
||||
|
||||
Options:
|
||||
-b, --basedir PATH Specify the basedir to use for uploads, timelapses etc.
|
||||
-c, --config PATH Specify the config file to use.
|
||||
-v, --verbose Increase logging verbosity
|
||||
--version Show the version and exit.
|
||||
--help Show this message and exit.
|
||||
|
||||
Commands:
|
||||
custom_cli_command:greet Greet someone by name, the greeting can be...
|
||||
custom_cli_command:random Greet someone by name with a random greeting.
|
||||
daemon Starts, stops or restarts in daemon mode.
|
||||
devel:newplugin Creates a new plugin based on the OctoPrint...
|
||||
serve Starts the OctoPrint server.
|
||||
|
||||
Each also has an individual help output:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
$ octoprint custom_cli_command:greet --help
|
||||
Usage: octoprint custom_cli_command:greet [OPTIONS] [NAME]
|
||||
|
||||
Greet someone by name, the greeting can be customized.
|
||||
|
||||
Options:
|
||||
-g, --greeting TEXT The greeting to use
|
||||
--help Show this message and exit.
|
||||
|
||||
$ octoprint custom_cli_command:random --help
|
||||
Usage: octoprint custom_cli_command:random [OPTIONS] [NAME]
|
||||
|
||||
Greet someone by name with a random greeting.
|
||||
|
||||
Options:
|
||||
--help Show this message and exit.
|
||||
|
||||
And of course they work too:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
$ octoprint custom_cli_command:greet
|
||||
Hello World!
|
||||
|
||||
$ octoprint custom_cli_command:greet --greeting "Good morning"
|
||||
Good morning World!
|
||||
|
||||
$ octoprint custom_cli_command:random stranger
|
||||
Hola stranger!
|
||||
|
||||
.. note::
|
||||
|
||||
If your hook handler is an instance method of a plugin mixin implementation, be aware that the hook will be
|
||||
called without OctoPrint initializing your implementation instance. That means that **none** of the
|
||||
:ref:`injected properties <sec-plugins-concepts-injectedproperties>` will be available and also the
|
||||
:meth:`~octoprint.plugin.Plugin.initialize` method will not be called.
|
||||
:method:`~octoprint.plugin.Plugin.initialize` method will not be called.
|
||||
|
||||
Your hook handler will have access to the plugin manager as ``cli_group._plugin_manager`` and to the
|
||||
*global* settings as ``cli_group._settings``. You can have your handler turn the latter into a
|
||||
Your hook handler will have access to the plugin manager as ``cli_group.plugin_manager`` and to the
|
||||
*global* settings as ``cli_group.settings``. You can have your handler turn the latter into a
|
||||
:class:`~octoprint.plugin.PluginSettings` instance by using :func:`octoprint.plugin.plugin_settings_from_settings_plugin`
|
||||
if your plugin's implementation implements the :class:`~octoprint.plugin.SettingsPlugin` mixin and inject
|
||||
that and the plugin manager instance yourself:
|
||||
|
|
@ -92,7 +159,7 @@ octoprint.cli.commands
|
|||
OctoPrint server context, so there is absolutely no way to access a printer connection, the event bus or
|
||||
anything else like that. The only things available are the settings and the plugin manager.
|
||||
|
||||
:return: A list of `Click commands or groups <http://click.pocoo.org/5/commands/>` to provide on
|
||||
:return: A list of `Click commands or groups <http://click.pocoo.org/5/commands/>`_ to provide on
|
||||
OctoPrint's CLI.
|
||||
:rtype: list
|
||||
|
||||
|
|
|
|||
|
|
@ -11,16 +11,20 @@ import octoprint
|
|||
#~~ click context
|
||||
|
||||
class OctoPrintContext(object):
|
||||
def __init__(self, configfile=None, basedir=None, debug=False, verbosity=0):
|
||||
"""Custom context wrapping the standard options."""
|
||||
|
||||
def __init__(self, configfile=None, basedir=None, verbosity=0):
|
||||
self.configfile = configfile
|
||||
self.basedir = basedir
|
||||
self.debug = debug
|
||||
self.verbosity = verbosity
|
||||
|
||||
pass_octoprint_ctx = click.make_pass_decorator(OctoPrintContext, ensure=True)
|
||||
"""Decorator to pass in the :class:`OctoPrintContext` instance."""
|
||||
|
||||
#~~ Custom click option to hide from help
|
||||
|
||||
class HiddenOption(click.Option):
|
||||
"""Custom option sub class with empty help."""
|
||||
def get_help_record(self, ctx):
|
||||
pass
|
||||
|
||||
|
|
@ -55,6 +59,13 @@ def set_ctx_obj_option(ctx, param, value):
|
|||
#~~ helper for setting a lot of bulk options
|
||||
|
||||
def bulk_options(options):
|
||||
"""
|
||||
Utility decorator to decorate a function with a list of click decorators.
|
||||
|
||||
The provided list of ``options`` will be reversed to ensure correct
|
||||
processing order (inverse from what would be intuitive).
|
||||
"""
|
||||
|
||||
def decorator(f):
|
||||
options.reverse()
|
||||
for option in options:
|
||||
|
|
@ -65,6 +76,14 @@ def bulk_options(options):
|
|||
#~~ helper for setting --basedir, --config and --verbose options
|
||||
|
||||
def standard_options(hidden=False):
|
||||
"""
|
||||
Decorator to add the standard options shared among all "octoprint" commands.
|
||||
|
||||
Adds the options ``--basedir``, ``--config`` and ``--verbose``. If ``hidden``
|
||||
is set to ``True``, the options will be available on the command but not
|
||||
listed in its help page.
|
||||
"""
|
||||
|
||||
factory = click.option
|
||||
if hidden:
|
||||
factory = hidden_option
|
||||
|
|
@ -91,6 +110,9 @@ legacy_options = bulk_options([
|
|||
hidden_option("--pid", type=click.Path(), default="/tmp/octoprint.pid"),
|
||||
hidden_option("--iknowwhatimdoing", "allow_root", is_flag=True),
|
||||
])
|
||||
"""Legacy options available directly on the "octoprint" command in earlier versions.
|
||||
Kept available for reasons of backwards compatibility, but hidden from the
|
||||
generated help pages."""
|
||||
|
||||
#~~ "octoprint" command, merges server_commands and plugin_commands groups
|
||||
|
||||
|
|
|
|||
|
|
@ -9,8 +9,12 @@ __copyright__ = "Copyright (C) 2015 The OctoPrint Project - Released under terms
|
|||
import click
|
||||
import logging
|
||||
|
||||
|
||||
class OctoPrintDevelCommands(click.MultiCommand):
|
||||
"""
|
||||
Custom `click.MultiCommand <http://click.pocoo.org/5/api/#click.MultiCommand>`_
|
||||
implementation that provides commands relevant for (plugin) development
|
||||
based on availability of development dependencies.
|
||||
"""
|
||||
|
||||
sep = ":"
|
||||
|
||||
|
|
|
|||
|
|
@ -14,21 +14,32 @@ from octoprint.cli import pass_octoprint_ctx, OctoPrintContext
|
|||
|
||||
class OctoPrintPluginCommands(click.MultiCommand):
|
||||
"""
|
||||
Custom `click.MultiCommand` implementation that collects commands from
|
||||
the plugin hook "octoprint.cli.commands".
|
||||
Custom `click.MultiCommand <http://click.pocoo.org/5/api/#click.MultiCommand>`_
|
||||
implementation that collects commands from the plugin hook
|
||||
:ref:`octoprint.cli.commands <sec-plugins-hook-cli-commands>`.
|
||||
|
||||
.. attribute:: settings
|
||||
|
||||
The global :class:`~octoprint.settings.Settings` instance.
|
||||
|
||||
.. attribute:: plugin_manager
|
||||
|
||||
The :class:`~octoprint.plugin.core.PluginManager` instance.
|
||||
"""
|
||||
|
||||
sep = ":"
|
||||
"""Separator for commands between plugin name and command name."""
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
click.MultiCommand.__init__(self, *args, **kwargs)
|
||||
self._settings = None
|
||||
self._plugin_manager = None
|
||||
|
||||
self.settings = None
|
||||
self.plugin_manager = None
|
||||
|
||||
self._logger = logging.getLogger(__name__)
|
||||
self._initialized = False
|
||||
|
||||
def _initialize(self, ctx):
|
||||
if self._settings is not None:
|
||||
if self._initialized:
|
||||
return
|
||||
|
||||
if ctx.obj is None:
|
||||
|
|
@ -37,11 +48,13 @@ class OctoPrintPluginCommands(click.MultiCommand):
|
|||
# initialize settings and plugin manager based on provided
|
||||
# context (basedir and configfile)
|
||||
from octoprint import init_settings, init_pluginsystem
|
||||
self._settings = init_settings(ctx.obj.basedir, ctx.obj.configfile)
|
||||
self._plugin_manager = init_pluginsystem(self._settings)
|
||||
self.settings = init_settings(ctx.obj.basedir, ctx.obj.configfile)
|
||||
self.plugin_manager = init_pluginsystem(self.settings)
|
||||
|
||||
# fetch registered hooks
|
||||
self._hooks = self._plugin_manager.get_hooks("octoprint.cli.commands")
|
||||
self.hooks = self.plugin_manager.get_hooks("octoprint.cli.commands")
|
||||
|
||||
self._initialized = True
|
||||
|
||||
def list_commands(self, ctx):
|
||||
self._initialize(ctx)
|
||||
|
|
@ -60,7 +73,7 @@ class OctoPrintPluginCommands(click.MultiCommand):
|
|||
import collections
|
||||
result = collections.OrderedDict()
|
||||
|
||||
for name, hook in self._hooks.items():
|
||||
for name, hook in self.hooks.items():
|
||||
try:
|
||||
commands = hook(self, pass_octoprint_ctx)
|
||||
for command in commands:
|
||||
|
|
|
|||
|
|
@ -12,6 +12,8 @@ import sys
|
|||
from octoprint.cli import pass_octoprint_ctx, bulk_options, standard_options
|
||||
|
||||
def run_server(basedir, configfile, host, port, debug, allow_root, logging_config, verbosity):
|
||||
"""Initializes the environment and starts up the server."""
|
||||
|
||||
from octoprint import init_platform, __display_version__
|
||||
|
||||
def log_startup(_):
|
||||
|
|
@ -39,10 +41,8 @@ def run_server(basedir, configfile, host, port, debug, allow_root, logging_confi
|
|||
octoprint_server = Server(settings=settings, plugin_manager=plugin_manager, host=host, port=port, debug=debug, allow_root=allow_root)
|
||||
octoprint_server.run()
|
||||
|
||||
|
||||
#~~ server options
|
||||
|
||||
|
||||
server_options = bulk_options([
|
||||
click.option("--host", type=click.STRING,
|
||||
help="Specify the host on which to bind the server."),
|
||||
|
|
@ -54,6 +54,8 @@ server_options = bulk_options([
|
|||
help="Allow OctoPrint to run as user root."),
|
||||
click.option("--debug", is_flag=True, help="Enable debug mode"),
|
||||
])
|
||||
"""Decorator to add the options shared among the server commands: ``--host``, ``--port``,
|
||||
``--logging``, ``--iknowwhatimdoing`` and ``--debug``."""
|
||||
|
||||
#~~ "octoprint serve" and "octoprint daemon" commands
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue