Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions jupyter-js-widgets/examples/web6/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
lib/
built/
node_modules/
3 changes: 3 additions & 0 deletions jupyter-js-widgets/examples/web6/.jshintrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"esnext": true
}
36 changes: 36 additions & 0 deletions jupyter-js-widgets/examples/web6/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Using jupyter-js-widgets in non-notebook, web context + mybinder backend

## Description

This directory is an example project that shows how to use `jupyter-js-widgets`
and `ipywidgets` in a web context other than the notebook.

Similarly to the `web3` example, this example makes uses of a Python kernel.
However, it makes use of the `mybinder` service to spawn a new transient Jupyter
notebook server from which it then requests a Python kernel.

Besides, this example also displays read-only text area containing the code
provided in the `widget_code.json`, which we used to generate the widget state.
This directory is an example project that shows how you can embed the widgets in
a context other than the notebook.

## Try it

1. Start with a development install of jupyter-js-widgets by running
`npm install` in the `jupyter-js-widgets` subfolder of the repo root
(see the [README.md](../../../README.md) in the repo root for more details).
2. Cd into this directory and run `npm install`.
3. Now open the `index.html` file.

## Details

If you plan to reproduce this in your own project, pay careful attention to the
`package.json` file. The dependency to `jupyter-js-widgets`, which reads
`"jupyter-js-widgets": "file:../../../ipywidgets"`, **should not** point to
`"file:../../../ipywidgets"`.

Instead point it to the version you want to use on npm.

(but really, you should let npm do this for you by running

`npm install --save jupyter-js-widgets`.)
44 changes: 44 additions & 0 deletions jupyter-js-widgets/examples/web6/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<html>
<head>
<script src="built/index.built.js"></script>
<meta http-equiv="content-type" content="text/html; charset=UTF8">
<link rel="stylesheet" type="text/css" href="./node_modules/font-awesome/css/font-awesome.css">
<style>
body {
margin-left: auto;
margin-right: auto;
max-width: 900px;
background-color: #eee;
}

.jupyter-js-widgets-example {
margin-top: 10px;
margin-bottom: 10px;
background-color: white;
overflow: auto;
box-shadow: 0px 0px 12px 1px rgba(87, 87, 87, 0.2);
}

.widgetarea, .inputarea {
margin: 5px;
}

.CodeMirror {
border: 1px solid #ccc;
height: auto;
background-color: #f7f7f7;
border-radius: 2px;
}

.CodeMirror-Scroll {
height: auto;
}
</style>
</head>
<body>
<div class="jupyter-js-widgets-example">
<div class="inputarea"></div>
<div class="widgetarea"></div>
</div>
</body>
</html>
41 changes: 41 additions & 0 deletions jupyter-js-widgets/examples/web6/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
{
"name": "jupyter-js-widgets-test",
"version": "1.0.0",
"description": "Project that tests the ability to npm install jupyter-js-widgets within an npm project.",
"main": "index.js",
"scripts": {
"clean": "rimraf lib && rimraf built",
"prepublish": "npm run build",
"build": "npm run clean && tsc --project src && node scripts/copyfiles.js && webpack",
"host": "http-server",
"test": "npm run test:default",
"test:default": "echo \"No test specified\""
},
"author": "IPython",
"license": "BSD-3-Clause",
"dependencies": {
"@jupyterlab/services": "^0.24.0",
"@types/codemirror": "0.0.33",
"codemirror": "^5.9.0",
"font-awesome": "^4.5.0",
"http-server": "^0.8.5",
"jupyter-js-widgets": "file:../..",
"lodash.startswith": "^4.2.1",
"browser-request": "^0.3.3"
},
"devDependencies": {
"css-loader": "^0.23.1",
"file-loader": "^0.8.5",
"fs-extra": "^0.30.0",
"json-loader": "^0.5.4",
"postcss": "^5.2.5",
"postcss-cssnext": "^2.8.0",
"postcss-import": "^8.1.2",
"postcss-loader": "^1.1.0",
"rimraf": "^2.5.4",
"style-loader": "^0.13.0",
"typescript": "^2.0.3",
"url-loader": "^0.5.7",
"webpack": "^1.12.10"
}
}
5 changes: 5 additions & 0 deletions jupyter-js-widgets/examples/web6/scripts/copyfiles.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// Copyright (c) Jupyter Development Team.
// Distributed under the terms of the Modified BSD License.

