class HelloWorldPlugin(octoprint.plugin.StartupPlugin):
def on_after_startup(self):
self._logger.info("Hello World!")
__plugin_name__ = "Hello World"
__plugin_version__ = "1.0"
__plugin_description__ = "A quick \"Hello World\" example plugin for OctoPrint"
__plugin_implementations__ = [HelloWorldPlugin()]
and restart OctoPrint. You now get this output in the log::
2015-01-27 11:17:10,792 - octoprint.plugins.helloworld - INFO - Hello World!
Neat, isn't it? We added a custom class that subclasses one of OctoPrint's :ref:`plugin mixins <sec-plugins-mixins>`
with :class:`StartupPlugin` and another control property, ``__plugin_implementations__``, that instantiates
our plugin class and tells OctoPrint about it. Taking a look at the documentation of :class:`StartupPlugin` we see that
this mixin offers two methods that get called by OctoPrint during startup of the server, ``on_startup`` and
``on_after_startup``. We decided to add our logging output by overriding ``on_after_startup``, but we could also have
used ``on_startup`` instead, in which case our logging statement would be executed before the server was done starting
up and ready to serve requests.
You'll also note that we are using ``self._logger`` for logging. Where did that one come from? OctoPrint's plugin system
injects :ref:`a couple of useful objects <sec-plugins-infrastructure-injections>` into our plugin implementation classes,
one of those being a fully instantiated `python logger <https://docs.python.org/2/library/logging.html>`_ ready to be
used by your plugin. As you can see in the log output above, that logger uses the namespace ``octoprint.plugins.helloworld``
for our little plugin here, or more generally ``octoprint.plugins.<plugin identifier>``.
Growing up: How to make it distributable
----------------------------------------
If you now want to distribute this plugin to other OctoPrint users (since it is so awesome to be greeted upon server
startup), let's take a look at how you'd go about that now before our plugin gets more complicated.
You basically have two options to distribute your plugin. One would be about the exact same way we are using it now,
as a simple python file following the naming convention ``<plugin identifier>.py`` that your users add to their
``~/.octoprint/plugins`` folder. You already know how that works. But let's say you have more than just a simple plugin
that can be done in one file. Distributing multiple files and getting your users to install them in the right way
so that OctoPrint will be able to actually find and load them is certainly not impossible (see :ref:`the plugin distribution
documentation <sec-plugins-distribution>` if you want to take a closer look at that option), but we want to do it in the
best way possible, meaning we want to make our plugin a fully installable python module that your users will be able to
install directly via Python's standard package manager ``pip`` or alternatively via `OctoPrint's own plugin manager <https://github.com/OctoPrint/OctoPrint-PluginManager>`_.
So let's begin. First checkout the `Plugin Skeleton <https://github.com/OctoPrint/OctoPrint-PluginSkeleton>`_ and rename
the ``octoprint_skeleton`` folder to something better suited to our "Hello World" plugin::