192 строки
7.1 KiB
ReStructuredText
192 строки
7.1 KiB
ReStructuredText
.. _specification:
|
|
|
|
==============================
|
|
WWT KDR Protocol Specification
|
|
==============================
|
|
|
|
This document specifies the interactions between the WWT kernel data relay (KDR)
|
|
and various Jupyter kernels that use it to publish data. The reference kernel
|
|
implmentation is found in `pywwt`_.
|
|
|
|
.. _pywwt: https://github.com/WorldWideTelescope/pywwt/
|
|
|
|
|
|
URL Structure
|
|
=============
|
|
|
|
The URLs that are ultimately provided by the KDR have the form:
|
|
|
|
.. code-block::
|
|
|
|
{base-url}/wwtkdr/{key}/{entry...}
|
|
|
|
Here, ``base-url`` is the base URL of the Jupyter server, which is
|
|
easily determined on the server side and is not-so-easily determined on the
|
|
kernel side. The base URL is not necessarily absolute, however, and there may be
|
|
different kinds of proxies or redirectors in place that prevent either the
|
|
kernel *or* the server from knowing the true, actual public URL at which their
|
|
content is ultimately made available. The only way to reliably construct a fully
|
|
absolute URL is in the frontend JavaScript code, by combining a KDR URL with the
|
|
current window's ``location``, or in a server request handler where the request
|
|
origin is specified.
|
|
|
|
The ``key`` is a unique identifier associated with exactly one Jupyter kernel. A
|
|
running kernel must “claim” a key before any data it publishes will be
|
|
accessible. Later on, a different kernel can override the claim and take over
|
|
the association between key and kernel; this functionality is required so that
|
|
URLs have the possibility of continuing to work across kernel restarts. A single
|
|
kernel may claim multiple keys. Keys starting with an underscore character
|
|
(``_``) are reserved and may not be claimed.
|
|
|
|
The ``entry...`` identifies resources published by a specific kernel. The
|
|
structure and semantics of the ``entry`` portion of the URL are unspecified;
|
|
each kernel may use whichever scheme it deems appropriate.
|
|
|
|
|
|
Claiming Keys
|
|
=============
|
|
|
|
A kernel can claim a URL key by publishing a message of type
|
|
``wwtkdr_claim_key`` on its `IOPub socket`_. The message content should have the
|
|
form:
|
|
|
|
.. code-block::
|
|
|
|
{
|
|
'key': $key:str
|
|
}
|
|
|
|
Where ``$key`` is the key being claimed by the kernel. This value should not be
|
|
empty and it should *not* be URL-escaped. If the claimed key is illegal (e.g. it
|
|
starts with an underscore) or the claim message is otherwise invalid, it is
|
|
ignored by the server.
|
|
|
|
.. _IOPub socket: https://jupyter-client.readthedocs.io/en/stable/messaging.html
|
|
|
|
|
|
Requesting Resources
|
|
====================
|
|
|
|
When the server receives an HTTP request for a KDR URL path, the key will be
|
|
used to map the request to a specific kernel. If the key is unregistered, or if
|
|
it is associated with a dead kernel, the requestor will receive a 404 error.
|
|
|
|
On a valid HTTP GET request, the associated kernel will be sent a message on its
|
|
`shell socket`_ of type ``wwtkdr_resource_request`` with the following content
|
|
structure:
|
|
|
|
.. _shell socket: https://jupyter-client.readthedocs.io/en/stable/messaging.html
|
|
|
|
.. code-block::
|
|
|
|
{
|
|
'method': 'GET',
|
|
'authenticated': $authenticated:bool,
|
|
'url': $url:str,
|
|
'key': $key:str,
|
|
'entry': $entry:str
|
|
}
|
|
|
|
The ``$key`` string provides the key of the request URL. Because a kernel can
|
|
claim more than one key, it is needed for disambiguation. The key value has been
|
|
decoded: if the literal URL text is ``my%2Fkey``, the value if ``$key`` will be
|
|
``my/key``.
|
|
|
|
The ``$url`` string gives the absolute URL of the HTTP request. Due to the way
|
|
that the Tornado framework works, there are some normalizations that are applied
|
|
before the KDR can do anything about it: ``foo/../bar`` becomes ``bar``, and
|
|
``./foo`` becomes ``foo``. But other constructs, such as ``foo//bar``, are not
|
|
normalized.
|
|
|
|
The ``$entry`` string identifies the resource being requested. The relay is not
|
|
responsible for, or capable of, checking its validity. For the time being, the
|
|
value is merely extracted from the URL and relayed to the kernel, including the
|
|
normalizations described above. Clients should use this value instead of trying
|
|
to parse anything out of ``$url``.
|
|
|
|
The ``$authenticated`` boolean indicates whether the request is coming from an
|
|
authenticated client, as determined by the Tornado framework. It is up to the
|
|
kernel to determine if unauthenticated users should be allowed to access the
|
|
resources that it publishes.
|
|
|
|
The kernel should reply on its shell socket with one or more messages of type
|
|
``wwtkdr_resource_reply``. While every reply message must contain some baseline
|
|
JSON content, the *first* reply message must contain additional fields
|
|
(analogous to HTTP header data). Every reply message, except for the last one,
|
|
must also be associated with one or more byte buffers, which contain the
|
|
resource binary content to be returned to the client that has connected to the
|
|
server. The final reply message is allowed to arrive without any
|
|
associated buffers.
|
|
|
|
The JSON content of the *every* reply message should contain the following fields:
|
|
|
|
.. code-block::
|
|
|
|
{
|
|
'status': $status:str,
|
|
'seq': $seq:int,
|
|
'more': $more:bool
|
|
}
|
|
|
|
Furthermore, the JSON content of the *first* reply message should contain the
|
|
following additional fields:
|
|
|
|
.. code-block::
|
|
|
|
{
|
|
'http_status': $httpStatus:int,
|
|
'http_headers': $httpHeaders:list<[str, str]>,
|
|
}
|
|
|
|
The ``$status`` field is a Jupyter messaging status indicator. It should be
|
|
``"ok"`` if the request was processed successfully (even if the resulting HTTP
|
|
status is an error status). If an error was encountered, the value should be
|
|
``"error"``, and the structure of the reply should be as described in `the
|
|
jupyter_client documentation`_. The value of the ``evalue`` JSON field, if
|
|
present, will be relayed to the requestor as part of an HTTP 500 error.
|
|
|
|
.. _the jupyter_client documentation: https://jupyter-client.readthedocs.io/en/stable/messaging.html#request-reply
|
|
|
|
The ``$seq`` field gives a sequence number for each reply message, starting at
|
|
zero and increasing by one with each reply. This is needed because some
|
|
implementations of the Jupyter messaging protocol don't guarantee in-order
|
|
message delivery.
|
|
|
|
The ``$more`` field indicates whether more reply messages will be sent. If your
|
|
implementation doesn't "know" when the last reply will be sent until all data
|
|
have been transferred, send a final message with no associated byte buffers.
|
|
|
|
On the first reply, the ``$httpStatus`` field should give an HTTP status code
|
|
that will be relayed to the requesting client. The ``$httpHeaders`` field should
|
|
be a list of sub-lists, each sub-list consisting of two strings: an HTTP header
|
|
name and a header value. These will be included in the HTTP response issued by
|
|
the relay, and should include fields such as ``Content-Type``.
|
|
|
|
|
|
Support Interfaces
|
|
==================
|
|
|
|
The KDR provides one additional support API. New APIs, or extensions to existing
|
|
APIs, may be added in the future.
|
|
|
|
Probe API
|
|
---------
|
|
|
|
A request to the following URL may be used by a frontend to probe whether the
|
|
KDR server extension is available:
|
|
|
|
.. code-block::
|
|
|
|
{base-url}/wwtkdr/_probe
|
|
|
|
If the extension is installed, the following JSON content will be returned:
|
|
|
|
.. code-block::
|
|
|
|
{
|
|
'status': 'ok'
|
|
}
|
|
|
|
This API is marked as requiring authentication, so it must be accessed from a
|
|
session that is logged into the current Jupyter session.
|