This commit is contained in:
Peter Williams 2021-07-02 18:10:49 -04:00
Коммит 5060c283d8
25 изменённых файлов: 819 добавлений и 0 удалений

Просмотреть файл

@ -0,0 +1,5 @@
[repo]
upstream_urls = [
'git@github.com:WorldWideTelescope/wwt_kernel_data_relay.git',
'https://github.com/WorldWideTelescope/wwt_kernel_data_relay.git',
]

6
.coveragerc Normal file
Просмотреть файл

@ -0,0 +1,6 @@
[report]
omit = wwt_kernel_data_relay/*tests/*
exclude_lines =
pragma: no cover
if __name__ == .__main__.:
raise NotImplementedError

8
.gitignore поставляемый Normal file
Просмотреть файл

@ -0,0 +1,8 @@
*.py[cod]
*.egg
*.egg-info
/dist/
/build/
/eggs/
/sdist/
__pycache__/

15
.readthedocs.yml Normal file
Просмотреть файл

@ -0,0 +1,15 @@
version: 2
build:
image: latest
python:
version: 3.7
install:
- method: pip
path: .
extra_requirements:
- docs
# Don't build any extra formats
formats: []

8
CHANGELOG.md Normal file
Просмотреть файл

@ -0,0 +1,8 @@
# See elsewhere for changelog
This projects release notes are curated from the Git history of its main
branch. You can find them by looking at [the version of this file on the
`release` branch][branch] or the [GitHub release history][gh-releases].
[branch]: https://github.com/WorldWideTelescope/wwt_kernel_data_relay/blob/release/CHANGELOG.md
[gh-releases]: https://github.com/WorldWideTelescope/wwt_kernel_data_relay/releases

18
LICENSE Normal file
Просмотреть файл

@ -0,0 +1,18 @@
The MIT License (MIT)
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

15
MANIFEST.in Normal file
Просмотреть файл

@ -0,0 +1,15 @@
include LICENSE
include .coveragerc
include *.md
include *.yml
graft docs
prune docs/_build
graft wwt_kernel_data_relay/tests
global-exclude *~
global-exclude *.pyc
global-exclude *.pyo
global-exclude .git
global-exclude .ipynb_checkpoints

79
README.md Normal file
Просмотреть файл

@ -0,0 +1,79 @@
# WWT Kernel Data Relay
<!--pypi-begin-->
[wwt_kernel_data_relay] is a [Jupyter server extension][ext] that enables
[Jupyter kernels][kernels] to publish some of their data files to the Web; that
is, to request that the Jupyter HTTP server make them accessible at a
predictable URL. This functionality is used by [pywwt], the [AAS] [WorldWide
Telescope] Python library, to expose kernel-side data assets for visualization
inside the WWT [research app][rapp].
[wwt_kernel_data_relay]: https://github.com/WorldWideTelescope/wwt_kernel_data_relay/
[ext]: https://jupyter-notebook.readthedocs.io/en/stable/extending/handlers.html
[kernels]: https://jupyter.readthedocs.io/en/latest/projects/kernels.html
[pywwt]: https://pywwt.readthedocs.io/
[AAS]: https://aas.org/
[WorldWide Telescope]: http://www.worldwidetelescope.org/
[rapp]: https://docs.worldwidetelescope.org/research-app/latest/
<!--pypi-end-->
## Installation
Install [wwt_kernel_data_relay] with [pip]:
```
pip install wwt_kernel_data_relay
```
[pip]: https://pip.pypa.io/
## Contributions
Contributions to [wwt_kernel_data_relay] are welcome! See
[the WorldWide Telescope contributors guide][contrib] for applicable information. We
use a standard workflow with issues and pull requests. All participants in
[wwt_kernel_data_relay] and the WWT communities must abide by the
[WWT Code of Conduct].
[contrib]: https://worldwidetelescope.github.io/contributing/
[WWT Code of Conduct]: https://worldwidetelescope.github.io/code-of-conduct/
## Release History
Releases of [wwt_kernel_data_relay] are logged in the file
[CHANGELOG.md](https://github.com/WorldWideTelescope/wwt_kernel_data_relay/blob/release/CHANGELOG.md)
on the `release` branch of this repository, as well as release listings
maintained by
[GitHub](https://github.com/WorldWideTelescope/wwt_kernel_data_relay/releases) and
[PyPI](https://pypi.org/project/wwt_kernel_data_relay/#history).
## Dependencies
[wwt_kernel_data_relay] is a [Jupyter server extension][ext] so it is only
useful if the Jupyter [notebook] package is installed.
[notebook]: https://jupyter-notebook.readthedocs.io/
## Legalities
[wwt_kernel_data_relay] is copyright the .NET Foundation. It is licensed under the
[MIT License](./LICENSE).
## Acknowledgments
[wwt_kernel_data_relay] is part of the AAS WorldWide Telescope system, a [.NET
Foundation] project managed by the non-profit [American Astronomical Society]
(AAS). Work on WWT has been supported by the AAS, the US [National Science
Foundation], and other partners. See [the WWT user website][acks] for details.
[.NET Foundation]: https://dotnetfoundation.org/
[American Astronomical Society]: https://aas.org/
[National Science Foundation]: https://www.nsf.gov/
[acks]: https://worldwidetelescope.org/about/acknowledgments/

1
docs/.gitignore поставляемый Normal file
Просмотреть файл

@ -0,0 +1 @@
/_build/

20
docs/Makefile Normal file
Просмотреть файл

@ -0,0 +1,20 @@
# Minimal makefile for Sphinx documentation
#
# You can set these variables from the command line.
SPHINXOPTS = -W
SPHINXBUILD = python -msphinx
SPHINXPROJ = wwt_kernel_data_relay
SOURCEDIR = .
BUILDDIR = _build
# Put it first so that "make" without argument is like "make help".
help:
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
.PHONY: help Makefile
# Catch-all target: route all unknown targets to Sphinx using the new
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
%: Makefile
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)

92
docs/_static/copybutton.js поставляемый Normal file
Просмотреть файл

@ -0,0 +1,92 @@
// Copyright (c) 2014-2018, Astropy Developers
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice, this
// list of conditions and the following disclaimer in the documentation and/or
// other materials provided with the distribution.
// * Neither the name of the Astropy Team nor the names of its contributors may be
// used to endorse or promote products derived from this software without
// specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
$(document).ready(function() {
/* Add a [>>>] button on the top-right corner of code samples to hide
* the >>> and ... prompts and the output and thus make the code
* copyable. */
var div = $('.highlight-python .highlight,' +
'.highlight-python3 .highlight,' +
'.highlight-default .highlight')
var pre = div.find('pre');
// get the styles from the current theme
pre.parent().parent().css('position', 'relative');
var hide_text = 'Hide the prompts and output';
var show_text = 'Show the prompts and output';
var border_width = pre.css('border-top-width');
var border_style = pre.css('border-top-style');
var border_color = pre.css('border-top-color');
var button_styles = {
'cursor':'pointer', 'position': 'absolute', 'top': '0', 'right': '0',
'border-color': border_color, 'border-style': border_style,
'border-width': '1px', 'color': border_color, 'font-size': '11px',
'color': '#aaaaaa',
'padding-left': '0.2em', 'padding-right': '0.2em',
'border-radius': '0 3px 0 0'
}
// create and add the button to all the code blocks that contain >>>
div.each(function(index) {
var jthis = $(this);
if (jthis.find('.gp').length > 0) {
var button = $('<span class="copybutton">Hide prompt</span>');
button.css(button_styles)
button.attr('title', hide_text);
button.data('hidden', 'false');
jthis.prepend(button);
}
// tracebacks (.gt) contain bare text elements that need to be
// wrapped in a span to work with .nextUntil() (see later)
jthis.find('pre:has(.gt)').contents().filter(function() {
return ((this.nodeType == 3) && (this.data.trim().length > 0));
}).wrap('<span>');
});
// define the behavior of the button when it's clicked
$('.copybutton').click(function(e){
e.preventDefault();
var button = $(this);
if (button.data('hidden') === 'false') {
// hide the code output
button.parent().find('.go, .gp, .gt').hide();
button.next('pre').find('.gt').nextUntil('.gp, .go').css('visibility', 'hidden');
// button.css('text-decoration', 'line-through');
button.text('Show prompt');
button.attr('title', show_text);
button.data('hidden', 'true');
} else {
// show the code output
button.parent().find('.go, .gp, .gt').show();
button.next('pre').find('.gt').nextUntil('.gp, .go').css('visibility', 'visible');
// button.css('text-decoration', 'none');
button.text('Hide prompt');
button.attr('title', hide_text);
button.data('hidden', 'false');
}
});
});

24
docs/_templates/layout.html поставляемый Normal file
Просмотреть файл

@ -0,0 +1,24 @@
{% extends "!layout.html" %}
{%- block extrahead %}
{% if not embedded %}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script type="text/javascript" src="{{ pathto('_static/copybutton.js', 1) }}"></script>
{% endif %}
{% endblock %}
{# astropy hardcodes a link to astropy.org in the header bar, which we don't want #}
{# It also hardcodes an Astropy logo in the `a.brand` element that we remove #}
{% block header %}
<div class="topbar">
<a class="brand" title="{{ _('Documentation Home') }}" href="{{ pathto(master_doc) }}" style="background: transparent;"><span id="logotext1">{{ theme_logotext1 }}</span><span id="logotext2">{{ theme_logotext2 }}</span><span id="logotext3">{{ theme_logotext3 }}</span></a>
<ul>
<li><a title="{{ _('General Index') }}" href="{{ pathto('genindex') }}">Index</a></li>
<li><a title="{{ _('Module Index') }}" href="{{ pathto('py-modindex') }}">Modules</a></li>
<li>
{% block sidebarsearch %}
{% include "searchbox.html" %}
{% endblock %}
</li>
</ul>
</div>
{% endblock %}

11
docs/api.rst Normal file
Просмотреть файл

@ -0,0 +1,11 @@
=============
API Reference
=============
.. automodapi:: wwt_kernel_data_relay
:no-inheritance-diagram:
:no-inherited-members:
.. automodapi:: wwt_kernel_data_relay.serverextension
:no-inheritance-diagram:
:no-inherited-members:

Просмотреть файл

@ -0,0 +1,6 @@
load_jupyter_server_extension
=============================
.. currentmodule:: wwt_kernel_data_relay
.. autofunction:: load_jupyter_server_extension

Просмотреть файл

@ -0,0 +1,6 @@
load_jupyter_server_extension
=============================
.. currentmodule:: wwt_kernel_data_relay.serverextension
.. autofunction:: load_jupyter_server_extension

56
docs/conf.py Normal file
Просмотреть файл

@ -0,0 +1,56 @@
# -*- coding: utf-8 -*-
project = 'wwt_kernel_data_relay'
author = 'The AAS WorldWide Telescope Team'
copyright = '2019-2021 the .NET Foundation'
release = '0.dev0' # cranko project-version
version = '.'.join(release.split('.')[:2])
extensions = [
'sphinx.ext.autodoc',
'sphinx.ext.doctest',
'sphinx.ext.intersphinx',
'sphinx.ext.mathjax',
'sphinx.ext.viewcode',
'sphinx_automodapi.automodapi',
'sphinx_automodapi.smart_resolver',
'numpydoc',
]
templates_path = ['_templates']
source_suffix = '.rst'
master_doc = 'index'
language = None
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
pygments_style = 'sphinx'
todo_include_todos = False
html_theme = 'bootstrap-astropy'
html_theme_options = {
'logotext1': 'wwt_kernel_data_relay',
'logotext2': '',
'logotext3': ':docs',
'astropy_project_menubar': False,
}
html_static_path = ['_static']
htmlhelp_basename = 'wwtkerneldatarelaydoc'
intersphinx_mapping = {
'python': (
'https://docs.python.org/3/',
(None, 'http://data.astropy.org/intersphinx/python3.inv')
),
}
numpydoc_show_class_members = False
nitpicky = True
nitpick_ignore = []
default_role = 'obj'
html_logo = 'images/logo.png'
linkcheck_retries = 5
linkcheck_timeout = 10

Двоичные данные
docs/images/logo.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 266 KiB

51
docs/index.rst Normal file
Просмотреть файл

@ -0,0 +1,51 @@
=============================
WWT Jupyter Kernel Data Relay
=============================
`wwt_kernel_data_relay`_ is a `Jupyter server extension`_ that enables `Jupyter
kernels`_ to publish some of their data files to the Web; that is, to request
that the Jupyter HTTP server make them accessible at a predictable URL. This
functionality is used by `pywwt`_ to expose kernel-side data assets for
visualization inside the `WWT research app`_.
.. _wwt_kernel_data_relay: https://github.com/WorldWideTelescope/wwt_kernel_data_relay/
.. _Jupyter server extension: https://jupyter-notebook.readthedocs.io/en/stable/extending/handlers.html
.. _Jupyter kernels: https://jupyter.readthedocs.io/en/latest/projects/kernels.html
.. _pywwt: https://pywwt.readthedocs.io/
.. _WWT research app: https://docs.worldwidetelescope.org/research-app/latest/
Detailed Table of Contents
==========================
.. toctree::
:maxdepth: 2
installation
specification
api
Getting help
============
If you run into any issues when using `wwt_kernel_data_relay`_, please open an
issue `on its GitHub repository
<https://github.com/WorldWideTelescope/wwt_kernel_data_relay/issues>`_.
Acknowledgments
===============
`wwt_kernel_data_relay`_ is part of the `AAS`_ `WorldWide Telescope`_ system, a
`.NET Foundation`_ project managed by the non-profit `American Astronomical
Society`_ (AAS). Work on WWT has been supported by the AAS, the US `National
Science Foundation`_, and other partners. See `the WWT user website`_ for
details.
.. _.NET Foundation: https://dotnetfoundation.org/
.. _AAS: https://aas.org/
.. _WorldWide Telescope: https://worldwidetelescope.org/home/
.. _American Astronomical Society: https://aas.org/
.. _National Science Foundation: https://www.nsf.gov/
.. _the WWT user website: https://worldwidetelescope.org/about/acknowledgments/

39
docs/installation.rst Normal file
Просмотреть файл

@ -0,0 +1,39 @@
================================
Installing wwt_kernel_data_relay
================================
Installing wwt_kernel_data_relay with pip
=========================================
You can install the latest release of ``wwt_kernel_data_relay`` using pip_::
pip install wwt_kernel_data_relay
.. _pip: https://pip.pypa.io/en/stable/
Dependencies
============
If you install ``wwt_kernel_data_relay`` using pip_ as described above, any
required dependencies will get installed automatically. The `README in the Git
repository`_ lists the current dependencies if you would like to see an
explict list.
.. _README in the Git repository: https://github.com/WorldWideTelescope/wwt_kernel_data_relay/#readme
Installing the developer version
================================
If you want to use the very latest developer version, you should clone `this
repository <https://github.com/WorldWideTelescope/wwt_kernel_data_relay/>`_ and manually
install the package in “editable” mode::
git clone https://github.com/WorldWideTelescope/wwt_kernel_data_relay.git
cd wwt_kernel_data_relay
pip install -e .
You can run the test suite with the command::
pytest wwt_kernel_data_relay

36
docs/make.bat Normal file
Просмотреть файл

@ -0,0 +1,36 @@
@ECHO OFF
pushd %~dp0
REM Command file for Sphinx documentation
if "%SPHINXBUILD%" == "" (
set SPHINXBUILD=python -msphinx
)
set SOURCEDIR=.
set BUILDDIR=_build
set SPHINXPROJ=wwt_kernel_data_relay
if "%1" == "" goto help
%SPHINXBUILD% >NUL 2>NUL
if errorlevel 9009 (
echo.
echo.The Sphinx module was not found. Make sure you have Sphinx installed,
echo.then set the SPHINXBUILD environment variable to point to the full
echo.path of the 'sphinx-build' executable. Alternatively you may add the
echo.Sphinx directory to PATH.
echo.
echo.If you don't have Sphinx installed, grab it from
echo.http://sphinx-doc.org/
exit /b 1
)
%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS%
goto end
:help
%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS%
:end
popd

75
docs/specification.rst Normal file
Просмотреть файл

@ -0,0 +1,75 @@
.. _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.
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 notebook 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``.
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.
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:: json
{
'key': $key
}
Where ``$key`` is the key being claimed by the kernel. This value should not be
empty and it should *not* be URL-escaped.
.. _IOPub socket: https://jupyter-client.readthedocs.io/en/stable/messaging.html
Requesting Resources
====================
When the server receives a request for a KDR URL path, the key will be used to
map the request to a specific kernel. That 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:: json
{
'method': 'GET',
'entry': $entry,
}

4
pyproject.toml Normal file
Просмотреть файл

@ -0,0 +1,4 @@
[tool.cranko]
extra_python_rewrite_files = [
"docs/conf.py"
]

79
setup.py Normal file
Просмотреть файл

@ -0,0 +1,79 @@
# -*- mode: python; coding: utf-8 -*-
# Copyright 2019-2021 the .NET Foundation
# Licensed under the MIT License
import os
from setuptools import setup, Extension
def get_long_desc():
in_preamble = True
lines = []
with open('README.md', 'rt', encoding='utf8') as f:
for line in f:
if in_preamble:
if line.startswith('<!--pypi-begin-->'):
in_preamble = False
else:
if line.startswith('<!--pypi-end-->'):
break
else:
lines.append(line)
lines.append('''
For more information, including installation instructions, please visit [the
project homepage].
[the project homepage]: https://github.com/WorldWideTelescope/wwt_kernel_data_relay/
''')
return ''.join(lines)
setup_args = dict(
name = 'wwt_kernel_data_relay', # cranko project-name
version = '0.dev0', # cranko project-version
description = 'Jupyter server extension to allow kernels to make data web-accessible',
long_description = get_long_desc(),
long_description_content_type = 'text/markdown',
url = 'https://github.com/WorldWideTelescope/wwt_kernel_data_relay/',
license = 'MIT',
platforms = 'Linux, Mac OS X, Windows',
author = 'AAS WorldWide Telescope Team',
author_email = 'wwt@aas.org',
classifiers = [
'Intended Audience :: Science/Research',
'License :: OSI Approved :: MIT License',
'Operating System :: OS Independent',
'Programming Language :: Python :: 3.7',
'Programming Language :: Python :: 3.8',
'Programming Language :: Python :: 3.9',
'Topic :: Scientific/Engineering :: Astronomy',
'Topic :: Scientific/Engineering :: Visualization',
],
packages = [
'wwt_kernel_data_relay',
#'wwt_kernel_data_relay.tests',
],
include_package_data = True,
install_requires = [],
extras_require = {
'test': [
'pytest-cov',
],
'docs': [
'astropy-sphinx-theme',
'numpydoc',
'sphinx',
'sphinx-automodapi',
],
},
)
if __name__ == '__main__':
setup(**setup_args)

Просмотреть файл

@ -0,0 +1,14 @@
# Copyright 2021 the .NET Foundation
# Licensed under the MIT License
"""
The main module for the WWT kernel data relay Jupyter server extension.
It contains no nontrivial functionality of its own.
"""
from .serverextension import load_jupyter_server_extension # noqa
# See: https://jupyter-notebook.readthedocs.io/en/stable/examples/Notebook/Distributing%20Jupyter%20Extensions%20as%20Python%20Packages.html
def _jupyter_server_extension_paths():
return [{"module": "wwt_kernel_data_relay.serverextension"}]

Просмотреть файл

@ -0,0 +1,151 @@
# Copyright 2021 the .NET Foundation
# Licensed under the MIT License
"""
The WWT kernel data relay Jupyter notebook server extension.
"""
from tornado import gen
from jupyter_client.session import Session
from notebook.utils import url_path_join
from notebook.base.handlers import IPythonHandler
__all__ = ['load_jupyter_server_extension']
class Registry(object):
"""
A registry of kernels that have expressed an interest in publishing data files.
"""
def __init__(self):
self._key_to_kid = {}
def watch_new_kernel(self, kernel_id, km):
session = Session(
config = km.session.config,
key = km.session.key,
)
stream = km.connect_iopub()
print('WWTKDR: watching kernel', kernel_id)
def watch_iopubs(msg_list):
idents, fed_msg_list = session.feed_identities(msg_list)
msg = session.deserialize(fed_msg_list)
msg_type = msg['header']['msg_type']
if msg_type == 'wwtkdr_claim_key':
key = msg['content'].get('key')
if not key:
print('WWTKDR: missing/empty key in claim?')
else:
print(f'WWTKDR: key {key} claimed by kernel {kernel_id}')
self._key_to_kid[key] = kernel_id
stream.on_recv(watch_iopubs)
def get(self, key):
return self._key_to_kid.get(key)
class DataRequestHandler(IPythonHandler):
def initialize(self, registry):
self.registry = registry
@gen.coroutine
def get(self, key, entry):
authenticated = bool(self.current_user)
print('************* WWTKDR HANDLER *****************')
print('auth:', authenticated)
print('key:', key)
print('entry:', entry)
kernel_id = self.registry.get(key)
if kernel_id is None:
self.clear()
self.set_status(404)
self.finish(f'unrecognized WWTKDR key {key!r}')
return
print('kernel_id:', kernel_id)
try:
km = self.kernel_manager.get_kernel(kernel_id)
except Exception as e:
self.clear()
self.set_status(404)
self.finish(f'could not get kernel for WWTKDR key {key!r}: {e}')
return
kc = km.client()
content = dict(
method = 'GET',
entry = entry,
)
msg = kc.session.msg('wwtkdr_resource_request', content)
msg_id = msg['header']['msg_id']
kc.shell_channel.send(msg)
self.clear()
self.set_header('Content-Type', 'image/png') # XXXXXXXXXX
while True:
reply = yield kc.get_shell_msg(timeout=30)
print('============= reply:')
print(reply)
print('====================')
if reply['parent_header'].get('msg_id') != msg_id:
print('** not my message')
continue
status = reply['content'].get('status', 'unspecified')
if status != 'ok':
raise HTTPError(500)
if not len(reply['buffers']):
break
self.write(bytes(reply['buffers'][0]))
self.finish(b'')
def load_jupyter_server_extension(nb_server_app):
"""
Initialize the server extension.
The argument ``nb_server_app`` is an instance of
``notebook.notebookapp.NotebookWebApplication``.
"""
web_app = nb_server_app.web_app
host_pattern = '.*$'
route_pattern = url_path_join(web_app.settings['base_url'], '/wwtkdr/([^/]*)/(.*)')
# The registry of kernels and URL "keys"
registry = Registry()
# Register our handler that will relay requests for data files.
web_app.add_handlers(host_pattern, [
(route_pattern, DataRequestHandler, {'registry': registry}),
])
# In order for the registry to be notified of when a kernel has requested a
# URL prefix, we need to shim ourselves into the kernel startup framework
# and register a message listener.
app_km = nb_server_app.kernel_manager
orig_start_watching_activity = app_km.start_watching_activity
def shimmed_start_watching_activity(kernel_id):
orig_start_watching_activity(kernel_id)
km = app_km.get_kernel(kernel_id)
registry.watch_new_kernel(kernel_id, km)
app_km.start_watching_activity = shimmed_start_watching_activity