Skip to content

Commit

Permalink
Add pyupgrade and doc8 hooks (#768)
Browse files Browse the repository at this point in the history
  • Loading branch information
blink1073 committed Mar 31, 2022
1 parent 45ce912 commit 25ec3ed
Show file tree
Hide file tree
Showing 61 changed files with 310 additions and 276 deletions.
12 changes: 12 additions & 0 deletions .pre-commit-config.yaml
Expand Up @@ -36,6 +36,18 @@ repos:
hooks:
- id: prettier

- repo: https://github.com/asottile/pyupgrade
rev: v2.31.1
hooks:
- id: pyupgrade
args: [--py37-plus]

- repo: https://github.com/PyCQA/doc8
rev: 0.11.0
hooks:
- id: doc8
args: [--max-line-length=200]

- repo: https://github.com/pycqa/flake8
rev: 4.0.1
hooks:
Expand Down
1 change: 0 additions & 1 deletion docs/source/conf.py
@@ -1,5 +1,4 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# Jupyter Server documentation build configuration file, created by
# sphinx-quickstart on Mon Apr 13 09:51:11 2015.
Expand Down
12 changes: 9 additions & 3 deletions docs/source/developers/dependency.rst
@@ -1,9 +1,15 @@
Depending on Jupyter Server
===========================

If your project depends directly on Jupyter Server, be sure to watch Jupyter Server's ChangeLog and pin your project to a version that works for your application. Major releases represent possible backwards-compatibility breaking API changes or features.

When a new major version in released on PyPI, a branch for that version will be created in this repository, and the version of the master branch will be bumped to the next major version number. That way, the master branch always reflects the latest un-released version.
If your project depends directly on Jupyter Server, be sure to watch Jupyter
Server's ChangeLog and pin your project to a version that works for your
application. Major releases represent possible backwards-compatibility breaking
API changes or features.

When a new major version in released on PyPI, a branch for that version will be
created in this repository, and the version of the master branch will be bumped
to the next major version number. That way, the master branch always reflects
the latest un-released version.

To install the latest patch of a given version:

Expand Down
48 changes: 38 additions & 10 deletions docs/source/developers/extensions.rst
Expand Up @@ -10,7 +10,9 @@ You can check some simple examples on the `examples folder
Authoring a basic server extension
==================================

The simplest way to write a Jupyter Server extension is to write an extension module with a ``_load_jupyter_server_extension`` function. This function should take a single argument, an instance of the ``ServerApp``.
The simplest way to write a Jupyter Server extension is to write an extension
module with a ``_load_jupyter_server_extension`` function. This function should
take a single argument, an instance of the ``ServerApp``.


.. code-block:: python
Expand Down Expand Up @@ -62,7 +64,11 @@ Then add this handler to Jupyter Server's Web Application through the ``_load_ju
Making an extension discoverable
--------------------------------

To make this extension discoverable to Jupyter Server, first define a ``_jupyter_server_extension_points()`` function at the root of the module/package. This function returns metadata describing how to load the extension. Usually, this requires a ``module`` key with the import path to the extension's ``_load_jupyter_server_extension`` function.
To make this extension discoverable to Jupyter Server, first define a
``_jupyter_server_extension_points()`` function at the root of the module/
package. This function returns metadata describing how to load the extension.
Usually, this requires a ``module`` key with the import path to the extension's
``_load_jupyter_server_extension`` function.

.. code-block:: python
Expand All @@ -85,7 +91,10 @@ Second, add the extension to the ServerApp's ``jpserver_extensions`` trait. This
"my_extension": True
}
or loaded from a JSON file in the ``jupyter_server_config.d`` directory under one of `Jupyter's paths`_. (See the `Distributing a server extension`_ section for details on how to automatically enabled your extension when users install it.)
or loaded from a JSON file in the ``jupyter_server_config.d`` directory under
one of `Jupyter's paths`_. (See the `Distributing a server extension`_ section
for details on how to automatically enabled your extension when users install
it.)

.. code-block:: python
Expand Down Expand Up @@ -161,7 +170,10 @@ The basic structure of an ExtensionApp is shown below:
# Perform any required shut down steps
The ``ExtensionApp`` uses the following methods and properties to connect your extension to the Jupyter server. You do not need to define a ``_load_jupyter_server_extension`` function for these apps. Instead, overwrite the pieces below to add your custom settings, handlers and templates:
The ``ExtensionApp`` uses the following methods and properties to connect your
extension to the Jupyter server. You do not need to define a
``_load_jupyter_server_extension`` function for these apps. Instead, overwrite
the pieces below to add your custom settings, handlers and templates:

Methods

Expand Down Expand Up @@ -212,7 +224,9 @@ Jinja templating from frontend extensions

Many Jupyter frontend applications use Jinja for basic HTML templating. Since this is common enough, Jupyter Server provides some extra mixin that integrate Jinja with Jupyter server extensions.

Use ``ExtensionAppJinjaMixin`` to automatically add a Jinja templating environment to an ``ExtensionApp``. This adds a ``<name>_jinja2_env`` setting to Tornado Web Server's settings that will be used by request handlers.
Use ``ExtensionAppJinjaMixin`` to automatically add a Jinja templating
environment to an ``ExtensionApp``. This adds a ``<name>_jinja2_env`` setting
to Tornado Web Server's settings that will be used by request handlers.

.. code-block:: python
Expand All @@ -224,7 +238,9 @@ Use ``ExtensionAppJinjaMixin`` to automatically add a Jinja templating environme
...
Pair the example above with ``ExtensionHandlers`` that also inherit the ``ExtensionHandlerJinjaMixin`` mixin. This will automatically load HTML templates from the Jinja templating environment created by the ``ExtensionApp``.
Pair the example above with ``ExtensionHandlers`` that also inherit the
``ExtensionHandlerJinjaMixin`` mixin. This will automatically load HTML
templates from the Jinja templating environment created by the ``ExtensionApp``.


.. code-block:: python
Expand Down Expand Up @@ -347,7 +363,10 @@ Putting it all together, authors can distribute their extension following this s
This is where the extension logic will live (i.e. custom extension handlers, config, etc). See the sections above for more information on how to create an extension.

3. Add the following JSON config file to the extension package.
The file should be named after the extension (e.g. ``myextension.json``) and saved in a subdirectory of the package with the prefix: ``jupyter-config/jupyter_server_config.d/``. The extension package will have a similar structure to this example:
The file should be named after the extension (e.g. ``myextension.json``)
and saved in a subdirectory of the package with the prefix:
``jupyter-config/jupyter_server_config.d/``. The extension package will
have a similar structure to this example:

.. code-block::
Expand Down Expand Up @@ -413,12 +432,18 @@ Putting it all together, authors can distribute their extension following this s
Migrating an extension to use Jupyter Server
============================================

If you're a developer of a `classic Notebook Server`_ extension, your extension should be able to work with *both* the classic notebook server and ``jupyter_server``.
If you're a developer of a `classic Notebook Server`_ extension, your extension
should be able to work with *both* the classic notebook server and
``jupyter_server``.

There are a few key steps to make this happen:

1. Point Jupyter Server to the ``load_jupyter_server_extension`` function with a new reference name.
The ``load_jupyter_server_extension`` function was the key to loading a server extension in the classic Notebook Server. Jupyter Server expects the name of this function to be prefixed with an underscore—i.e. ``_load_jupyter_server_extension``. You can easily achieve this by adding a reference to the old function name with the new name in the same module.
The ``load_jupyter_server_extension`` function was the key to loading a
server extension in the classic Notebook Server. Jupyter Server expects the
name of this function to be prefixed with an underscore—i.e.
``_load_jupyter_server_extension``. You can easily achieve this by adding a
reference to the old function name with the new name in the same module.

.. code-block:: python
Expand Down Expand Up @@ -483,7 +508,10 @@ There are a few key steps to make this happen:
)
3. (Optional) Point extension at the new favicon location.
The favicons in the Jupyter Notebook have been moved to a new location in Jupyter Server. If your extension is using one of these icons, you'll want to add a set of redirect handlers this. (In ``ExtensionApp``, this is handled automatically).
The favicons in the Jupyter Notebook have been moved to a new location in
Jupyter Server. If your extension is using one of these icons, you'll want
to add a set of redirect handlers this. (In ``ExtensionApp``, this is
handled automatically).

