Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merge JupyterDash with Dash #2530

Merged
merged 19 commits into from
Jun 21, 2023
Merged
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
2 changes: 1 addition & 1 deletion .pylintrc
Original file line number Diff line number Diff line change
Expand Up @@ -412,7 +412,7 @@ max-attributes=20
max-bool-expr=5

# Maximum number of branch for function / method body
max-branches=12
max-branches=15

# Maximum number of locals for function / method body
max-locals=15
Expand Down
2 changes: 1 addition & 1 deletion .pylintrc39
Original file line number Diff line number Diff line change
Expand Up @@ -513,7 +513,7 @@ max-attributes=20
max-bool-expr=5

# Maximum number of branch for function / method body.
max-branches=12
max-branches=15

# Maximum number of locals for function / method body.
max-locals=15
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,4 @@ const MemoTypeScriptComponent = (props: TypescriptComponentProps) => (
<div id={props.id}>{props.required_string}</div>
);

export default React.memo(MemoTypeScriptComponent);
export default React.memo(MemoTypeScriptComponent, () => true);
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,4 @@ StandardComponent.propTypes = {
children: PropTypes.node,
}

export default StandardComponent
export default React.memo(StandardComponent, (prevProps,nextProps) => true)
3 changes: 3 additions & 0 deletions @plotly/dash-jupyterlab/.prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"singleQuote": true
}
7 changes: 7 additions & 0 deletions @plotly/dash-jupyterlab/lib/index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { JupyterFrontEndPlugin } from '@jupyterlab/application';
import '../style/index.css';
/**
* Initialization data for the jupyterlab-dash extension.
*/
declare const extension: JupyterFrontEndPlugin<void>;
export default extension;
115 changes: 115 additions & 0 deletions @plotly/dash-jupyterlab/lib/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const application_1 = require("@jupyterlab/application");
const coreutils_1 = require("@jupyterlab/coreutils");
const notebook_1 = require("@jupyterlab/notebook");
const console_1 = require("@jupyterlab/console");
const widgets_1 = require("@lumino/widgets");
require("../style/index.css");
class DashIFrameWidget extends widgets_1.Widget {
/**
* Construct a new DashIFrameWidget.
*/
constructor(port, url) {
super();
this.id = port;
this.title.label = `Dash (port: ${port})`;
this.title.closable = true;
this.addClass('jp-dashWidget');
// Add jp-IFrame class to keep drag events from being lost to the iframe
// See https://github.com/phosphorjs/phosphor/issues/305
// See https://github.com/jupyterlab/jupyterlab/blob/master/packages/apputils/style/iframe.css#L17-L35
this.addClass('jp-IFrame');
const serviceUrl = url;
const iframeElement = document.createElement('iframe');
iframeElement.setAttribute('baseURI', serviceUrl);
this.iframe = iframeElement;
this.iframe.src = serviceUrl;
this.iframe.id = 'iframe-' + this.id;
this.node.appendChild(this.iframe);
}
/**
* Handle update requests for the widget.
*/
onUpdateRequest(msg) {
this.iframe.src += '';
}
}
function activate(app, restorer, notebooks, consoles) {
// Declare a widget variable
let widgets = new Map();
// Watch notebook creation
notebooks.widgetAdded.connect((sender, nbPanel) => {
// const session = nbPanel.session;
const sessionContext = nbPanel.sessionContext;
sessionContext.ready.then(() => {
const session = sessionContext.session;
let kernel = session.kernel;
registerCommTarget(kernel, widgets, app);
});
});
// Watch console creation
consoles.widgetAdded.connect((sender, consolePanel) => {
const sessionContext = consolePanel.sessionContext;
sessionContext.ready.then(() => {
const session = sessionContext.session;
let kernel = session.kernel;
registerCommTarget(kernel, widgets, app);
});
});
}
function registerCommTarget(kernel, widgets, app) {
kernel.registerCommTarget('dash', (comm, msg) => {
comm.onMsg = (msg) => {
let msgData = msg.content.data;
if (msgData.type === 'show') {
let widget;
if (!widgets.has(msgData.port)) {
// Create a new widget
widget = new DashIFrameWidget(msgData.port, msgData.url);
widget.update();
widgets.set(msgData.port, widget);
// Add instance tracker stuff
}
else {
widget = widgets.get(msgData.port);
}
if (!widget.isAttached) {
// Attach the widget to the main work area
// if it's not there
app.shell.add(widget, 'main');
widget.update();
}
else {
// Refresh the widget
widget.update();
}
// Activate the widget
app.shell.activateById(widget.id);
}
else if (msgData.type === 'base_url_request') {
// Build server url and base subpath.
const baseUrl = coreutils_1.PageConfig.getBaseUrl();
const baseSubpath = coreutils_1.PageConfig.getOption('baseUrl');
const n = baseUrl.lastIndexOf(baseSubpath);
const serverUrl = baseUrl.slice(0, n);
comm.send({
type: 'base_url_response',
server_url: serverUrl,
base_subpath: baseSubpath,
frontend: "jupyterlab",
});
}
};
});
}
/**
* Initialization data for the jupyterlab-dash extension.
*/
const extension = {
id: 'jupyterlab_dash',
autoStart: true,
requires: [application_1.ILayoutRestorer, notebook_1.INotebookTracker, console_1.IConsoleTracker],
activate: activate
};
exports.default = extension;
48 changes: 48 additions & 0 deletions @plotly/dash-jupyterlab/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
{
"name": "@plotly/dash-jupyterlab",
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is currently published to npm as jupyterlab-dash - is that published version used for anything? Is there a reason to change its name and scoping here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It uses the tar bundle included in the Python package, that needs to be built the first time you open jupyterlab. Not sure if the npm package is used for anything, the jupyterlab docs says it can be directly to jupyterlab with npm but I am not sure the user really want to do that. https://jupyterlab.readthedocs.io/en/latest/extension/extension_tutorial.html#publishing-your-extension

I changed the name to avoid conflict if jupyter-dash is installed.

"version": "0.4.3",
"description": "A JupyterLab extension for rendering Plotly Dash apps",
"keywords": [
"jupyter",
"jupyterlab",
"jupyterlab-extension"
],
"homepage": "https://github.com/plotly/dash",
"bugs": {
"url": "https://github.com/plotly/dash/issues"
},
"license": "MIT",
"author": "Plotly",
"files": [
"lib/**/*.{d.ts,eot,gif,html,jpg,js,js.map,json,png,svg,woff2,ttf}",
"style/**/*.{css,eot,gif,html,jpg,json,png,svg,woff2,ttf}"
],
"main": "lib/index.js",
"types": "lib/index.d.ts",
"repository": {
"type": "git",
"url": "git+https://github.com/plotly/dash.git"
},
"scripts": {
"build": "tsc",
"build:pack": "jlpm run prepare && jlpm pack --filename ../../dash/labextension/dist/dash-jupyterlab.tgz && jlpm run build:copy",
"build:copy": "cp package.json ../../dash/labextension/dist/package.json",
"clean": "rimraf lib",
"prepare": "mkdir -p ../../dash/labextension/dist && jlpm run clean && jlpm run build",
"prettier": "prettier --write '{!(package),src/**,!(lib)/**}{.js,.jsx,.ts,.tsx,.css,.json,.md}'",
"watch": "tsc -w"
},
"dependencies": {
"@jupyterlab/application": "^2.0.0 || ^3.0.0",
"@jupyterlab/notebook": "^2.0.0 || ^3.0.0",
"@jupyterlab/console": "^2.0.0 || ^3.0.0"
},
"devDependencies": {
"prettier": "2.0.5",
"rimraf": "3.0.2",
"typescript": "3.9.3"
},
"jupyterlab": {
"extension": true
}
}
Loading