Skip to content

Commit ac4fdef

Browse files
committed
Mybinder example
1 parent ba6a312 commit ac4fdef

File tree

11 files changed

+267
-0
lines changed

11 files changed

+267
-0
lines changed
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
lib/
2+
built/
3+
node_modules/
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"esnext": true
3+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# Using jupyter-js-widgets in non-notebook, web context + mybinder backend
2+
3+
## Description
4+
5+
This directory is an example project that shows how to use `jupyter-js-widgets`
6+
and `ipywidgets` in a web context other than the notebook.
7+
8+
Similarly to the `web3` example, this example makes uses of a Python kernel.
9+
However, it makes use of the `mybinder` service to spawn a new transient Jupyter
10+
notebook server from which it then requests a Python kernel.
11+
12+
Besides, this example also displays read-only text area containing the code
13+
provided in the `widget_code.json`, which we used to generate the widget state.
14+
This directory is an example project that shows how you can embed the widgets in
15+
a context other than the notebook.
16+
17+
## Try it
18+
19+
1. Start with a development install of jupyter-js-widgets by running
20+
`npm install` in the `jupyter-js-widgets` subfolder of the repo root
21+
(see the [README.md](../../../README.md) in the repo root for more details).
22+
2. Cd into this directory and run `npm install`.
23+
3. Now open the `index.html` file.
24+
25+
## Details
26+
27+
If you plan to reproduce this in your own project, pay careful attention to the
28+
`package.json` file. The dependency to `jupyter-js-widgets`, which reads
29+
`"jupyter-js-widgets": "file:../../../ipywidgets"`, **should not** point to
30+
`"file:../../../ipywidgets"`.
31+
32+
Instead point it to the version you want to use on npm.
33+
34+
(but really, you should let npm do this for you by running
35+
36+
`npm install --save jupyter-js-widgets`.)
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
<html>
2+
<head>
3+
<script src="built/index.built.js"></script>
4+
<meta http-equiv="content-type" content="text/html; charset=UTF8">
5+
<link rel="stylesheet" type="text/css" href="./node_modules/font-awesome/css/font-awesome.css">
6+
<style>
7+
body {
8+
margin-left: auto;
9+
margin-right: auto;
10+
max-width: 900px;
11+
background-color: #eee;
12+
}
13+
14+
.jupyter-js-widgets-example {
15+
margin-top: 10px;
16+
margin-bottom: 10px;
17+
background-color: white;
18+
overflow: auto;
19+
box-shadow: 0px 0px 12px 1px rgba(87, 87, 87, 0.2);
20+
}
21+
22+
.widgetarea, .inputarea {
23+
margin: 5px;
24+
}
25+
26+
.CodeMirror {
27+
border: 1px solid #ccc;
28+
height: auto;
29+
background-color: #f7f7f7;
30+
border-radius: 2px;
31+
}
32+
33+
.CodeMirror-Scroll {
34+
height: auto;
35+
}
36+
</style>
37+
</head>
38+
<body>
39+
<div class="jupyter-js-widgets-example">
40+
<div class="inputarea"></div>
41+
<div class="widgetarea"></div>
42+
</div>
43+
</body>
44+
</html>
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
{
2+
"name": "jupyter-js-widgets-test",
3+
"version": "1.0.0",
4+
"description": "Project that tests the ability to npm install jupyter-js-widgets within an npm project.",
5+
"main": "index.js",
6+
"scripts": {
7+
"clean": "rimraf lib && rimraf built",
8+
"prepublish": "npm run build",
9+
"build": "npm run clean && tsc --project src && node scripts/copyfiles.js && webpack",
10+
"host": "http-server",
11+
"test": "npm run test:default",
12+
"test:default": "echo \"No test specified\""
13+
},
14+
"author": "IPython",
15+
"license": "BSD-3-Clause",
16+
"dependencies": {
17+
"@jupyterlab/services": "^0.24.0",
18+
"@types/codemirror": "0.0.33",
19+
"codemirror": "^5.9.0",
20+
"font-awesome": "^4.5.0",
21+
"http-server": "^0.8.5",
22+
"jupyter-js-widgets": "file:../..",
23+
"lodash.startswith": "^4.2.1",
24+
"browser-request": "^0.3.3"
25+
},
26+
"devDependencies": {
27+
"css-loader": "^0.23.1",
28+
"file-loader": "^0.8.5",
29+
"fs-extra": "^0.30.0",
30+
"json-loader": "^0.5.4",
31+
"postcss": "^5.2.5",
32+
"postcss-cssnext": "^2.8.0",
33+
"postcss-import": "^8.1.2",
34+
"postcss-loader": "^1.1.0",
35+
"rimraf": "^2.5.4",
36+
"style-loader": "^0.13.0",
37+
"typescript": "^2.0.3",
38+
"url-loader": "^0.5.7",
39+
"webpack": "^1.12.10"
40+
}
41+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
// Copyright (c) Jupyter Development Team.
2+
// Distributed under the terms of the Modified BSD License.
3+
4+
var fs = require('fs-extra');
5+
fs.copySync('src/', 'lib/', { filter: /\.css$/ });
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import * as CodeMirror from 'codemirror';
2+
import 'codemirror/lib/codemirror.css';
3+
import 'codemirror/mode/python/python';
4+
import * as request from 'browser-request';
5+
import * as startsWith from 'lodash.startswith';
6+
import { WidgetManager } from './manager';
7+
import { Kernel } from '@jupyterlab/services';
8+
9+
var apiServer = "http://beta.mybinder.org";
10+
var displayName = "jovyan/pythreejs";
11+
var templateName = displayName.replace('/tree', '').replace(/\//g, '-').toLowerCase();
12+
13+
request({
14+
url: apiServer + '/api/deploy/' + templateName,
15+
json: true
16+
}, function (err, res, json) {
17+
if (err) {
18+
console.log(err);
19+
}
20+
request({
21+
url: apiServer + '/api/apps/' + templateName + '/' + json['id'],
22+
json: true
23+
}, function (err, res, json) {
24+
var location = json['location'];
25+
var status = json['status'];
26+
if (location) {
27+
if (!startsWith(location, 'http://')) {
28+
location = 'http://' + location;
29+
}
30+
console.log('success');
31+
//window.location.href = location + deepLink;
32+
} else if (status === 'failed') {
33+
console.log('error');
34+
}
35+
});
36+
});
37+
38+
39+
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import * as widgets from 'jupyter-js-widgets';
2+
import 'phosphor/styles/base.css';
3+
import 'jupyter-js-widgets/css/widgets.css';
4+
import * as PWidget from 'phosphor/lib/ui/widget';
5+
6+
export
7+
class WidgetManager extends widgets.ManagerBase<HTMLElement> {
8+
constructor(kernel, el) {
9+
super();
10+
this.kernel = kernel;
11+
this.el = el;
12+
13+
// Create a comm manager shim
14+
this.commManager = new widgets.shims.services.CommManager(kernel);
15+
16+
// Register the comm target
17+
this.commManager.register_target(this.comm_target_name, this.handle_comm_open.bind(this));
18+
}
19+
20+
display_view(msg, view, options) {
21+
return Promise.resolve(view).then((view) => {
22+
PWidget.Widget.attach(view.pWidget, this.el);
23+
view.on('remove', function() {
24+
console.log('view removed', view);
25+
});
26+
return view;
27+
});
28+
}
29+
30+
_create_comm(targetName, id, metadata) {
31+
return this.commManager.new_comm(targetName, metadata, id);
32+
}
33+
34+
_get_comm_info() {
35+
return Promise.resolve({});
36+
}
37+
38+
kernel: any;
39+
el: HTMLElement;
40+
commManager: any;
41+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"compilerOptions": {
3+
"declaration": true,
4+
//"noImplicitAny": true,
5+
"lib": ["dom", "es5", "es2015.promise"],
6+
"types": ["requirejs"],
7+
"noEmitOnError": true,
8+
"module": "commonjs",
9+
"moduleResolution": "node",
10+
"target": "ES5",
11+
"outDir": "../lib"
12+
}
13+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
module.exports = {
2+
entry: './lib/index.js',
3+
output: {
4+
filename: 'index.built.js',
5+
path: './built/',
6+
publicPath: 'built/'
7+
},
8+
module: {
9+
loaders: [
10+
{ test: /\.css$/, loader: "style-loader!css-loader!postcss-loader" },
11+
{ test: /\.json$/, loader: "json-loader" },
12+
// jquery-ui loads some images
13+
{ test: /\.(jpg|png|gif)$/, loader: "file" },
14+
// required to load font-awesome
15+
{ test: /\.woff2(\?v=\d+\.\d+\.\d+)?$/, loader: "url?limit=10000&mimetype=application/font-woff" },
16+
{ test: /\.woff(\?v=\d+\.\d+\.\d+)?$/, loader: "url?limit=10000&mimetype=application/font-woff" },
17+
{ test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/, loader: "url?limit=10000&mimetype=application/octet-stream" },
18+
{ test: /\.eot(\?v=\d+\.\d+\.\d+)?$/, loader: "file" },
19+
{ test: /\.svg(\?v=\d+\.\d+\.\d+)?$/, loader: "url?limit=10000&mimetype=image/svg+xml" }
20+
]
21+
},
22+
postcss: function () {
23+
return [
24+
require('postcss-import'),
25+
require('postcss-cssnext')
26+
];
27+
}
28+
};

0 commit comments

Comments
 (0)