This usually means adding a chunk to your ``load_jupyter_server_extension`` function similar to this:

Expand Down
5 changes: 4 additions & 1 deletion docs/source/developers/websocket-protocols.rst
Expand Up @@ -8,7 +8,10 @@ The Jupyter Server needs to pass messages between kernels and the Jupyter web ap
ZeroMQ wire protocol
--------------------

The kernel wire protocol over ZeroMQ takes advantage of multipart messages, allowing to decompose a message into parts and to send and receive them unmerged. The following table shows the message format (the beginning has been omitted for clarity):
The kernel wire protocol over ZeroMQ takes advantage of multipart messages,
allowing to decompose a message into parts and to send and receive them
unmerged. The following table shows the message format (the beginning has been
omitted for clarity):

.. list-table:: Format of a kernel message over ZeroMQ socket (indices refer to parts, not bytes)
:header-rows: 1
Expand Down
8 changes: 6 additions & 2 deletions docs/source/operators/configuring-extensions.rst
Expand Up @@ -3,7 +3,9 @@
Configuring Extensions
======================

Some Jupyter Server extensions are also configurable applications. There are two ways to configure such extensions: i) pass arguments to the extension's entry point or ii) list configurable options in a Jupyter config file.
Some Jupyter Server extensions are also configurable applications. There are
two ways to configure such extensions: i) pass arguments to the extension's
entry point or ii) list configurable options in a Jupyter config file.

Jupyter Server looks for an extension's config file in a set of specific paths. Use the ``jupyter`` entry point to list these paths:

Expand Down Expand Up @@ -45,7 +47,9 @@ A Jupyter Server will automatically load config for each enabled extension. You
Extension config on the command line
------------------------------------

Server extension applications can also be configured from the command line, and multiple extension can be configured at the same time. Simply pass the traits (with their appropriate prefix) to the ``jupyter server`` entrypoint, e.g.:
Server extension applications can also be configured from the command line, and
multiple extension can be configured at the same time. Simply pass the traits
(with their appropriate prefix) to the ``jupyter server`` entrypoint, e.g.:

.. code-block:: console
Expand Down
6 changes: 5 additions & 1 deletion docs/source/operators/multiple-extensions.rst
Expand Up @@ -4,7 +4,11 @@
Managing multiple extensions
----------------------------

One of the major benefits of Jupyter Server is that you can run serve multiple Jupyter frontend applications above the same Tornado web server. That's because every Jupyter frontend application is now a server extension. When you run a Jupyter Server will multiple extensions enabled, each extension appends its own set of handlers and static assets to the server.
One of the major benefits of Jupyter Server is that you can run serve multiple
Jupyter frontend applications above the same Tornado web server.
That's because every Jupyter frontend application is now a server extension.
When you run a Jupyter Server will multiple extensions enabled, each extension
appends its own set of handlers and static assets to the server.

Listing extensions
~~~~~~~~~~~~~~~~~~
Expand Down
12 changes: 6 additions & 6 deletions docs/source/operators/public-server.rst
Expand Up @@ -113,13 +113,13 @@ Preparing a hashed password
You can prepare a hashed password manually, using the function
:func:`notebook.auth.security.passwd`:

.. code-block:: ipython
.. code-block:: python
In [1]: from jupyter_server.auth import passwd
In [2]: passwd()
Enter password:
Verify password:
Out[2]: 'sha1:67c9e60bb8b6:9ffede0825894254b2e042ea597d771089e11aed'
>>> from jupyter_server.auth import passwd
>>> passwd()
... Enter password:
... Verify password:
'sha1:67c9e60bb8b6:9ffede0825894254b2e042ea597d771089e11aed'
.. caution::

Expand Down
6 changes: 5 additions & 1 deletion docs/source/other/full-config.rst
Expand Up @@ -514,7 +514,11 @@ ServerApp.show_config_json : Bool
ServerApp.shutdown_no_activity_timeout : Int
Default: ``0``

Shut down the server after N seconds with no kernels or terminals running and no activity. This can be used together with culling idle kernels (MappingKernelManager.cull_idle_timeout) to shutdown the Jupyter server when it's not in use. This is not precisely timed: it may shut down up to a minute later. 0 (the default) disables this automatic shutdown.
Shut down the server after N seconds with no kernels or terminals running
and no activity. This can be used together with culling idle kernels
(MappingKernelManager.cull_idle_timeout) to shutdown the Jupyter server
when it's not in use. This is not precisely timed: it may shut down up to
a minute later. 0 (the default) disables this automatic shutdown.

ServerApp.ssl_options : Dict
Default: ``{}``
Expand Down
5 changes: 4 additions & 1 deletion docs/source/users/configuration.rst
Expand Up @@ -27,7 +27,10 @@ By default, Jupyter Server looks for server-specific configuration in a ``jupyte
The paths under ``config`` are listed in order of precedence. If the same trait is listed in multiple places, it will be set to the value from the file will highest precendence.


Jupyter Server uses IPython's traitlets system for configuration. Traits can be listed in a Python or JSON config file. You can quickly create a ``jupyter_server_config.py`` file in the ``.jupyter`` directory, with all the defaults commented out, use the following command:
Jupyter Server uses IPython's traitlets system for configuration. Traits can be
listed in a Python or JSON config file. You can quickly create a
``jupyter_server_config.py`` file in the ``.jupyter`` directory, with all the
defaults commented out, use the following command:

.. code-block:: console
Expand Down
4 changes: 3 additions & 1 deletion docs/source/users/index.rst
@@ -1,7 +1,9 @@
Documentation for Users
=======================

The Jupyter Server is a highly technical piece of the Jupyter Stack, so users probably won't import or install this library directly. These pages are to meant to help you in case you run into issues or bugs.
The Jupyter Server is a highly technical piece of the Jupyter Stack, so users
probably won't import or install this library directly. These pages are to
meant to help you in case you run into issues or bugs.


.. toctree::
Expand Down
5 changes: 4 additions & 1 deletion docs/source/users/installation.rst
Expand Up @@ -3,7 +3,10 @@
Installation
============

Most Jupyter users will **never need to install Jupyter Server manually**. Jupyter Web applications will include the (correct version) of Jupyter Server as a dependency. It's best to let those applications handle installation, because they may require a specific version of Jupyter Server.
Most Jupyter users will **never need to install Jupyter Server manually**.
Jupyter Web applications will include the (correct version) of Jupyter Server
as a dependency. It's best to let those applications handle installation,
because they may require a specific version of Jupyter Server.

If you decide to install manually, run:

Expand Down
9 changes: 7 additions & 2 deletions docs/source/users/launching.rst
Expand Up @@ -3,9 +3,14 @@
Launching a bare Jupyter Server
===============================

Most of the time, you won't need to start the Jupyter Server directly. Jupyter Web Applications (like Jupyter Notebook, Jupyterlab, Voila, etc.) come with their own entry points that start a server automatically.
Most of the time, you won't need to start the Jupyter Server directly. Jupyter
Web Applications (like Jupyter Notebook, Jupyterlab, Voila, etc.) come with
their own entry points that start a server automatically.

