Skip to content
Snippets Groups Projects
Commit e6772aa0 authored by alice grosch's avatar alice grosch
Browse files

Add Dockerfile

parent 4a6b06f9
No related branches found
No related tags found
No related merge requests found
Showing
with 947 additions and 0 deletions
// Entry point for the unpkg bundle containing custom model definitions.
//
// It differs from the notebook bundle in that it does not need to define a
// dynamic baseURL for the static assets and may load some css that would
// already be loaded by the notebook otherwise.
// Export widget models and views, and the npm package version number.
module.exports = require('./remoterenderer.js');
module.exports['version'] = require('../package.json').version;
// This file contains the javascript that is run when the notebook is loaded.
// It contains some requirejs configuration and the `load_ipython_extension`
// which is required for any notebook extension.
//
// Some static assets may be required by the custom widget javascript. The base
// url for the notebook is not known at build time and is therefore computed
// dynamically.
__webpack_public_path__ = document.querySelector('body').getAttribute('data-base-url') + 'nbextensions/pvlink';
// Configure requirejs
if (window.require) {
window.require.config({
map: {
"*" : {
"pvlink": "nbextensions/pvlink/index",
}
}
});
}
// Export the required load_ipython_extension
module.exports = {
load_ipython_extension: function() {}
};
// Export widget models and views, and the npm package version number.
module.exports = require('./remoterenderer.js');
module.exports['version'] = require('../package.json').version;
var plugin = require('./index');
var base = require('@jupyter-widgets/base');
module.exports = {
id: 'pvlink',
requires: [base.IJupyterWidgetRegistry],
activate: function(app, widgets) {
widgets.registerWidget({
name: 'pvlink',
version: plugin.version,
exports: plugin
});
},
autoStart: true
};
var widgets = require('@jupyter-widgets/base');
var _ = require('lodash');
import ParaViewWebClient from 'paraviewweb/src/IO/WebSocket/ParaViewWebClient';
import RemoteRenderer from 'paraviewweb/src/NativeUI/Canvas/RemoteRenderer';
import SizeHelper from "paraviewweb/src/Common/Misc/SizeHelper";
import SmartConnect from 'wslink/src/SmartConnect';
export var RemoteRendererModel = widgets.DOMWidgetModel.extend({
defaults: _.extend(widgets.DOMWidgetModel.prototype.defaults(), {
_model_name: 'RemoteRendererModel',
_view_name: 'RemoteRendererView',
_model_module: 'pvlink',
_view_module: 'pvlink',
_model_module_version: '0.1.0',
_view_module_version: '0.1.0',
})
});
export var RemoteRendererView = widgets.DOMWidgetView.extend({
render: function () {
var that = this;
// div to hold the canvas of the RemoteRenderer.
var render_div = document.createElement('div');
render_div.style.height = '100%';
render_div.style.width = '100%';
this.el.appendChild(render_div);
/* Get configuration for SmartConnect.
* SmartConnect will establish a direct
* WebSocket connection using Autobahn.
*/
var config = {
sessionURL: this.model.get('sessionURL'),
secret: this.model.get('authKey')
};
var smartConnect = SmartConnect.newInstance({ config: config });
smartConnect.onConnectionReady(function (connection) {
// Create the RemoteRenderer
var pvwClient = ParaViewWebClient.createClient(connection, [
'MouseHandler',
'ViewPort',
'ViewPortImageDelivery']
);
var renderer = new RemoteRenderer(pvwClient);
renderer.setContainer(render_div);
renderer.setView(that.model.get('viewID'));
renderer.onImageReady(function () {
// Resize when the renderer is placed within a widget.
if (that.el.style.width != '100%') {
that.el.style.width = '100%';
renderer.resize();
}
console.log("We are good.");
});
// Handle size changes when the entire window is resized.
SizeHelper.onSizeChange(function () {
renderer.resize();
});
SizeHelper.startListening();
// Explicit render called from python side.
that.model.on('change:_update', function () {
renderer.render(true);
}, that);
});
smartConnect.connect();
},
});
{
"name": "pvlink",
"version": "0.1.0",
"description": "Displays the ParaviewWeb RemoteRenderer in a Jupyter Notebook",
"author": "Alice Grosch",
"main": "lib/index.js",
"repository": {
"type": "git",
"url": "https://github.com//pvlink.git"
},
"keywords": [
"jupyter",
"widgets",
"ipython",
"ipywidgets",
"jupyterlab-extension"
],
"files": [
"lib/**/*.js",
"dist/*.js"
],
"scripts": {
"clean": "rimraf dist/",
"prepublish": "webpack",
"build": "webpack",
"watch": "webpack --watch --mode=development",
"test": "echo \"Error: no test specified\" && exit 1"
},
"devDependencies": {
"webpack": "^3.5.5",
"rimraf": "^2.6.1",
"hammerjs": "^2.0.8",
"monologue.js": "^0.3.5"
},
"dependencies": {
"@jupyter-widgets/base": "^1.1 || ^2",
"lodash": "^4.17.4",
"paraviewweb": "^3.2.12",
"wslink": "^0.1.12"
},
"jupyterlab": {
"extension": "lib/labplugin"
}
}
var path = require('path');
var version = require('./package.json').version;
// Custom webpack rules are generally the same for all webpack bundles, hence
// stored in a separate local variable.
var rules = [
{ test: /\.css$/, use: ['style-loader', 'css-loader']}
]
module.exports = [
{// Notebook extension
//
// This bundle only contains the part of the JavaScript that is run on
// load of the notebook. This section generally only performs
// some configuration for requirejs, and provides the legacy
// "load_ipython_extension" function which is required for any notebook
// extension.
//
entry: './lib/extension.js',
output: {
filename: 'extension.js',
path: path.resolve(__dirname, '..', 'pvlink', 'static'),
libraryTarget: 'amd'
}
},
{// Bundle for the notebook containing the custom widget views and models
//
// This bundle contains the implementation for the custom widget views and
// custom widget.
// It must be an amd module
//
entry: './lib/index.js',
output: {
filename: 'index.js',
path: path.resolve(__dirname, '..', 'pvlink', 'static'),
libraryTarget: 'amd'
},
devtool: 'source-map',
module: {
rules: rules
},
externals: ['@jupyter-widgets/base']
},
{// Embeddable pvlink bundle
//
// This bundle is generally almost identical to the notebook bundle
// containing the custom widget views and models.
//
// The only difference is in the configuration of the webpack public path
// for the static assets.
//
// It will be automatically distributed by unpkg to work with the static
// widget embedder.
//
// The target bundle is always `dist/index.js`, which is the path required
// by the custom widget embedder.
//
entry: './lib/embed.js',
output: {
filename: 'index.js',
path: path.resolve(__dirname, 'dist'),
libraryTarget: 'amd',
publicPath: 'https://unpkg.com/pvlink@' + version + '/dist/'
},
devtool: 'source-map',
module: {
rules: rules
},
externals: ['@jupyter-widgets/base']
}
];
# add paraview modules
import sys
sys.path.append('/home/grosch/Devel/install/ParaView-v5.6.0/build/lib/python3.6/site-packages/')
# import to process args
import os
# import paraview modules.
from paraview.web import pv_wslink
from paraview.web import protocols as pv_protocols
from paraview import simple
from wslink import server
try:
import argparse
except ImportError:
# since Python 2.6 and earlier don't have argparse, we simply provide
# the source for the same as _argparse and we use it instead.
from vtk.util import _argparse as argparse
# =============================================================================
# Create custom PVServerProtocol class to handle clients requests
# =============================================================================
class _DemoServer(pv_wslink.PVServerProtocol):
authKey = "wslink-secret"
def initialize(self):
# Bring used components
self.registerVtkWebProtocol(pv_protocols.ParaViewWebMouseHandler())
self.registerVtkWebProtocol(pv_protocols.ParaViewWebViewPort())
self.registerVtkWebProtocol(pv_protocols.ParaViewWebViewPortImageDelivery())
self.updateSecret(_DemoServer.authKey)
# Disable interactor-based render calls
simple.GetRenderView().EnableRenderOnInteraction = 0
simple.GetRenderView().Background = [0,0,0]
cone = simple.Cone()
simple.Show(cone)
simple.Render()
# Update interaction mode
pxm = simple.servermanager.ProxyManager()
interactionProxy = pxm.GetProxy('settings', 'RenderViewInteractionSettings')
interactionProxy.Camera3DManipulators = ['Rotate', 'Pan', 'Zoom', 'Pan', 'Roll', 'Pan', 'Zoom', 'Rotate', 'Zoom']
# =============================================================================
# Main: Parse args and start server
# =============================================================================
if __name__ == "__main__":
# Create argument parser
parser = argparse.ArgumentParser(description="ParaViewWeb Demo")
# Add default arguments
server.add_arguments(parser)
# Extract arguments
args = parser.parse_args()
# Start server
server.start_webserver(options=args, protocol=_DemoServer)
\ No newline at end of file
{
"load_extensions": {
"pvlink/extension": true
}
}
from ._version import version_info, __version__
from .remoterenderer import *
def _jupyter_nbextension_paths():
return [{
'section': 'notebook',
'src': 'static',
'dest': 'pvlink',
'require': 'pvlink/extension'
}]
version_info = (0, 1, 0, 'alpha', 0)
_specifier_ = {'alpha': 'a', 'beta': 'b', 'candidate': 'rc', 'final': ''}
__version__ = '%s.%s.%s%s'%(version_info[0], version_info[1], version_info[2],
'' if version_info[3]=='final' else _specifier_[version_info[3]]+str(version_info[4]))
import ipywidgets as widgets
from traitlets import Unicode, Int
@widgets.register
class RemoteRenderer(widgets.DOMWidget):
"""ParaviewWeb RemoteRenderer for the Jupyter Notebook."""
_view_name = Unicode('RemoteRendererView').tag(sync=True)
_model_name = Unicode('RemoteRendererModel').tag(sync=True)
_view_module = Unicode('pvlink').tag(sync=True)
_model_module = Unicode('pvlink').tag(sync=True)
_view_module_version = Unicode('^0.1.0').tag(sync=True)
_model_module_version = Unicode('^0.1.0').tag(sync=True)
# URL to establish a websocket connection to.
sessionURL = Unicode('ws://localhost:8080/ws').tag(sync=True)
# Authentication key for clients to connect to the WebSocket.
authKey = Unicode('wslink-secret').tag(sync=True)
# ViewID of the view to connect to (only relevant
# if multiple views exist on the server side).
viewID = Unicode("-1").tag(sync=True)
# Placeholder to force rendering updates on change.
_update = Int(0).tag(sync=True)
def __init__(self, sessionURL='ws://localhost:8080/ws', authKey='wslink-secret', viewID='-1', *args, **kwargs):
super(RemoteRenderer, self).__init__(*args, **kwargs)
self.sessionURL = sessionURL
self.authKey = authKey
self.viewID = viewID
def update_render(self):
"""Explicit call for the renderer on the javascript side to render."""
self._update += 1
\ No newline at end of file
import ipywidgets as widgets
from traitlets import Unicode, Int
@widgets.register
class RemoteRenderer(widgets.DOMWidget):
"""ParaviewWeb RemoteRenderer for the Jupyter Notebook."""
_view_name = Unicode('RemoteRendererView').tag(sync=True)
_model_name = Unicode('RemoteRendererModel').tag(sync=True)
_view_module = Unicode('pvlink').tag(sync=True)
_model_module = Unicode('pvlink').tag(sync=True)
_view_module_version = Unicode('^0.1.0').tag(sync=True)
_model_module_version = Unicode('^0.1.0').tag(sync=True)
# URL to establish a websocket connection to.
sessionURL = Unicode('ws://localhost:8080/ws').tag(sync=True)
# Authentication key for clients to connect to the WebSocket.
authKey = Unicode('wslink-secret').tag(sync=True)
# ViewID of the view to connect to (only relevant
# if multiple views exist on the server side).
viewID = Unicode("-1").tag(sync=True)
# Placeholder to force rendering updates on change.
_update = Int(0).tag(sync=True)
def __init__(self, sessionURL='ws://localhost:8080/ws', authKey='wslink-secret', viewID='-1', *args, **kwargs):
super(RemoteRenderer, self).__init__(*args, **kwargs)
self.sessionURL = sessionURL
self.authKey = authKey
self.viewID = viewID
def update_render(self):
"""Explicit call for the renderer on the javascript side to render."""
self._update += 1
\ No newline at end of file
%% Cell type:code id: tags:
``` python
from pvlink import RemoteRenderer
```
%% Cell type:code id: tags:
``` python
renderer = RemoteRenderer()
# renderer
```
%% Output
%% Cell type:code id: tags:
``` python
from ipywidgets import Box
```
%% Cell type:code id: tags:
``` python
out = Box(children=[renderer])
out.layout.height = '500px'
out
```
%% Output
%% Cell type:code id: tags:
``` python
```
[bdist_wheel]
universal=1
from __future__ import print_function
from setuptools import setup, find_packages, Command
from setuptools.command.sdist import sdist
from setuptools.command.build_py import build_py
from setuptools.command.egg_info import egg_info
from subprocess import check_call
import os
import sys
import platform
here = os.path.dirname(os.path.abspath(__file__))
node_root = os.path.join(here, 'js')
is_repo = os.path.exists(os.path.join(here, '.git'))
npm_path = os.pathsep.join([
os.path.join(node_root, 'node_modules', '.bin'),
os.environ.get('PATH', os.defpath),
])
from distutils import log
log.set_verbosity(log.DEBUG)
log.info('setup.py entered')
log.info('$PATH=%s' % os.environ['PATH'])
LONG_DESCRIPTION = 'Displays the ParaviewWeb RemoteRenderer in a Jupyter Notebook'
def js_prerelease(command, strict=False):
"""decorator for building minified js/css prior to another command"""
class DecoratedCommand(command):
def run(self):
jsdeps = self.distribution.get_command_obj('jsdeps')
if not is_repo and all(os.path.exists(t) for t in jsdeps.targets):
# sdist, nothing to do
command.run(self)
return
try:
self.distribution.run_command('jsdeps')
except Exception as e:
missing = [t for t in jsdeps.targets if not os.path.exists(t)]
if strict or missing:
log.warn('rebuilding js and css failed')
if missing:
log.error('missing files: %s' % missing)
raise e
else:
log.warn('rebuilding js and css failed (not a problem)')
log.warn(str(e))
command.run(self)
update_package_data(self.distribution)
return DecoratedCommand
def update_package_data(distribution):
"""update package_data to catch changes during setup"""
build_py = distribution.get_command_obj('build_py')
# distribution.package_data = find_package_data()
# re-init build_py options which load package_data
build_py.finalize_options()
class NPM(Command):
description = 'install package.json dependencies using npm'
user_options = []
node_modules = os.path.join(node_root, 'node_modules')
targets = [
os.path.join(here, 'pvlink', 'static', 'extension.js'),
os.path.join(here, 'pvlink', 'static', 'index.js')
]
def initialize_options(self):
pass
def finalize_options(self):
pass
def get_npm_name(self):
npmName = 'npm';
if platform.system() == 'Windows':
npmName = 'npm.cmd';
return npmName;
def has_npm(self):
npmName = self.get_npm_name();
try:
check_call([npmName, '--version'])
return True
except:
return False
def should_run_npm_install(self):
package_json = os.path.join(node_root, 'package.json')
node_modules_exists = os.path.exists(self.node_modules)
return self.has_npm()
def run(self):
has_npm = self.has_npm()
if not has_npm:
log.error("`npm` unavailable. If you're running this command using sudo, make sure `npm` is available to sudo")
env = os.environ.copy()
env['PATH'] = npm_path
if self.should_run_npm_install():
log.info("Installing build dependencies with npm. This may take a while...")
npmName = self.get_npm_name();
check_call([npmName, 'install'], cwd=node_root, stdout=sys.stdout, stderr=sys.stderr)
os.utime(self.node_modules, None)
for t in self.targets:
if not os.path.exists(t):
msg = 'Missing file: %s' % t
if not has_npm:
msg += '\nnpm is required to build a development version of a widget extension'
raise ValueError(msg)
# update package data in case this created new files
update_package_data(self.distribution)
version_ns = {}
with open(os.path.join(here, 'pvlink', '_version.py')) as f:
exec(f.read(), {}, version_ns)
setup_args = {
'name': 'pvlink',
'version': version_ns['__version__'],
'description': 'Displays the ParaviewWeb RemoteRenderer in a Jupyter Notebook',
'long_description': LONG_DESCRIPTION,
'include_package_data': True,
'data_files': [
('share/jupyter/nbextensions/pvlink', [
'pvlink/static/extension.js',
'pvlink/static/index.js',
'pvlink/static/index.js.map',
],),
('etc/jupyter/nbconfig/notebook.d' ,['pvlink.json'])
],
'install_requires': [
'ipywidgets>=7.0.0',
'wslink>=0.1.11',
'twisted>=19.2.1',
],
'packages': find_packages(),
'zip_safe': False,
'cmdclass': {
'build_py': js_prerelease(build_py),
'egg_info': js_prerelease(egg_info),
'sdist': js_prerelease(sdist, strict=True),
'jsdeps': NPM,
},
'author': 'Alice Grosch',
'author_email': 'a.grosch@fz-juelich.de',
'url': 'https://github.com//pvlink',
'keywords': [
'ipython',
'jupyter',
'widgets',
],
'classifiers': [
'Development Status :: 4 - Beta',
'Framework :: IPython',
'Intended Audience :: Developers',
'Intended Audience :: Science/Research',
'Topic :: Multimedia :: Graphics',
'Programming Language :: Python :: 2',
'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.3',
'Programming Language :: Python :: 3.4',
'Programming Language :: Python :: 3.5',
'Programming Language :: Python :: 3.6',
'Programming Language :: Python :: 3.7',
],
}
setup(**setup_args)
[bdist_wheel]
universal=1
from __future__ import print_function
from setuptools import setup, find_packages, Command
from setuptools.command.sdist import sdist
from setuptools.command.build_py import build_py
from setuptools.command.egg_info import egg_info
from subprocess import check_call
import os
import sys
import platform
here = os.path.dirname(os.path.abspath(__file__))
node_root = os.path.join(here, 'js')
is_repo = os.path.exists(os.path.join(here, '.git'))
npm_path = os.pathsep.join([
os.path.join(node_root, 'node_modules', '.bin'),
os.environ.get('PATH', os.defpath),
])
from distutils import log
log.set_verbosity(log.DEBUG)
log.info('setup.py entered')
log.info('$PATH=%s' % os.environ['PATH'])
LONG_DESCRIPTION = 'Displays the ParaviewWeb RemoteRenderer in a Jupyter Notebook'
def js_prerelease(command, strict=False):
"""decorator for building minified js/css prior to another command"""
class DecoratedCommand(command):
def run(self):
jsdeps = self.distribution.get_command_obj('jsdeps')
if not is_repo and all(os.path.exists(t) for t in jsdeps.targets):
# sdist, nothing to do
command.run(self)
return
try:
self.distribution.run_command('jsdeps')
except Exception as e:
missing = [t for t in jsdeps.targets if not os.path.exists(t)]
if strict or missing:
log.warn('rebuilding js and css failed')
if missing:
log.error('missing files: %s' % missing)
raise e
else:
log.warn('rebuilding js and css failed (not a problem)')
log.warn(str(e))
command.run(self)
update_package_data(self.distribution)
return DecoratedCommand
def update_package_data(distribution):
"""update package_data to catch changes during setup"""
build_py = distribution.get_command_obj('build_py')
# distribution.package_data = find_package_data()
# re-init build_py options which load package_data
build_py.finalize_options()
class NPM(Command):
description = 'install package.json dependencies using npm'
user_options = []
node_modules = os.path.join(node_root, 'node_modules')
targets = [
os.path.join(here, 'pvlink', 'static', 'extension.js'),
os.path.join(here, 'pvlink', 'static', 'index.js')
]
def initialize_options(self):
pass
def finalize_options(self):
pass
def get_npm_name(self):
npmName = 'npm';
if platform.system() == 'Windows':
npmName = 'npm.cmd';
return npmName;
def has_npm(self):
npmName = self.get_npm_name();
try:
check_call([npmName, '--version'])
return True
except:
return False
def should_run_npm_install(self):
package_json = os.path.join(node_root, 'package.json')
node_modules_exists = os.path.exists(self.node_modules)
return self.has_npm()
def run(self):
has_npm = self.has_npm()
if not has_npm:
log.error("`npm` unavailable. If you're running this command using sudo, make sure `npm` is available to sudo")
env = os.environ.copy()
env['PATH'] = npm_path
if self.should_run_npm_install():
log.info("Installing build dependencies with npm. This may take a while...")
npmName = self.get_npm_name();
check_call([npmName, 'install'], cwd=node_root, stdout=sys.stdout, stderr=sys.stderr)
os.utime(self.node_modules, None)
for t in self.targets:
if not os.path.exists(t):
msg = 'Missing file: %s' % t
if not has_npm:
msg += '\nnpm is required to build a development version of a widget extension'
raise ValueError(msg)
# update package data in case this created new files
update_package_data(self.distribution)
version_ns = {}
with open(os.path.join(here, 'pvlink', '_version.py')) as f:
exec(f.read(), {}, version_ns)
setup_args = {
'name': 'pvlink',
'version': version_ns['__version__'],
'description': 'Displays the ParaviewWeb RemoteRenderer in a Jupyter Notebook',
'long_description': LONG_DESCRIPTION,
'include_package_data': True,
'data_files': [
('share/jupyter/nbextensions/pvlink', [
'pvlink/static/extension.js',
'pvlink/static/index.js',
'pvlink/static/index.js.map',
],),
('etc/jupyter/nbconfig/notebook.d' ,['pvlink.json'])
],
'install_requires': [
'ipywidgets>=7.0.0',
'wslink>=0.1.11',
'twisted>=19.2.1',
],
'packages': find_packages(),
'zip_safe': False,
'cmdclass': {
'build_py': js_prerelease(build_py),
'egg_info': js_prerelease(egg_info),
'sdist': js_prerelease(sdist, strict=True),
'jsdeps': NPM,
},
'author': 'Alice Grosch',
'author_email': 'a.grosch@fz-juelich.de',
'url': 'https://github.com//pvlink',
'keywords': [
'ipython',
'jupyter',
'widgets',
],
'classifiers': [
'Development Status :: 4 - Beta',
'Framework :: IPython',
'Intended Audience :: Developers',
'Intended Audience :: Science/Research',
'Topic :: Multimedia :: Graphics',
'Programming Language :: Python :: 2',
'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.3',
'Programming Language :: Python :: 3.4',
'Programming Language :: Python :: 3.5',
'Programming Language :: Python :: 3.6',
'Programming Language :: Python :: 3.7',
],
}
setup(**setup_args)
%% Cell type:code id: tags:
``` python
from pvlink import RemoteRenderer
```
%% Cell type:code id: tags:
``` python
renderer = RemoteRenderer()
# renderer
```
%% Cell type:code id: tags:
``` python
from ipywidgets import Box
```
%% Cell type:code id: tags:
``` python
out = Box(children=[renderer])
out.layout.height = '500px'
out
```
%% Output
%% Cell type:code id: tags:
``` python
```
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment