Skip to content

Commit 3f3853d

Browse files
authored
Merge pull request #313 from martinRenou/more_perf
Some more performance improvements
2 parents afe9065 + 597f7c1 commit 3f3853d

File tree

6 files changed

+151
-25
lines changed

6 files changed

+151
-25
lines changed

package.json

+1
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@
9696
"yjs": "^13.5.40"
9797
},
9898
"jupyterlab": {
99+
"schemaDir": "schema",
99100
"extension": true,
100101
"outputDir": "lckr_jupyterlab_variableinspector/labextension",
101102
"sharedPackages": {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{
2+
"jupyter.lab.setting-icon": "ui-components:list",
3+
"title": "Variable Inspector",
4+
"description": "Settings for the jupyterlab-variableInspector extension.",
5+
"type": "object",
6+
"properties": {
7+
"maxItems": {
8+
"type": "number",
9+
"minimum": 0,
10+
"title": "Maximum number of items",
11+
"description": "The maximum number of items to show in lists/dicts etc",
12+
"default": 10
13+
}
14+
}
15+
}

src/handler.ts

+40
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import { ISessionContext } from '@jupyterlab/apputils';
22

3+
import { ISettingRegistry } from '@jupyterlab/settingregistry';
4+
35
import { IExecuteResult } from '@jupyterlab/nbformat';
46

57
import { IRenderMimeRegistry } from '@jupyterlab/rendermime';
@@ -100,8 +102,12 @@ export class VariableInspectionHandler extends AbstractHandler {
100102
private _matrixQueryCommand: string;
101103
private _widgetQueryCommand: string;
102104
private _deleteCommand: string;
105+
private _changeSettingsCommand:
106+
| ((settings: IVariableInspector.ISettings) => string)
107+
| undefined;
103108
private _ready: Promise<void>;
104109
private _id: string;
110+
private _setting: ISettingRegistry.ISettings;
105111

106112
constructor(options: VariableInspectionHandler.IOptions) {
107113
super(options.connector);
@@ -110,11 +116,14 @@ export class VariableInspectionHandler extends AbstractHandler {
110116
this._queryCommand = options.queryCommand;
111117
this._matrixQueryCommand = options.matrixQueryCommand;
112118
this._widgetQueryCommand = options.widgetQueryCommand;
119+
this._changeSettingsCommand = options.changeSettingsCommand;
113120
this._deleteCommand = options.deleteCommand;
114121
this._initScript = options.initScript;
122+
this._setting = options.setting;
115123

116124
this._ready = this._connector.ready.then(() => {
117125
this._initOnKernel().then((msg: KernelMessage.IExecuteReplyMsg) => {
126+
this.performSettingsChange();
118127
this._connector.iopubMessage.connect(this._queryCall);
119128
return;
120129
});
@@ -131,12 +140,20 @@ export class VariableInspectionHandler extends AbstractHandler {
131140

132141
this._ready = kernelReady.then(() => {
133142
this._initOnKernel().then((msg: KernelMessage.IExecuteReplyMsg) => {
143+
this.performSettingsChange();
134144
this._connector.iopubMessage.connect(this._queryCall);
135145
this.performInspection();
136146
});
137147
});
138148
};
139149

150+
this._setting.changed.connect(async () => {
151+
await this._ready;
152+
153+
this.performSettingsChange();
154+
this.performInspection();
155+
});
156+
140157
this._connector.kernelRestarted.connect(onKernelReset);
141158
this._connector.kernelChanged.connect(onKernelReset);
142159
}
@@ -232,6 +249,27 @@ export class VariableInspectionHandler extends AbstractHandler {
232249
this._connector.fetch(content, this._handleQueryResponse);
233250
}
234251

252+
/**
253+
* Send a kernel request to change settings
254+
*/
255+
performSettingsChange(): void {
256+
if (!this._changeSettingsCommand) {
257+
return;
258+
}
259+
260+
const settings: IVariableInspector.ISettings = {
261+
maxItems: this._setting.get('maxItems').composite as number
262+
};
263+
264+
const content: KernelMessage.IExecuteRequestMsg['content'] = {
265+
code: this._changeSettingsCommand(settings),
266+
stop_on_error: false,
267+
store_history: false
268+
};
269+
270+
this._connector.fetch(content, this._handleQueryResponse);
271+
}
272+
235273
/**
236274
* Initializes the kernel by running the set up script located at _initScriptPath.
237275
*/
@@ -344,9 +382,11 @@ export namespace VariableInspectionHandler {
344382
queryCommand: string;
345383
matrixQueryCommand: string;
346384
widgetQueryCommand: string;
385+
changeSettingsCommand?(settings: IVariableInspector.ISettings): string;
347386
deleteCommand: string;
348387
initScript: string;
349388
id: string;
389+
setting: ISettingRegistry.ISettings;
350390
}
351391
}
352392

src/index.ts

+45-20
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ import { IConsoleTracker } from '@jupyterlab/console';
1111

1212
import { INotebookTracker, NotebookPanel } from '@jupyterlab/notebook';
1313

14+
import { ISettingRegistry } from '@jupyterlab/settingregistry';
15+
1416
import { listIcon } from '@jupyterlab/ui-components';
1517

1618
import { DummyHandler, VariableInspectionHandler } from './handler';
@@ -30,6 +32,9 @@ namespace CommandIDs {
3032
export const open = 'variableinspector:open';
3133
}
3234

35+
const SETTINGS_ID =
36+
'@lckr/jupyterlab_variableinspector:jupyterlab-variableInspector-settings';
37+
3338
/**
3439
* A service providing variable introspection.
3540
*/
@@ -110,17 +115,24 @@ const variableinspector: JupyterFrontEndPlugin<IVariableInspectorManager> = {
110115
*/
111116
const consoles: JupyterFrontEndPlugin<void> = {
112117
id: '@lckr/jupyterlab-variableinspector:consoles',
113-
requires: [IVariableInspectorManager, IConsoleTracker, ILabShell],
118+
requires: [
119+
IVariableInspectorManager,
120+
IConsoleTracker,
121+
ILabShell,
122+
ISettingRegistry
123+
],
114124
autoStart: true,
115-
activate: (
125+
activate: async (
116126
app: JupyterFrontEnd,
117127
manager: IVariableInspectorManager,
118128
consoles: IConsoleTracker,
119-
labShell: ILabShell
120-
): void => {
129+
labShell: ILabShell,
130+
settings: ISettingRegistry
131+
): Promise<void> => {
121132
const handlers: {
122133
[id: string]: Promise<IVariableInspector.IInspectable>;
123134
} = {};
135+
const setting = await settings.load(SETTINGS_ID);
124136

125137
/**
126138
* Subscribes to the creation of new consoles. If a new notebook is created, build a new handler for the consoles.
@@ -150,15 +162,18 @@ const consoles: JupyterFrontEndPlugin<void> = {
150162
const matrixQueryCommand = result.matrixQueryCommand;
151163
const widgetQueryCommand = result.widgetQueryCommand;
152164
const deleteCommand = result.deleteCommand;
165+
const changeSettingsCommand = result.changeSettingsCommand;
153166

154167
const options: VariableInspectionHandler.IOptions = {
155-
queryCommand: queryCommand,
156-
matrixQueryCommand: matrixQueryCommand,
168+
queryCommand,
169+
matrixQueryCommand,
157170
widgetQueryCommand,
158-
deleteCommand: deleteCommand,
159-
connector: connector,
160-
initScript: initScript,
161-
id: session.path //Using the sessions path as an identifier for now.
171+
deleteCommand,
172+
connector,
173+
initScript,
174+
changeSettingsCommand,
175+
id: session.path, //Using the sessions path as an identifier for now.
176+
setting
162177
};
163178
const handler = new VariableInspectionHandler(options);
164179
manager.addHandler(handler);
@@ -222,15 +237,22 @@ const consoles: JupyterFrontEndPlugin<void> = {
222237
*/
223238
const notebooks: JupyterFrontEndPlugin<void> = {
224239
id: '@lckr/jupyterlab-variableinspector:notebooks',
225-
requires: [IVariableInspectorManager, INotebookTracker, ILabShell],
240+
requires: [
241+
IVariableInspectorManager,
242+
INotebookTracker,
243+
ILabShell,
244+
ISettingRegistry
245+
],
226246
autoStart: true,
227-
activate: (
247+
activate: async (
228248
app: JupyterFrontEnd,
229249
manager: IVariableInspectorManager,
230250
notebooks: INotebookTracker,
231-
labShell: ILabShell
232-
): void => {
251+
labShell: ILabShell,
252+
settings: ISettingRegistry
253+
): Promise<void> => {
233254
const handlers: { [id: string]: Promise<VariableInspectionHandler> } = {};
255+
const setting = await settings.load(SETTINGS_ID);
234256

235257
/**
236258
* Subscribes to the creation of new notebooks. If a new notebook is created, build a new handler for the notebook.
@@ -256,16 +278,19 @@ const notebooks: JupyterFrontEndPlugin<void> = {
256278
const matrixQueryCommand = result.matrixQueryCommand;
257279
const widgetQueryCommand = result.widgetQueryCommand;
258280
const deleteCommand = result.deleteCommand;
281+
const changeSettingsCommand = result.changeSettingsCommand;
259282

260283
const options: VariableInspectionHandler.IOptions = {
261-
queryCommand: queryCommand,
262-
matrixQueryCommand: matrixQueryCommand,
284+
queryCommand,
285+
matrixQueryCommand,
263286
widgetQueryCommand,
264-
deleteCommand: deleteCommand,
265-
connector: connector,
287+
deleteCommand,
288+
connector,
266289
rendermime,
267-
initScript: initScript,
268-
id: session.path //Using the sessions path as an identifier for now.
290+
initScript,
291+
changeSettingsCommand,
292+
id: session.path, //Using the sessions path as an identifier for now.
293+
setting
269294
};
270295
const handler = new VariableInspectionHandler(options);
271296
manager.addHandler(handler);

src/inspectorscripts.ts

+45-5
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
1+
import { IVariableInspector } from './tokens';
2+
13
export namespace Languages {
24
export type LanguageModel = {
35
initScript: string;
46
queryCommand: string;
57
matrixQueryCommand: string;
68
widgetQueryCommand: string;
79
deleteCommand: string;
10+
changeSettingsCommand?: (settings: IVariableInspector.ISettings) => string;
811
};
912
}
1013

@@ -16,6 +19,8 @@ export abstract class Languages {
1619
static py_script = `import json
1720
import sys
1821
from importlib import __import__
22+
from itertools import islice
23+
import collections
1924
from IPython import get_ipython
2025
from IPython.core.magics.namespace import NamespaceMagics
2126
@@ -24,6 +29,8 @@ _jupyterlab_variableinspector_nms = NamespaceMagics()
2429
_jupyterlab_variableinspector_Jupyter = get_ipython()
2530
_jupyterlab_variableinspector_nms.shell = _jupyterlab_variableinspector_Jupyter.kernel.shell
2631
32+
_jupyterlab_variableinspector_maxitems = 10
33+
2734
__np = None
2835
__pd = None
2936
__pyspark = None
@@ -54,6 +61,12 @@ def _check_imported():
5461
__xr = _attempt_import('xarray')
5562
5663
64+
def _jupyterlab_variableinspector_changesettings(maxitems, **kwargs):
65+
global _jupyterlab_variableinspector_maxitems
66+
67+
_jupyterlab_variableinspector_maxitems = maxitems
68+
69+
5770
def _jupyterlab_variableinspector_getsizeof(x):
5871
if type(x).__name__ in ['ndarray', 'Series']:
5972
return x.nbytes
@@ -101,7 +114,28 @@ def _jupyterlab_variableinspector_getshapeof(x):
101114
def _jupyterlab_variableinspector_getcontentof(x):
102115
# returns content in a friendly way for python variables
103116
# pandas and numpy
104-
if __pd and isinstance(x, __pd.DataFrame):
117+
if isinstance(x, (bool, str, int, float, type(None))):
118+
content = str(x)
119+
elif isinstance(x, (list, tuple)):
120+
if len(x) <= _jupyterlab_variableinspector_maxitems:
121+
content = str(x)
122+
else:
123+
content = "["
124+
for i in range(_jupyterlab_variableinspector_maxitems):
125+
content += f"{x[i]}, "
126+
content += "...]"
127+
elif isinstance(x, collections.abc.Mapping):
128+
if len(x.keys()) <= _jupyterlab_variableinspector_maxitems:
129+
content = str(x)
130+
else:
131+
first_ten_keys = list(islice(x.keys(), _jupyterlab_variableinspector_maxitems))
132+
content = "{"
133+
for idx, key in enumerate(first_ten_keys):
134+
if idx > 0:
135+
content += ", "
136+
content += f'"{key}": {x[key]}'
137+
content += ", ...}"
138+
elif __pd and isinstance(x, __pd.DataFrame):
105139
colnames = ', '.join(x.columns.map(str))
106140
content = "Columns: %s" % colnames
107141
elif __pd and isinstance(x, __pd.Series):
@@ -152,7 +186,7 @@ def _jupyterlab_variableinspector_dict_list():
152186
def keep_cond(v):
153187
try:
154188
obj = eval(v)
155-
if isinstance(obj, (bool, str, list, int, float, type(None))):
189+
if isinstance(obj, (bool, str, list, tuple, collections.abc.Mapping, int, float, type(None))):
156190
return True
157191
if __tf and isinstance(obj, __tf.Variable):
158192
return True
@@ -311,21 +345,27 @@ def _jupyterlab_variableinspector_deletevariable(x):
311345
queryCommand: '_jupyterlab_variableinspector_dict_list()',
312346
matrixQueryCommand: '_jupyterlab_variableinspector_getmatrixcontent',
313347
widgetQueryCommand: '_jupyterlab_variableinspector_displaywidget',
314-
deleteCommand: '_jupyterlab_variableinspector_deletevariable'
348+
deleteCommand: '_jupyterlab_variableinspector_deletevariable',
349+
changeSettingsCommand: (settings: IVariableInspector.ISettings) =>
350+
`_jupyterlab_variableinspector_changesettings(maxitems=${settings.maxItems})`
315351
},
316352
python2: {
317353
initScript: Languages.py_script,
318354
queryCommand: '_jupyterlab_variableinspector_dict_list()',
319355
matrixQueryCommand: '_jupyterlab_variableinspector_getmatrixcontent',
320356
widgetQueryCommand: '_jupyterlab_variableinspector_displaywidget',
321-
deleteCommand: '_jupyterlab_variableinspector_deletevariable'
357+
deleteCommand: '_jupyterlab_variableinspector_deletevariable',
358+
changeSettingsCommand: (settings: IVariableInspector.ISettings) =>
359+
`_jupyterlab_variableinspector_changesettings(maxitems=${settings.maxItems})`
322360
},
323361
python: {
324362
initScript: Languages.py_script,
325363
queryCommand: '_jupyterlab_variableinspector_dict_list()',
326364
matrixQueryCommand: '_jupyterlab_variableinspector_getmatrixcontent',
327365
widgetQueryCommand: '_jupyterlab_variableinspector_displaywidget',
328-
deleteCommand: '_jupyterlab_variableinspector_deletevariable'
366+
deleteCommand: '_jupyterlab_variableinspector_deletevariable',
367+
changeSettingsCommand: (settings: IVariableInspector.ISettings) =>
368+
`_jupyterlab_variableinspector_changesettings(maxitems=${settings.maxItems})`
329369
},
330370
R: {
331371
initScript: Languages.r_script,

src/tokens.ts

+5
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,10 @@ export namespace IVariableInspector {
5353
performDelete(varName: string): void;
5454
}
5555

56+
export interface ISettings {
57+
maxItems: number;
58+
}
59+
5660
export interface IVariableInspectorUpdate {
5761
title: IVariableTitle;
5862
payload: Array<IVariable>;
@@ -67,6 +71,7 @@ export namespace IVariableInspector {
6771
isMatrix: boolean;
6872
isWidget: boolean;
6973
}
74+
7075
export interface IVariableTitle {
7176
kernelName?: string;
7277
contextName?: string; //Context currently reserved for special information.

0 commit comments

Comments
 (0)