Skip to content

Commit 3dd51fa

Browse files
committed
Add docs on writing & using plugins
1 parent c2a9bda commit 3dd51fa

File tree

3 files changed

+149
-0
lines changed

3 files changed

+149
-0
lines changed

docs/contributing/plugins.rst

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
.. _contributing/plugins:
2+
3+
============
4+
TLJH Plugins
5+
============
6+
7+
TLJH plugins are the official way to make customized 'spins' or 'stacks'
8+
with TLJH as the base. For example, the earth sciences community can make
9+
a plugin that installs commonly used packages, set up authentication
10+
and pre-download useful datasets. The mybinder.org community can
11+
make a plugin that gives you a single-node, single-repository mybinder.org.
12+
Plugins are very powerful, so the possibilities are endless.
13+
14+
Design
15+
======
16+
17+
`pluggy <https://github.com/pytest-dev/pluggy>`_ is used to implement
18+
plugin functionality. TLJH exposes specific **hooks** that your plugin
19+
can provide implementations for. This allows us to have specific hook
20+
points in the application that can be explicitly extended by plugins,
21+
balancing the need to change TLJH internals in the future with the
22+
stability required for a good plugin ecosystem.
23+
24+
Writing a simple plugins
25+
========================
26+
27+
We shall try to write a simple plugin that installs a few libraries,
28+
and use it to explain how the plugin mechanism works. We shall call
29+
this plugin ``tljh-simple``.
30+
31+
Plugin directory layout
32+
-----------------------
33+
34+
We recommend creating a new git repo for your plugin. Plugins are
35+
normal python packages - however, since they are usually simpler,
36+
we recommend they live in one file.
37+
38+
For ``tljh-simple``, the repository's structure should look like:
39+
40+
.. code-block:: none
41+
42+
tljh_simple:
43+
- tljh_simple.py
44+
- setup.py
45+
- README.md
46+
- LICENSE
47+
48+
The ``README.md`` (or ``README.rst`` file) contains human readable
49+
information about what your plugin does for your users. ``LICENSE``
50+
specifies the license used by your plugin - we recommend the
51+
3-Clause BSD License, since that is what is used by TLJH itself.
52+
53+
``setup.py`` - metadata & registration
54+
--------------------------------------
55+
56+
``setup.py`` marks this as a python package, and contains metadata
57+
about the package itself. It should look something like:
58+
59+
.. code-block:: python
60+
61+
from setuptools import setup
62+
63+
setup(
64+
name="tljh-simple",
65+
author="YuviPanda",
66+
version="0.1",
67+
license="3-clause BSD",
68+
url='https://github.com/yuvipanda/tljh-simple',
69+
entry_points={"tljh": ["simple = tljh_simple"]},
70+
py_modules=["tljh_simple"],
71+
)
72+
73+
74+
This is a mostly standard ``setup.py`` file. ``entry_points={"tljh": ["simple = tljh_simple]}``
75+
'registers' the module ``tljh_simple`` (in file ``tljh_simple.py``) with TLJH as a plugin.
76+
77+
``tljh_simple.py`` - implementation
78+
-----------------------------------
79+
80+
In ``tljh_simple.py``, you provide implementations for whichever hooks
81+
you want to extend.
82+
83+
A hook implementation is a function that has the following characteristics:
84+
85+
#. Has same name as the hook
86+
#. Accepts some or all of the parameters defined for the hook
87+
#. Is decorated with the ``hookimpl`` decorator function, imported from
88+
``tljh.hooks``.
89+
90+
The current list of available hooks and when they are called can be
91+
seen in ```tljh/hooks.py`` <https://github.com/jupyterhub/the-littlest-jupyterhub/blob/master/tljh/hooks.py>`_
92+
in the source repository.
93+
94+
95+
This example provides an implementation for the ``tljh_extra_user_conda_packages``
96+
hook, which can return a list of conda packages that'll be installed in users'
97+
environment from conda-forge.
98+
99+
.. code-block:: python
100+
101+
from tljh.hooks import hookimpl
102+
103+
@hookimpl
104+
def tljh_extra_user_conda_packages():
105+
return [
106+
'xarray',
107+
'iris',
108+
'dask',
109+
]
110+
111+
112+
Publishing plugins
113+
==================
114+
115+
Plugins are python packages and should be published on PyPI. Users
116+
can also install them directly from GitHub - although this is
117+
not good long term practice.
118+
119+
The python package should be named ``tljh-<pluginname>``.

docs/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,3 +127,4 @@ to people contributing in various ways.
127127
contributing/code-review
128128
contributing/dev-setup
129129
contributing/tests
130+
contributing/plugins

docs/topic/customizing-installer.rst

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,3 +56,32 @@ will fail.
5656

5757
When pointing to a file on GitHub, make sure to use the 'Raw' version. It should point to
5858
``raw.githubusercontent.com``, not ``github.com``.
59+
60+
Installing TLJH plugins
61+
=======================
62+
63+
The Littlest JupyterHub can install additional *plugins* that provide additional
64+
features. They are most commonly used to install a particular *stack* - such as
65+
the `PANGEO Stack <https://github.com/yuvipanda/tljh-pangeo>`_ for earth sciences
66+
research, a stack for a praticular class, etc.
67+
68+
``--plugin <plugin-to-install>`` installs and activates a plugin. You can pass it
69+
however many times you want. Since plugins are distributed as python packages,
70+
``<plugin-to-install>`` can be anything that can be passed to ``pip install`` -
71+
``plugin-name-on-pypy==<version>`` and ``git+https://github.com/user/repo@tag``
72+
are the most popular ones. Specifying a version or tag is highly recommended.
73+
74+
For example, to install the PANGEO Plugin version 0.1 in your new TLJH install,
75+
you would use:
76+
77+
.. code-block:: bash
78+
79+
curl https://raw.githubusercontent.com/jupyterhub/the-littlest-jupyterhub/master/bootstrap/bootstrap.py \
80+
| sudo python3 - \
81+
--plugin git+https://github.com/yuvipanda/[email protected]
82+
83+
84+
.. note::
85+
86+
Plugins are extremely powerful and can do a large number of arbitrary things.
87+
Only install plugins you trust.

0 commit comments

Comments
 (0)