Sometimes, though, it can be useful to start Jupyter Server directly when you want to run multiple Jupyter Web applications at the same time. For more details, see the :ref:`Managing multiple extensions <managing-multiple-extensions>` page. If these extensions are enabled, you can simple run the following:
Sometimes, though, it can be useful to start Jupyter Server directly when you
want to run multiple Jupyter Web applications at the same time. For more
details, see the :ref:`Managing multiple extensions <managing-multiple-extensions>` page.
If these extensions are enabled, you can simple run the following:

.. code-block:: bash
Expand Down
14 changes: 7 additions & 7 deletions examples/simple/simple_ext1/application.py
Expand Up @@ -43,17 +43,17 @@ class SimpleApp1(ExtensionAppJinjaMixin, ExtensionApp):
def initialize_handlers(self):
self.handlers.extend(
[
(r"/{}/default".format(self.name), DefaultHandler),
(r"/{}/params/(.+)$".format(self.name), ParameterHandler),
(r"/{}/template1/(.*)$".format(self.name), TemplateHandler),
(r"/{}/redirect".format(self.name), RedirectHandler),
(r"/{}/typescript/?".format(self.name), TypescriptHandler),
(r"/{}/(.*)".format(self.name), ErrorHandler),
(rf"/{self.name}/default", DefaultHandler),
(rf"/{self.name}/params/(.+)$", ParameterHandler),
(rf"/{self.name}/template1/(.*)$", TemplateHandler),
(rf"/{self.name}/redirect", RedirectHandler),
(rf"/{self.name}/typescript/?", TypescriptHandler),
(rf"/{self.name}/(.*)", ErrorHandler),
]
)

def initialize_settings(self):
self.log.info("Config {}".format(self.config))
self.log.info(f"Config {self.config}")


# -----------------------------------------------------------------------------
Expand Down
12 changes: 6 additions & 6 deletions examples/simple/simple_ext1/handlers.py
Expand Up @@ -9,28 +9,28 @@
class DefaultHandler(ExtensionHandlerMixin, JupyterHandler):
def get(self):
# The name of the extension to which this handler is linked.
self.log.info("Extension Name in {} Default Handler: {}".format(self.name, self.name))
self.log.info(f"Extension Name in {self.name} Default Handler: {self.name}")
# A method for getting the url to static files (prefixed with /static/<name>).
self.log.info(
"Static URL for / in simple_ext1 Default Handler: {}".format(self.static_url(path="/"))
)
self.write("<h1>Hello Simple 1 - I am the default...</h1>")
self.write("Config in {} Default Handler: {}".format(self.name, self.config))
self.write(f"Config in {self.name} Default Handler: {self.config}")


class RedirectHandler(ExtensionHandlerMixin, JupyterHandler):
def get(self):
self.redirect("/static/{}/favicon.ico".format(self.name))
self.redirect(f"/static/{self.name}/favicon.ico")


class ParameterHandler(ExtensionHandlerMixin, JupyterHandler):
def get(self, matched_part=None, *args, **kwargs):
var1 = self.get_argument("var1", default=None)
components = [x for x in self.request.path.split("/") if x]
self.write("<h1>Hello Simple App 1 from Handler.</h1>")
self.write("<p>matched_part: {}</p>".format(url_escape(matched_part)))
self.write("<p>var1: {}</p>".format(url_escape(var1)))
self.write("<p>components: {}</p>".format(components))
self.write(f"<p>matched_part: {url_escape(matched_part)}</p>")
self.write(f"<p>var1: {url_escape(var1)}</p>")
self.write(f"<p>components: {components}</p>")


class BaseTemplateHandler(ExtensionHandlerJinjaMixin, ExtensionHandlerMixin, JupyterHandler):
Expand Down

0 comments on commit 25ec3ed

Please sign in to comment.