var fs = require('fs-extra');
fs.copySync('src/', 'lib/', { filter: /\.css$/ });
39 changes: 39 additions & 0 deletions jupyter-js-widgets/examples/web6/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import * as CodeMirror from 'codemirror';
import 'codemirror/lib/codemirror.css';
import 'codemirror/mode/python/python';
import * as request from 'browser-request';
import * as startsWith from 'lodash.startswith';
import { WidgetManager } from './manager';
import { Kernel } from '@jupyterlab/services';

var apiServer = "http://beta.mybinder.org";
var displayName = "jovyan/pythreejs";
var templateName = displayName.replace('/tree', '').replace(/\//g, '-').toLowerCase();

request({
url: apiServer + '/api/deploy/' + templateName,
json: true
}, function (err, res, json) {
if (err) {
console.log(err);
}
request({
url: apiServer + '/api/apps/' + templateName + '/' + json['id'],
json: true
}, function (err, res, json) {
var location = json['location'];
var status = json['status'];
if (location) {
if (!startsWith(location, 'http://')) {
location = 'http://' + location;
}
console.log('success');
//window.location.href = location + deepLink;
} else if (status === 'failed') {
console.log('error');
}
});
});



41 changes: 41 additions & 0 deletions jupyter-js-widgets/examples/web6/src/manager.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import * as widgets from 'jupyter-js-widgets';
import 'phosphor/styles/base.css';
import 'jupyter-js-widgets/css/widgets.css';
import * as PWidget from 'phosphor/lib/ui/widget';

export
class WidgetManager extends widgets.ManagerBase<HTMLElement> {
constructor(kernel, el) {
super();
this.kernel = kernel;
this.el = el;

// Create a comm manager shim
this.commManager = new widgets.shims.services.CommManager(kernel);

// Register the comm target
this.commManager.register_target(this.comm_target_name, this.handle_comm_open.bind(this));
}

display_view(msg, view, options) {
return Promise.resolve(view).then((view) => {
PWidget.Widget.attach(view.pWidget, this.el);
view.on('remove', function() {
console.log('view removed', view);
});
return view;
});
}

_create_comm(targetName, id, metadata) {
return this.commManager.new_comm(targetName, metadata, id);
}

_get_comm_info() {
return Promise.resolve({});
}

kernel: any;
el: HTMLElement;
commManager: any;
}
13 changes: 13 additions & 0 deletions jupyter-js-widgets/examples/web6/src/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"compilerOptions": {
"declaration": true,
//"noImplicitAny": true,
"lib": ["dom", "es5", "es2015.promise"],
"types": ["requirejs"],
"noEmitOnError": true,
"module": "commonjs",
"moduleResolution": "node",
"target": "ES5",
"outDir": "../lib"
}
}
28 changes: 28 additions & 0 deletions jupyter-js-widgets/examples/web6/webpack.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
module.exports = {
entry: './lib/index.js',
output: {
filename: 'index.built.js',
path: './built/',
publicPath: 'built/'
},
module: {
loaders: [
{ test: /\.css$/, loader: "style-loader!css-loader!postcss-loader" },
{ test: /\.json$/, loader: "json-loader" },
// jquery-ui loads some images
{ test: /\.(jpg|png|gif)$/, loader: "file" },
// required to load font-awesome
{ test: /\.woff2(\?v=\d+\.\d+\.\d+)?$/, loader: "url?limit=10000&mimetype=application/font-woff" },
{ test: /\.woff(\?v=\d+\.\d+\.\d+)?$/, loader: "url?limit=10000&mimetype=application/font-woff" },
{ test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/, loader: "url?limit=10000&mimetype=application/octet-stream" },
{ test: /\.eot(\?v=\d+\.\d+\.\d+)?$/, loader: "file" },
{ test: /\.svg(\?v=\d+\.\d+\.\d+)?$/, loader: "url?limit=10000&mimetype=image/svg+xml" }
]
},
postcss: function () {
return [
require('postcss-import'),
require('postcss-cssnext')
];
}
};
14 changes: 14 additions & 0 deletions jupyter-js-widgets/examples/web6/widget_code.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
[
"from ipywidgets import IntSlider, Text, VBox",
"from IPython.display import display",
"",
"s = IntSlider(max=200, value=100)",
"t = Text()",
"",
"def update_text(change=None):",
" t.value = str(s.value ** 2)",
"",
"s.observe(update_text, names='value')",
"update_text()",
"display(VBox([s, t]))"
]