mirror of
https://github.com/jupyterhub/the-littlest-jupyterhub.git
synced 2025-12-18 21:54:05 +08:00
adopt myst
run rst2myst, with minimal manual formatting fixes
This commit is contained in:
@@ -1,37 +1,32 @@
|
||||
.. _contributing/code-review:
|
||||
(contributing-code-review)=
|
||||
|
||||
======================
|
||||
Code Review guidelines
|
||||
======================
|
||||
# Code Review guidelines
|
||||
|
||||
This document outlines general guidelines to follow when you are making
|
||||
or reviewing a Pull Request.
|
||||
|
||||
Have empathy
|
||||
============
|
||||
## Have empathy
|
||||
|
||||
We recommend reading `On Empathy & Pull Requests <https://slack.engineering/on-empathy-pull-requests-979e4257d158>`_
|
||||
and `How about code reviews <https://slack.engineering/how-about-code-reviews-2695fb10d034>`_
|
||||
We recommend reading [On Empathy & Pull Requests](https://slack.engineering/on-empathy-pull-requests-979e4257d158)
|
||||
and [How about code reviews](https://slack.engineering/how-about-code-reviews-2695fb10d034)
|
||||
to learn more about being empathetic in code reviews.
|
||||
|
||||
Write documentation
|
||||
===================
|
||||
## Write documentation
|
||||
|
||||
If your pull request touches any code, you must write or update documentation
|
||||
for it. For this project, documentation is a lot more important than the code.
|
||||
If a feature is not documented, it does not exist. If a behavior is not documented,
|
||||
it is a bug.
|
||||
If a feature is not documented, it does not exist. If a behavior is not documented,
|
||||
it is a bug.
|
||||
|
||||
Do not worry about having perfect documentation! Documentation improves over
|
||||
time. The requirement is to have documentation before merging a pull request,
|
||||
not to have *perfect* documentation before merging a pull request. If you
|
||||
not to have _perfect_ documentation before merging a pull request. If you
|
||||
are new and not sure how to add documentation, other contributors will
|
||||
be happy to guide you.
|
||||
|
||||
See :ref:`contributing/docs` for guidelines on writing documentation.
|
||||
See {ref}`contributing/docs` for guidelines on writing documentation.
|
||||
|
||||
Write tests
|
||||
===========
|
||||
## Write tests
|
||||
|
||||
If your pull request touches any code, you must write unit or integration tests
|
||||
to exercise it. This helps validate & communicate that your pull request works
|
||||
@@ -48,4 +43,4 @@ add more tests.
|
||||
If you are unsure what kind of tests to add for your pull request, other
|
||||
contributors to the repo will be happy to help guide you!
|
||||
|
||||
See :ref:`contributing/tests` for guidelines on writing tests.
|
||||
See {ref}`contributing/tests` for guidelines on writing tests.
|
||||
72
docs/contributing/dev-setup.md
Normal file
72
docs/contributing/dev-setup.md
Normal file
@@ -0,0 +1,72 @@
|
||||
(contributing-dev-setup)=
|
||||
|
||||
# Setting up Development Environment
|
||||
|
||||
The easiest & safest way to develop & test TLJH is with [Docker](https://www.docker.com/).
|
||||
|
||||
1. Install Docker Community Edition by following the instructions on
|
||||
[their website](https://www.docker.com/community-edition).
|
||||
|
||||
2. Clone the [git repo](https://github.com/jupyterhub/the-littlest-jupyterhub) (or your fork of it).
|
||||
|
||||
3. Build a docker image that has a functional systemd in it.
|
||||
|
||||
```bash
|
||||
docker build -t tljh-systemd . -f integration-tests/Dockerfile
|
||||
```
|
||||
|
||||
4. Run a docker container with the image in the background, while bind mounting
|
||||
your TLJH repository under `/srv/src`.
|
||||
|
||||
```bash
|
||||
docker run \
|
||||
--privileged \
|
||||
--detach \
|
||||
--name=tljh-dev \
|
||||
--publish 12000:80 \
|
||||
--mount type=bind,source=$(pwd),target=/srv/src \
|
||||
tljh-systemd
|
||||
```
|
||||
|
||||
5. Get a shell inside the running docker container.
|
||||
|
||||
```bash
|
||||
docker exec -it tljh-dev /bin/bash
|
||||
```
|
||||
|
||||
6. Run the bootstrapper from inside the container (see step above):
|
||||
The container image is already set up to default to a `dev` install, so
|
||||
it'll install from your local repo rather than from github.
|
||||
|
||||
```console
|
||||
python3 /srv/src/bootstrap/bootstrap.py --admin admin
|
||||
```
|
||||
|
||||
> Or, if you would like to setup the admin's password during install,
|
||||
> you can use this command (replace "admin" with the desired admin username
|
||||
> and "password" with the desired admin password):
|
||||
>
|
||||
> > ```console
|
||||
> > python3 /srv/src/bootstrap/bootstrap.py --admin admin:password
|
||||
> > ```
|
||||
> >
|
||||
> > The primary hub environment will also be in your PATH already for convenience.
|
||||
|
||||
1. You should be able to access the JupyterHub from your browser now at
|
||||
[http://localhost:12000](http://localhost:12000). Congratulations, you are
|
||||
set up to develop TLJH!
|
||||
|
||||
2. Make some changes to the repository. You can test easily depending on what
|
||||
you changed.
|
||||
|
||||
- If you changed the `bootstrap/bootstrap.py` script or any of its dependencies,
|
||||
you can test it by running `python3 /srv/src/bootstrap/bootstrap.py`.
|
||||
- If you changed the `tljh/installer.py` code (or any of its dependencies),
|
||||
you can test it by running `python3 -m tljh.installer`.
|
||||
- If you changed `tljh/jupyterhub_config.py`, `tljh/configurer.py`,
|
||||
`/opt/tljh/config/` or any of their dependencies, you only need to
|
||||
restart jupyterhub for them to take effect. `tljh-config reload hub`
|
||||
should do that.
|
||||
|
||||
{ref}`troubleshooting/logs` has information on looking at various logs in the container
|
||||
to debug issues you might have.
|
||||
@@ -1,75 +0,0 @@
|
||||
.. _contributing/dev-setup:
|
||||
|
||||
==================================
|
||||
Setting up Development Environment
|
||||
==================================
|
||||
|
||||
The easiest & safest way to develop & test TLJH is with `Docker <https://www.docker.com/>`_.
|
||||
|
||||
#. Install Docker Community Edition by following the instructions on
|
||||
`their website <https://www.docker.com/community-edition>`_.
|
||||
|
||||
#. Clone the `git repo <https://github.com/jupyterhub/the-littlest-jupyterhub>`_ (or your fork of it).
|
||||
#. Build a docker image that has a functional systemd in it.
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
docker build -t tljh-systemd . -f integration-tests/Dockerfile
|
||||
|
||||
#. Run a docker container with the image in the background, while bind mounting
|
||||
your TLJH repository under ``/srv/src``.
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
docker run \
|
||||
--privileged \
|
||||
--detach \
|
||||
--name=tljh-dev \
|
||||
--publish 12000:80 \
|
||||
--mount type=bind,source=$(pwd),target=/srv/src \
|
||||
tljh-systemd
|
||||
|
||||
#. Get a shell inside the running docker container.
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
docker exec -it tljh-dev /bin/bash
|
||||
|
||||
#. Run the bootstrapper from inside the container (see step above):
|
||||
The container image is already set up to default to a ``dev`` install, so
|
||||
it'll install from your local repo rather than from github.
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
python3 /srv/src/bootstrap/bootstrap.py --admin admin
|
||||
|
||||
Or, if you would like to setup the admin's password during install,
|
||||
you can use this command (replace "admin" with the desired admin username
|
||||
and "password" with the desired admin password):
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
python3 /srv/src/bootstrap/bootstrap.py --admin admin:password
|
||||
|
||||
The primary hub environment will also be in your PATH already for convenience.
|
||||
|
||||
#. You should be able to access the JupyterHub from your browser now at
|
||||
`http://localhost:12000 <http://localhost:12000>`_. Congratulations, you are
|
||||
set up to develop TLJH!
|
||||
|
||||
#. Make some changes to the repository. You can test easily depending on what
|
||||
you changed.
|
||||
|
||||
* If you changed the ``bootstrap/bootstrap.py`` script or any of its dependencies,
|
||||
you can test it by running ``python3 /srv/src/bootstrap/bootstrap.py``.
|
||||
|
||||
* If you changed the ``tljh/installer.py`` code (or any of its dependencies),
|
||||
you can test it by running ``python3 -m tljh.installer``.
|
||||
|
||||
* If you changed ``tljh/jupyterhub_config.py``, ``tljh/configurer.py``,
|
||||
``/opt/tljh/config/`` or any of their dependencies, you only need to
|
||||
restart jupyterhub for them to take effect. ``tljh-config reload hub``
|
||||
should do that.
|
||||
|
||||
:ref:`troubleshooting/logs` has information on looking at various logs in the container
|
||||
to debug issues you might have.
|
||||
@@ -1,13 +1,11 @@
|
||||
.. _contributing/docs:
|
||||
(contributing-docs)=
|
||||
|
||||
=====================
|
||||
Writing documentation
|
||||
=====================
|
||||
# Writing documentation
|
||||
|
||||
.. note::
|
||||
|
||||
Heavily inspired by the
|
||||
`django project's guidelines <https://docs.djangoproject.com/en/dev/internals/contributing/writing-documentation/>`_
|
||||
:::{note}
|
||||
Heavily inspired by the
|
||||
[django project's guidelines](https://docs.djangoproject.com/en/dev/internals/contributing/writing-documentation/)
|
||||
:::
|
||||
|
||||
We place a high importance on consistency, readability and completeness of documentation.
|
||||
If a feature is not documented, it does not exist. If a behavior is not documented,
|
||||
@@ -17,70 +15,62 @@ possible.
|
||||
|
||||
Documentation changes generally come in two forms:
|
||||
|
||||
* General improvements: typo corrections, error fixes and better
|
||||
- General improvements: typo corrections, error fixes and better
|
||||
explanations through clearer writing and more examples.
|
||||
|
||||
* New features: documentation of features that have been added to the
|
||||
- New features: documentation of features that have been added to the
|
||||
framework since the last release.
|
||||
|
||||
This section explains how writers can craft their documentation changes
|
||||
in the most useful and least error-prone ways.
|
||||
|
||||
Getting the raw documentation
|
||||
=============================
|
||||
## Getting the raw documentation
|
||||
|
||||
Though TLJH's documentation is intended to be read as HTML at
|
||||
https://the-littlest-jupyterhub.readthedocs.io/, we edit it as a collection of text files for
|
||||
maximum flexibility. These files live in the top-level ``docs/`` directory of
|
||||
<https://the-littlest-jupyterhub.readthedocs.io/>, we edit it as a collection of text files for
|
||||
maximum flexibility. These files live in the top-level `docs/` directory of
|
||||
TLJH's repository.
|
||||
|
||||
If you'd like to start contributing to our docs, get the development version of
|
||||
TLJH from the source code repository. The development version has the
|
||||
latest-and-greatest documentation, just as it has latest-and-greatest code.
|
||||
|
||||
Getting started with Sphinx
|
||||
===========================
|
||||
## Getting started with Sphinx
|
||||
|
||||
TLJH's documentation uses the Sphinx__ documentation system, which in turn
|
||||
is based on docutils__. The basic idea is that lightly-formatted plain-text
|
||||
TLJH's documentation uses the [Sphinx](http://sphinx-doc.org/) documentation system, which in turn
|
||||
is based on [docutils](http://docutils.sourceforge.net/). The basic idea is that lightly-formatted plain-text
|
||||
documentation is transformed into HTML, PDF, and any other output format.
|
||||
|
||||
__ http://sphinx-doc.org/
|
||||
__ http://docutils.sourceforge.net/
|
||||
|
||||
To build the documentation locally, install the Sphinx dependencies:
|
||||
|
||||
.. code-block:: console
|
||||
```console
|
||||
$ cd docs/
|
||||
$ pip install -r requirements.txt
|
||||
```
|
||||
|
||||
$ cd docs/
|
||||
$ pip install -r requirements.txt
|
||||
Then from the `docs` directory, build the HTML:
|
||||
|
||||
Then from the ``docs`` directory, build the HTML:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ make html
|
||||
```console
|
||||
$ make html
|
||||
```
|
||||
|
||||
If you encounter this error, it's likely that you are running inside a virtual environment.
|
||||
|
||||
.. code-block:: console
|
||||
```console
|
||||
Error in "currentmodule" directive:
|
||||
```
|
||||
|
||||
Error in "currentmodule" directive:
|
||||
|
||||
To get started contributing, you'll want to read the :ref:`reStructuredText
|
||||
reference <sphinx:rst-index>`
|
||||
To get started contributing, you'll want to read the {ref}`reStructuredText reference <sphinx:rst-index>`
|
||||
|
||||
Your locally-built documentation will be themed differently than the
|
||||
documentation at `the-littlest-jupyterhub.readthedocs.io <https://the-littlest-jupyterhub.readthedocs.io>`_.
|
||||
documentation at [the-littlest-jupyterhub.readthedocs.io](https://the-littlest-jupyterhub.readthedocs.io).
|
||||
This is OK! If your changes look good on your local machine, they'll look good
|
||||
on the website.
|
||||
|
||||
How the documentation is organized
|
||||
==================================
|
||||
## How the documentation is organized
|
||||
|
||||
The documentation is organized into several categories:
|
||||
|
||||
* **Tutorials** take the reader by the hand through a series
|
||||
- **Tutorials** take the reader by the hand through a series
|
||||
of steps to create something.
|
||||
|
||||
The important thing in a tutorial is to help the reader achieve something
|
||||
@@ -97,7 +87,7 @@ The documentation is organized into several categories:
|
||||
systems. These should cross-link a lot to other parts of the documentation,
|
||||
avoid forcing the user to learn to SSH if possible & have lots of screenshots.
|
||||
|
||||
* **Topic guides** aim to explain a concept or subject at a
|
||||
- **Topic guides** aim to explain a concept or subject at a
|
||||
fairly high level.
|
||||
|
||||
Link to reference material rather than repeat it. Use examples and don't be
|
||||
@@ -107,7 +97,7 @@ The documentation is organized into several categories:
|
||||
Providing background context helps a newcomer connect the topic to things
|
||||
that they already know.
|
||||
|
||||
* **Reference guides** contain technical reference for APIs.
|
||||
- **Reference guides** contain technical reference for APIs.
|
||||
They describe the functioning of TLJH's internal machinery and instruct in
|
||||
its use.
|
||||
|
||||
@@ -119,7 +109,7 @@ The documentation is organized into several categories:
|
||||
yourself explaining basic concepts, you may want to move that material to a
|
||||
topic guide.
|
||||
|
||||
* **How-to guides** are recipes that take the reader through
|
||||
- **How-to guides** are recipes that take the reader through
|
||||
steps in key subjects.
|
||||
|
||||
What matters most in a how-to guide is what a user wants to achieve.
|
||||
@@ -131,83 +121,76 @@ The documentation is organized into several categories:
|
||||
hesitate to refer the reader back to the appropriate tutorial rather than
|
||||
repeat the same material.
|
||||
|
||||
* **Troubleshooting guides** help reader answer the question "Why is my JupyterHub
|
||||
- **Troubleshooting guides** help reader answer the question "Why is my JupyterHub
|
||||
not working?".
|
||||
|
||||
These guides help readers try find causes for their symptoms, and hopefully fix
|
||||
the issues. Some of these need to be specific to cloud providers, and that is
|
||||
acceptable.
|
||||
|
||||
Writing style
|
||||
=============
|
||||
## Writing style
|
||||
|
||||
Typically, documentation is written in second person, referring to the reader as “you”.
|
||||
Typically, documentation is written in second person, referring to the reader as “you”.
|
||||
When using pronouns in reference to a hypothetical person, such as "a user with
|
||||
a running notebook", gender neutral pronouns (they/their/them) should be used.
|
||||
Instead of:
|
||||
|
||||
* he or she... use they.
|
||||
* him or her... use them.
|
||||
* his or her... use their.
|
||||
* his or hers... use theirs.
|
||||
* himself or herself... use themselves.
|
||||
- he or she... use they.
|
||||
- him or her... use them.
|
||||
- his or her... use their.
|
||||
- his or hers... use theirs.
|
||||
- himself or herself... use themselves.
|
||||
|
||||
Commonly used terms
|
||||
===================
|
||||
## Commonly used terms
|
||||
|
||||
Here are some style guidelines on commonly used terms throughout the
|
||||
documentation:
|
||||
|
||||
* **TLJH** -- common abbreviation of The Littlest JupyterHub. Fully
|
||||
- **TLJH** -- common abbreviation of The Littlest JupyterHub. Fully
|
||||
capitalized except when used in code / the commandline.
|
||||
|
||||
* **Python** -- when referring to the language, capitalize Python.
|
||||
|
||||
* **Notebook Interface** -- generic term for referring to JupyterLab,
|
||||
- **Python** -- when referring to the language, capitalize Python.
|
||||
- **Notebook Interface** -- generic term for referring to JupyterLab,
|
||||
nteract, classic notebook & other user interfaces for accessing
|
||||
|
||||
|
||||
Guidelines for reStructuredText files
|
||||
=====================================
|
||||
## Guidelines for reStructuredText files
|
||||
|
||||
These guidelines regulate the format of our reST (reStructuredText)
|
||||
documentation:
|
||||
|
||||
* In section titles, capitalize only initial words and proper nouns.
|
||||
- In section titles, capitalize only initial words and proper nouns.
|
||||
|
||||
* Wrap the documentation at 120 characters wide, unless a code example
|
||||
- Wrap the documentation at 120 characters wide, unless a code example
|
||||
is significantly less readable when split over two lines, or for another
|
||||
good reason.
|
||||
|
||||
- Use these heading styles:
|
||||
|
||||
* Use these heading styles::
|
||||
```
|
||||
===
|
||||
One
|
||||
===
|
||||
|
||||
===
|
||||
One
|
||||
===
|
||||
Two
|
||||
===
|
||||
|
||||
Two
|
||||
===
|
||||
Three
|
||||
-----
|
||||
|
||||
Three
|
||||
-----
|
||||
Four
|
||||
~~~~
|
||||
|
||||
Four
|
||||
~~~~
|
||||
Five
|
||||
^^^^
|
||||
```
|
||||
|
||||
Five
|
||||
^^^^
|
||||
|
||||
Documenting new features
|
||||
========================
|
||||
## Documenting new features
|
||||
|
||||
Our policy for new features is:
|
||||
|
||||
All new features must have appropriate documentation before they
|
||||
can be merged.
|
||||
> All new features must have appropriate documentation before they
|
||||
> can be merged.
|
||||
|
||||
Choosing image size
|
||||
===================
|
||||
## Choosing image size
|
||||
|
||||
When adding images to the documentation, try to keep them as small as possible.
|
||||
Larger images make the site load more slowly on browsers, and may make the site
|
||||
@@ -217,37 +200,34 @@ If you're adding screenshots, make the size of your shot as small as possible.
|
||||
If you're uploading large images, consider using an image optimizer in order
|
||||
to reduce its size.
|
||||
|
||||
For example, for PNG files, use OptiPNG and AdvanceCOMP's ``advpng``:
|
||||
For example, for PNG files, use OptiPNG and AdvanceCOMP's `advpng`:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ cd docs
|
||||
$ optipng -o7 -zm1-9 -i0 -strip all `find . -type f -not -path "./_build/*" -name "*.png"`
|
||||
$ advpng -z4 `find . -type f -not -path "./_build/*" -name "*.png"`
|
||||
```console
|
||||
$ cd docs
|
||||
$ optipng -o7 -zm1-9 -i0 -strip all `find . -type f -not -path "./_build/*" -name "*.png"`
|
||||
$ advpng -z4 `find . -type f -not -path "./_build/*" -name "*.png"`
|
||||
```
|
||||
|
||||
This is based on OptiPNG version 0.7.5. Older versions may complain about the
|
||||
``--strip all`` option being lossy.
|
||||
`--strip all` option being lossy.
|
||||
|
||||
Spelling check
|
||||
==============
|
||||
## Spelling check
|
||||
|
||||
Before you commit your docs, it's a good idea to run the spelling checker.
|
||||
You'll need to install a couple packages first:
|
||||
|
||||
* `pyenchant <https://pypi.org/project/pyenchant/>`_ (which requires
|
||||
`enchant <https://www.abisource.com/projects/enchant/>`_)
|
||||
- [pyenchant](https://pypi.org/project/pyenchant/) (which requires
|
||||
[enchant](https://www.abisource.com/projects/enchant/))
|
||||
- [sphinxcontrib-spelling](https://pypi.org/project/sphinxcontrib-spelling/)
|
||||
|
||||
* `sphinxcontrib-spelling
|
||||
<https://pypi.org/project/sphinxcontrib-spelling/>`_
|
||||
|
||||
Then from the ``docs`` directory, run ``make spelling``. Wrong words (if any)
|
||||
Then from the `docs` directory, run `make spelling`. Wrong words (if any)
|
||||
along with the file and line number where they occur will be saved to
|
||||
``_build/spelling/output.txt``.
|
||||
`_build/spelling/output.txt`.
|
||||
|
||||
If you encounter false-positives (error output that actually is correct), do
|
||||
one of the following:
|
||||
|
||||
* Surround inline code or brand/technology names with grave accents (`).
|
||||
* Find synonyms that the spell checker recognizes.
|
||||
* If, and only if, you are sure the word you are using is correct - add it
|
||||
to ``docs/spelling_wordlist`` (please keep the list in alphabetical order).
|
||||
- Surround inline code or brand/technology names with grave accents (\`).
|
||||
- Find synonyms that the spell checker recognizes.
|
||||
- If, and only if, you are sure the word you are using is correct - add it
|
||||
to `docs/spelling_wordlist` (please keep the list in alphabetical order).
|
||||
@@ -1,6 +1,4 @@
|
||||
============
|
||||
Contributing
|
||||
============
|
||||
# Contributing
|
||||
|
||||
✨ Thank you for thinking about contributing to the littlest JupyterHub! ✨
|
||||
|
||||
@@ -9,14 +7,15 @@ Your contribution is integral to the future of the project. Thank you!
|
||||
|
||||
This section contains documentation for people who want to contribute.
|
||||
|
||||
You can find the `source code on GitHub <https://github.com/jupyterhub/the-littlest-jupyterhub/tree/HEAD/tljh>`_
|
||||
You can find the [source code on GitHub](https://github.com/jupyterhub/the-littlest-jupyterhub/tree/HEAD/tljh)
|
||||
|
||||
.. toctree::
|
||||
:titlesonly:
|
||||
```{toctree}
|
||||
:titlesonly: true
|
||||
|
||||
docs
|
||||
dev-setup
|
||||
tests
|
||||
plugins
|
||||
code-review
|
||||
packages
|
||||
docs
|
||||
dev-setup
|
||||
tests
|
||||
plugins
|
||||
code-review
|
||||
packages
|
||||
```
|
||||
@@ -1,46 +1,40 @@
|
||||
.. _contributing/packages:
|
||||
(contributing-packages)=
|
||||
|
||||
=======================
|
||||
Environments & Packages
|
||||
=======================
|
||||
# Environments & Packages
|
||||
|
||||
TLJH installs packages from different sources during installation.
|
||||
This document describes the various sources and how to upgrade
|
||||
versions of packages installed.
|
||||
|
||||
Python Environments
|
||||
===================
|
||||
## Python Environments
|
||||
|
||||
TLJH sets up two python environments during installation.
|
||||
|
||||
1. **Hub Environment**. JupyterHub, authenticators, spawners, TLJH plugins
|
||||
and the TLJH configuration management code is installed into this
|
||||
environment. A `venv <https://docs.python.org/3/library/venv.html>`_ is used,
|
||||
environment. A [venv](https://docs.python.org/3/library/venv.html) is used,
|
||||
primarily since conda does not support ARM CPUs and we'd like to support the
|
||||
RaspberryPI someday. Admins generally do not install custom packages
|
||||
in this environment.
|
||||
|
||||
2. **User Environment**. Jupyter Notebook, JupyterLab, nteract, kernels,
|
||||
and packages the users wanna use (such as numpy, scipy, etc) are installed
|
||||
here. A `conda <https://conda.io>`_ environment is used here, since
|
||||
a lot of scientific packages are available from Conda. ``pip`` is still
|
||||
here. A [conda](https://conda.io) environment is used here, since
|
||||
a lot of scientific packages are available from Conda. `pip` is still
|
||||
used to install Jupyter specific packages, primarily because most notebook
|
||||
extensions are still available only on `PyPI <https://pypi.org>`_.
|
||||
extensions are still available only on [PyPI](https://pypi.org).
|
||||
Admins can install packages here for use by all users.
|
||||
|
||||
Python package versions
|
||||
=======================
|
||||
## Python package versions
|
||||
|
||||
In ``installer.py``, most Python packages have a version specified. This
|
||||
In `installer.py`, most Python packages have a version specified. This
|
||||
can be upgraded freely whenever needed. Some of them have version checks
|
||||
in ``integration-tests/test_extensions.py``, so those might need
|
||||
in `integration-tests/test_extensions.py`, so those might need
|
||||
updating too.
|
||||
|
||||
Apt packages
|
||||
============
|
||||
## Apt packages
|
||||
|
||||
Base operating system packages, including Python itself, are installed
|
||||
via ``apt`` from the base Ubuntu repositories.
|
||||
via `apt` from the base Ubuntu repositories.
|
||||
|
||||
We generally do not pin versions of packages provided by apt, instead
|
||||
just using the latest versions provided by Ubuntu.
|
||||
132
docs/contributing/plugins.md
Normal file
132
docs/contributing/plugins.md
Normal file
@@ -0,0 +1,132 @@
|
||||
(contributing-plugins)=
|
||||
|
||||
# TLJH Plugins
|
||||
|
||||
TLJH plugins are the official way to make customized 'spins' or 'stacks'
|
||||
with TLJH as the base. For example, the earth sciences community can make
|
||||
a plugin that installs commonly used packages, set up authentication
|
||||
and pre-download useful datasets. The mybinder.org community can
|
||||
make a plugin that gives you a single-node, single-repository mybinder.org.
|
||||
Plugins are very powerful, so the possibilities are endless.
|
||||
|
||||
## Design
|
||||
|
||||
[pluggy](https://github.com/pytest-dev/pluggy) is used to implement
|
||||
plugin functionality. TLJH exposes specific **hooks** that your plugin
|
||||
can provide implementations for. This allows us to have specific hook
|
||||
points in the application that can be explicitly extended by plugins,
|
||||
balancing the need to change TLJH internals in the future with the
|
||||
stability required for a good plugin ecosystem.
|
||||
|
||||
## Installing Plugins
|
||||
|
||||
Include `--plugin <install_name>` in the Installer script. See {ref}`topic/customizing-installer` for more info.
|
||||
|
||||
## Writing a simple plugins
|
||||
|
||||
We shall try to write a simple plugin that installs a few libraries,
|
||||
and use it to explain how the plugin mechanism works. We shall call
|
||||
this plugin `tljh-simple`.
|
||||
|
||||
### Plugin directory layout
|
||||
|
||||
We recommend creating a new git repo for your plugin. Plugins are
|
||||
normal python packages - however, since they are usually simpler,
|
||||
we recommend they live in one file.
|
||||
|
||||
For `tljh-simple`, the repository's structure should look like:
|
||||
|
||||
```none
|
||||
tljh_simple:
|
||||
- tljh_simple.py
|
||||
- setup.py
|
||||
- README.md
|
||||
- LICENSE
|
||||
```
|
||||
|
||||
The `README.md` (or `README.rst` file) contains human readable
|
||||
information about what your plugin does for your users. `LICENSE`
|
||||
specifies the license used by your plugin - we recommend the
|
||||
3-Clause BSD License, since that is what is used by TLJH itself.
|
||||
|
||||
### `setup.py` - metadata & registration
|
||||
|
||||
`setup.py` marks this as a python package, and contains metadata
|
||||
about the package itself. It should look something like:
|
||||
|
||||
```python
|
||||
from setuptools import setup
|
||||
|
||||
setup(
|
||||
name="tljh-simple",
|
||||
author="YuviPanda",
|
||||
version="0.1",
|
||||
license="3-clause BSD",
|
||||
url='https://github.com/yuvipanda/tljh-simple',
|
||||
entry_points={"tljh": ["simple = tljh_simple"]},
|
||||
py_modules=["tljh_simple"],
|
||||
)
|
||||
```
|
||||
|
||||
This is a mostly standard `setup.py` file. `entry_points={"tljh": ["simple = tljh_simple]}`
|
||||
'registers' the module `tljh_simple` (in file `tljh_simple.py`) with TLJH as a plugin.
|
||||
|
||||
### `tljh_simple.py` - implementation
|
||||
|
||||
In `tljh_simple.py`, you provide implementations for whichever hooks
|
||||
you want to extend.
|
||||
|
||||
A hook implementation is a function that has the following characteristics:
|
||||
|
||||
1. Has same name as the hook
|
||||
2. Accepts some or all of the parameters defined for the hook
|
||||
3. Is decorated with the `hookimpl` decorator function, imported from
|
||||
`tljh.hooks`.
|
||||
|
||||
The current list of available hooks and when they are called can be
|
||||
seen in [tljh/hooks.py](https://github.com/jupyterhub/the-littlest-jupyterhub/blob/main/tljh/hooks.py)
|
||||
in the source repository. Example implementations of each hook can be referenced from
|
||||
[integration-tests/plugins/simplest/tljh_simplest.py](https://github.com/jupyterhub/the-littlest-jupyterhub/blob/main/integration-tests/plugins/simplest/tljh_simplest.py).
|
||||
|
||||
This example provides an implementation for the `tljh_extra_user_conda_packages`
|
||||
hook, which can return a list of conda packages that'll be installed in users'
|
||||
environment from conda-forge.
|
||||
|
||||
```python
|
||||
from tljh.hooks import hookimpl
|
||||
|
||||
@hookimpl
|
||||
def tljh_extra_user_conda_packages():
|
||||
return [
|
||||
'xarray',
|
||||
'iris',
|
||||
'dask',
|
||||
]
|
||||
```
|
||||
|
||||
## Publishing plugins
|
||||
|
||||
Plugins are python packages and should be published on PyPI. Users
|
||||
can also install them directly from GitHub - although this is
|
||||
not good long term practice.
|
||||
|
||||
The python package should be named `tljh-<pluginname>`.
|
||||
|
||||
## List of known plugins
|
||||
|
||||
If you are looking for a way to extend or customize your TLJH deployment, you might want to look for existing plugins.
|
||||
|
||||
Here is a non-exhaustive list of known TLJH plugins:
|
||||
|
||||
- [tljh-pangeo](https://github.com/yuvipanda/tljh-pangeo): TLJH plugin for setting up the Pangeo Stack.
|
||||
- [tljh-voila-gallery](https://github.com/voila-dashboards/tljh-voila-gallery): TLJH plugin that installs a gallery of Voilà dashboards.
|
||||
- [tljh-repo2docker](https://github.com/plasmabio/tljh-repo2docker): TLJH plugin to build multiple user environments with
|
||||
[repo2docker](https://repo2docker.readthedocs.io).
|
||||
- [tljh-shared-directory](https://github.com/kafonek/tljh-shared-directory): TLJH plugin which sets up a _shared directory_
|
||||
for the Hub users in `/srv/scratch`.
|
||||
- [tljh-db](https://github.com/sinzlab/tljh-db): TLJH plugin for working with mysql databases.
|
||||
|
||||
If you have authored a plugin, please open a PR to add it to this list!
|
||||
|
||||
We also recommend adding the `tljh-plugin` topic to the GitHub repository to make it more discoverable:
|
||||
[https://github.com/topics/tljh-plugin](https://github.com/topics/tljh-plugin)
|
||||
@@ -1,147 +0,0 @@
|
||||
.. _contributing/plugins:
|
||||
|
||||
============
|
||||
TLJH Plugins
|
||||
============
|
||||
|
||||
TLJH plugins are the official way to make customized 'spins' or 'stacks'
|
||||
with TLJH as the base. For example, the earth sciences community can make
|
||||
a plugin that installs commonly used packages, set up authentication
|
||||
and pre-download useful datasets. The mybinder.org community can
|
||||
make a plugin that gives you a single-node, single-repository mybinder.org.
|
||||
Plugins are very powerful, so the possibilities are endless.
|
||||
|
||||
Design
|
||||
======
|
||||
|
||||
`pluggy <https://github.com/pytest-dev/pluggy>`_ is used to implement
|
||||
plugin functionality. TLJH exposes specific **hooks** that your plugin
|
||||
can provide implementations for. This allows us to have specific hook
|
||||
points in the application that can be explicitly extended by plugins,
|
||||
balancing the need to change TLJH internals in the future with the
|
||||
stability required for a good plugin ecosystem.
|
||||
|
||||
Installing Plugins
|
||||
==================
|
||||
|
||||
Include ``--plugin <install_name>`` in the Installer script. See :ref:`topic/customizing-installer` for more info.
|
||||
|
||||
Writing a simple plugins
|
||||
========================
|
||||
|
||||
We shall try to write a simple plugin that installs a few libraries,
|
||||
and use it to explain how the plugin mechanism works. We shall call
|
||||
this plugin ``tljh-simple``.
|
||||
|
||||
Plugin directory layout
|
||||
-----------------------
|
||||
|
||||
We recommend creating a new git repo for your plugin. Plugins are
|
||||
normal python packages - however, since they are usually simpler,
|
||||
we recommend they live in one file.
|
||||
|
||||
For ``tljh-simple``, the repository's structure should look like:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
tljh_simple:
|
||||
- tljh_simple.py
|
||||
- setup.py
|
||||
- README.md
|
||||
- LICENSE
|
||||
|
||||
The ``README.md`` (or ``README.rst`` file) contains human readable
|
||||
information about what your plugin does for your users. ``LICENSE``
|
||||
specifies the license used by your plugin - we recommend the
|
||||
3-Clause BSD License, since that is what is used by TLJH itself.
|
||||
|
||||
``setup.py`` - metadata & registration
|
||||
--------------------------------------
|
||||
|
||||
``setup.py`` marks this as a python package, and contains metadata
|
||||
about the package itself. It should look something like:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from setuptools import setup
|
||||
|
||||
setup(
|
||||
name="tljh-simple",
|
||||
author="YuviPanda",
|
||||
version="0.1",
|
||||
license="3-clause BSD",
|
||||
url='https://github.com/yuvipanda/tljh-simple',
|
||||
entry_points={"tljh": ["simple = tljh_simple"]},
|
||||
py_modules=["tljh_simple"],
|
||||
)
|
||||
|
||||
|
||||
This is a mostly standard ``setup.py`` file. ``entry_points={"tljh": ["simple = tljh_simple]}``
|
||||
'registers' the module ``tljh_simple`` (in file ``tljh_simple.py``) with TLJH as a plugin.
|
||||
|
||||
``tljh_simple.py`` - implementation
|
||||
-----------------------------------
|
||||
|
||||
In ``tljh_simple.py``, you provide implementations for whichever hooks
|
||||
you want to extend.
|
||||
|
||||
A hook implementation is a function that has the following characteristics:
|
||||
|
||||
#. Has same name as the hook
|
||||
#. Accepts some or all of the parameters defined for the hook
|
||||
#. Is decorated with the ``hookimpl`` decorator function, imported from
|
||||
``tljh.hooks``.
|
||||
|
||||
The current list of available hooks and when they are called can be
|
||||
seen in `tljh/hooks.py <https://github.com/jupyterhub/the-littlest-jupyterhub/blob/main/tljh/hooks.py>`_
|
||||
in the source repository. Example implementations of each hook can be referenced from
|
||||
`integration-tests/plugins/simplest/tljh_simplest.py
|
||||
<https://github.com/jupyterhub/the-littlest-jupyterhub/blob/main/integration-tests/plugins/simplest/tljh_simplest.py>`_.
|
||||
|
||||
|
||||
This example provides an implementation for the ``tljh_extra_user_conda_packages``
|
||||
hook, which can return a list of conda packages that'll be installed in users'
|
||||
environment from conda-forge.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from tljh.hooks import hookimpl
|
||||
|
||||
@hookimpl
|
||||
def tljh_extra_user_conda_packages():
|
||||
return [
|
||||
'xarray',
|
||||
'iris',
|
||||
'dask',
|
||||
]
|
||||
|
||||
|
||||
Publishing plugins
|
||||
==================
|
||||
|
||||
Plugins are python packages and should be published on PyPI. Users
|
||||
can also install them directly from GitHub - although this is
|
||||
not good long term practice.
|
||||
|
||||
The python package should be named ``tljh-<pluginname>``.
|
||||
|
||||
|
||||
List of known plugins
|
||||
=====================
|
||||
|
||||
If you are looking for a way to extend or customize your TLJH deployment, you might want to look for existing plugins.
|
||||
|
||||
Here is a non-exhaustive list of known TLJH plugins:
|
||||
|
||||
- `tljh-pangeo <https://github.com/yuvipanda/tljh-pangeo>`_: TLJH plugin for setting up the Pangeo Stack.
|
||||
- `tljh-voila-gallery <https://github.com/voila-dashboards/tljh-voila-gallery>`_: TLJH plugin that installs a gallery of Voilà dashboards.
|
||||
- `tljh-repo2docker <https://github.com/plasmabio/tljh-repo2docker>`_: TLJH plugin to build multiple user environments with
|
||||
`repo2docker <https://repo2docker.readthedocs.io>`_.
|
||||
- `tljh-shared-directory <https://github.com/kafonek/tljh-shared-directory>`_: TLJH plugin which sets up a *shared directory*
|
||||
for the Hub users in ``/srv/scratch``.
|
||||
- `tljh-db <https://github.com/sinzlab/tljh-db>`_: TLJH plugin for working with mysql databases.
|
||||
|
||||
If you have authored a plugin, please open a PR to add it to this list!
|
||||
|
||||
We also recommend adding the ``tljh-plugin`` topic to the GitHub repository to make it more discoverable:
|
||||
`https://github.com/topics/tljh-plugin <https://github.com/topics/tljh-plugin>`_
|
||||
62
docs/contributing/tests.md
Normal file
62
docs/contributing/tests.md
Normal file
@@ -0,0 +1,62 @@
|
||||
(contributing-tests)=
|
||||
|
||||
# Testing TLJH
|
||||
|
||||
Unit and integration tests are a core part of TLJH, as important as
|
||||
the code & documentation. They help validate that the code works as
|
||||
we think it does, and continues to do so when changes occur. They
|
||||
also help communicate in precise terms what we expect our code
|
||||
to do.
|
||||
|
||||
## Integration tests
|
||||
|
||||
TLJH is a _distribution_ where the primary value is the many
|
||||
opinionated choices we have made on components to use and how
|
||||
they fit together. Integration tests are perfect for testing
|
||||
that the various components fit together and work as they should.
|
||||
So we write a lot of integration tests, and put in more effort
|
||||
towards them than unit tests.
|
||||
|
||||
All integration tests are run in [GitHub Actions](https://github.com/jupyterhub/the-littlest-jupyterhub/actions)
|
||||
for each PR and merge, making sure we don't have broken tests
|
||||
for too long.
|
||||
|
||||
The integration tests are in the `integration-tests` directory
|
||||
in the git repository. `py.test` is used to write the integration
|
||||
tests. Each file should contain tests that can be run in any order
|
||||
against the same installation of TLJH.
|
||||
|
||||
### Running integration tests locally
|
||||
|
||||
You need `docker` installed and callable by the user running
|
||||
the integration tests without needing sudo.
|
||||
|
||||
You can then run the tests with:
|
||||
|
||||
```bash
|
||||
.github/integration-test.py run-test <name-of-run> <test-file-names>
|
||||
```
|
||||
|
||||
- `<name-of-run>` is an identifier for the tests - you can choose anything you want
|
||||
- `<test-file-names>>` is list of test files (under `integration-tests`) that should be run in one go.
|
||||
|
||||
For example, to run all the basic tests, you would write:
|
||||
|
||||
```bash
|
||||
.github/integration-test.py run-test basic-tests \
|
||||
test_hub.py \
|
||||
test_proxy.py \
|
||||
test_install.py \
|
||||
test_extensions.py
|
||||
```
|
||||
|
||||
This will run the tests in the three files against the same installation
|
||||
of TLJH and report errors.
|
||||
|
||||
If you would like to run the tests with a custom pip spec for the bootstrap script, you can use the `--bootstrap-pip-spec`
|
||||
parameter:
|
||||
|
||||
```bash
|
||||
.github/integration-test.py run-test <name-of-run> <test-file-names> \
|
||||
--bootstrap-pip-spec="git+https://github.com/your-username/the-littlest-jupyterhub.git@branch-name"
|
||||
```
|
||||
@@ -1,66 +0,0 @@
|
||||
.. _contributing/tests:
|
||||
|
||||
============
|
||||
Testing TLJH
|
||||
============
|
||||
|
||||
Unit and integration tests are a core part of TLJH, as important as
|
||||
the code & documentation. They help validate that the code works as
|
||||
we think it does, and continues to do so when changes occur. They
|
||||
also help communicate in precise terms what we expect our code
|
||||
to do.
|
||||
|
||||
Integration tests
|
||||
=================
|
||||
|
||||
TLJH is a *distribution* where the primary value is the many
|
||||
opinionated choices we have made on components to use and how
|
||||
they fit together. Integration tests are perfect for testing
|
||||
that the various components fit together and work as they should.
|
||||
So we write a lot of integration tests, and put in more effort
|
||||
towards them than unit tests.
|
||||
|
||||
All integration tests are run in `GitHub Actions <https://github.com/jupyterhub/the-littlest-jupyterhub/actions>`_
|
||||
for each PR and merge, making sure we don't have broken tests
|
||||
for too long.
|
||||
|
||||
The integration tests are in the ``integration-tests`` directory
|
||||
in the git repository. ``py.test`` is used to write the integration
|
||||
tests. Each file should contain tests that can be run in any order
|
||||
against the same installation of TLJH.
|
||||
|
||||
Running integration tests locally
|
||||
---------------------------------
|
||||
|
||||
You need ``docker`` installed and callable by the user running
|
||||
the integration tests without needing sudo.
|
||||
|
||||
You can then run the tests with:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
.github/integration-test.py run-test <name-of-run> <test-file-names>
|
||||
|
||||
- ``<name-of-run>`` is an identifier for the tests - you can choose anything you want
|
||||
- ``<test-file-names>>`` is list of test files (under ``integration-tests``) that should be run in one go.
|
||||
|
||||
For example, to run all the basic tests, you would write:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
.github/integration-test.py run-test basic-tests \
|
||||
test_hub.py \
|
||||
test_proxy.py \
|
||||
test_install.py \
|
||||
test_extensions.py
|
||||
|
||||
This will run the tests in the three files against the same installation
|
||||
of TLJH and report errors.
|
||||
|
||||
If you would like to run the tests with a custom pip spec for the bootstrap script, you can use the ``--bootstrap-pip-spec``
|
||||
parameter:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
.github/integration-test.py run-test <name-of-run> <test-file-names> \
|
||||
--bootstrap-pip-spec="git+https://github.com/your-username/the-littlest-jupyterhub.git@branch-name"
|
||||
Reference in New Issue
Block a user