jupyterlab-pioneer 0.1.7 → 0.1.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -11,7 +11,7 @@ A JupyterLab extension for generating and exporting JupyterLab event telemetry d
11
11
 
12
12
  ```bash
13
13
  # enter the configuration_examples directory and run
14
- docker compose -p jupyterlab-pioneer up --build
14
+ docker compose -p jupyterlab_pioneer up --build
15
15
  ```
16
16
 
17
17
  A JupyterLab application with the extension installed and configured will run on localhost:8888.
@@ -23,7 +23,7 @@ A JupyterLab application with the extension installed and configured will run on
23
23
  To install the extension, execute:
24
24
 
25
25
  ```bash
26
- pip install jupyterlab-pioneer
26
+ pip install jupyterlab_pioneer
27
27
  ```
28
28
 
29
29
  Before starting Jupyter Lab, users need to write their own configuration files (or use the provided configuration examples) and **place them in the correct directory**.
@@ -61,7 +61,7 @@ Check jupyter server [doc](https://jupyter-server.readthedocs.io/en/latest/opera
61
61
 
62
62
  ```python
63
63
  {
64
- 'name': string # string, event name
64
+ 'name': # string, event name
65
65
  'logWholeNotebook': # boolean, whether to export the entire notebook content when event is triggered
66
66
  }
67
67
  ```
@@ -74,12 +74,12 @@ The extension will export the entire notebook content only for valid events with
74
74
 
75
75
  ```python
76
76
  {
77
- 'type': # one of 'console_exporter', 'command_line_exporter',
77
+ 'type': # One of 'console_exporter', 'command_line_exporter',
78
78
  # 'file_exporter', 'remote_exporter',
79
79
  # or 'custom_exporter'.
80
- 'args': # arguments passed to the exporter function.
80
+ 'args': # Optional. Arguments passed to the exporter function.
81
81
  # It needs to contain 'path' for file_exporter, 'url' for remote_exporter.
82
- 'activeEvents': # exporter's local active_events config will override global activeEvents config
82
+ 'activeEvents': # Optional. Exporter's local activeEvents config will override global activeEvents config
83
83
  }
84
84
  ```
85
85
 
@@ -121,6 +121,14 @@ jupyter labextension list
121
121
 
122
122
  ### Development install
123
123
 
124
+ #### (Optional) create conda environment from the provided `environment.yml` file
125
+
126
+ ```bash
127
+ conda env create -f environment.yml
128
+ ```
129
+
130
+ #### Clone and build the extension package
131
+
124
132
  Note: You will need NodeJS to build the extension package.
125
133
 
126
134
  The `jlpm` command is JupyterLab's pinned version of
@@ -129,7 +137,7 @@ The `jlpm` command is JupyterLab's pinned version of
129
137
 
130
138
  ```bash
131
139
  # Clone the repo to your local environment
132
- # Change directory to the jupyterlab_pioneer directory
140
+ # Change directory to the jupyterlab-pioneer directory
133
141
  # Install package in development mode
134
142
  pip install -e "."
135
143
  # Link your development version of the extension with JupyterLab
package/lib/index.d.ts CHANGED
@@ -8,13 +8,14 @@ export interface IJupyterLabPioneer {
8
8
  * Send event data to exporters defined in the configuration file.
9
9
  *
10
10
  * @param {NotebookPanel} notebookPanel The notebook panel the extension currently listens to.
11
- * @param {Object} eventDetail An object containing event details
12
- * @param {Boolean} logNotebookContent A boolean indicating whether to log the entire notebook or not
11
+ * @param {Object} eventDetail An object containing event details.
12
+ * @param {Exporter} exporter The exporter configuration.
13
+ * @param {Boolean=} logWholeNotebook A boolean indicating whether to log the entire notebook or not.
13
14
  */
14
- publishEvent(notebookPanel: NotebookPanel, eventDetail: Object, logWholeNotebook?: Boolean, exporter?: Exporter): Promise<void>;
15
+ publishEvent(notebookPanel: NotebookPanel, eventDetail: Object, exporter: Exporter, logWholeNotebook?: Boolean): Promise<void>;
15
16
  }
16
17
  declare class JupyterLabPioneer implements IJupyterLabPioneer {
17
- publishEvent(notebookPanel: NotebookPanel, eventDetail: Object, logWholeNotebook?: Boolean, exporter?: Exporter): Promise<void>;
18
+ publishEvent(notebookPanel: NotebookPanel, eventDetail: Object, exporter: Exporter, logWholeNotebook?: Boolean): Promise<void>;
18
19
  }
19
20
  declare const plugin: JupyterFrontEndPlugin<JupyterLabPioneer>;
20
21
  export default plugin;
package/lib/index.js CHANGED
@@ -5,7 +5,7 @@ import { producerCollection } from './producer';
5
5
  const PLUGIN_ID = 'jupyterlab-pioneer:plugin';
6
6
  export const IJupyterLabPioneer = new Token(PLUGIN_ID);
7
7
  class JupyterLabPioneer {
8
- async publishEvent(notebookPanel, eventDetail, logWholeNotebook, exporter) {
8
+ async publishEvent(notebookPanel, eventDetail, exporter, logWholeNotebook) {
9
9
  var _a, _b;
10
10
  if (!notebookPanel) {
11
11
  throw Error('router is listening to a null notebook panel');
@@ -44,7 +44,7 @@ const plugin = {
44
44
  await notebookPanel.sessionContext.ready;
45
45
  const activeEvents = config.activeEvents;
46
46
  const exporters = ((_a = notebookPanel.content.model) === null || _a === void 0 ? void 0 : _a.getMetadata('exporters')) ||
47
- config.exporters;
47
+ config.exporters; // The exporters configuration in the notebook metadata overrides the configuration in the configuration file "jupyter_jupyterlab_pioneer_config.py"
48
48
  const processedExporters = activeEvents && activeEvents.length
49
49
  ? exporters.map(e => {
50
50
  if (!e.activeEvents) {
@@ -56,6 +56,8 @@ const plugin = {
56
56
  }
57
57
  })
58
58
  : exporters.filter(e => e.activeEvents && e.activeEvents.length);
59
+ // Exporters without specifying the corresponding activeEvents will use the global activeEvents configuration.
60
+ // When the global activeEvents configuration is null, exporters that do not have corresponding activeEvents will be ignored.
59
61
  console.log(processedExporters);
60
62
  processedExporters.forEach(exporter => {
61
63
  producerCollection.forEach(producer => {
package/lib/producer.d.ts CHANGED
@@ -46,7 +46,7 @@ export declare class NotebookSaveEventProducer {
46
46
  static id: string;
47
47
  listen(notebookPanel: NotebookPanel, pioneer: IJupyterLabPioneer, exporter: Exporter): void;
48
48
  }
49
- export declare class NotebookScrollProducer {
49
+ export declare class NotebookScrollEventProducer {
50
50
  static id: string;
51
51
  private timeout;
52
52
  listen(notebookPanel: NotebookPanel, pioneer: IJupyterLabPioneer, exporter: Exporter): void;
package/lib/producer.js CHANGED
@@ -17,7 +17,7 @@ class ActiveCellChangeEventProducer {
17
17
  cells: [activatedCell] // activated cell
18
18
  }
19
19
  };
20
- await pioneer.publishEvent(notebookPanel, event, (_b = (_a = exporter.activeEvents) === null || _a === void 0 ? void 0 : _a.find(o => o.name == ActiveCellChangeEventProducer.id)) === null || _b === void 0 ? void 0 : _b.logWholeNotebook, exporter);
20
+ await pioneer.publishEvent(notebookPanel, event, exporter, (_b = (_a = exporter.activeEvents) === null || _a === void 0 ? void 0 : _a.find(o => o.name == ActiveCellChangeEventProducer.id)) === null || _b === void 0 ? void 0 : _b.logWholeNotebook);
21
21
  }
22
22
  });
23
23
  }
@@ -41,7 +41,7 @@ class CellAddEventProducer {
41
41
  cells: [addedCell]
42
42
  }
43
43
  };
44
- await pioneer.publishEvent(notebookPanel, event, (_b = (_a = exporter.activeEvents) === null || _a === void 0 ? void 0 : _a.find(o => o.name == CellAddEventProducer.id)) === null || _b === void 0 ? void 0 : _b.logWholeNotebook, exporter);
44
+ await pioneer.publishEvent(notebookPanel, event, exporter, (_b = (_a = exporter.activeEvents) === null || _a === void 0 ? void 0 : _a.find(o => o.name == CellAddEventProducer.id)) === null || _b === void 0 ? void 0 : _b.logWholeNotebook);
45
45
  }
46
46
  });
47
47
  }
@@ -63,7 +63,7 @@ class CellEditEventProducer {
63
63
  doc: (_b = (_a = editor === null || editor === void 0 ? void 0 : editor.state) === null || _a === void 0 ? void 0 : _a.doc) === null || _b === void 0 ? void 0 : _b.toJSON() // send entire cell content if this is a new cell
64
64
  }
65
65
  };
66
- await pioneer.publishEvent(notebookPanel, event, (_d = (_c = exporter.activeEvents) === null || _c === void 0 ? void 0 : _c.find(o => o.name == CellEditEventProducer.id)) === null || _d === void 0 ? void 0 : _d.logWholeNotebook, exporter);
66
+ await pioneer.publishEvent(notebookPanel, event, exporter, (_d = (_c = exporter.activeEvents) === null || _c === void 0 ? void 0 : _c.find(o => o.name == CellEditEventProducer.id)) === null || _d === void 0 ? void 0 : _d.logWholeNotebook);
67
67
  };
68
68
  const addDocChangeListener = async (cell) => {
69
69
  await (cell === null || cell === void 0 ? void 0 : cell.ready); // wait until cell is ready, to prevent errors when creating new cells
@@ -78,8 +78,8 @@ class CellEditEventProducer {
78
78
  changes: v.changes.toJSON() // send changes
79
79
  }
80
80
  };
81
- await pioneer.publishEvent(notebookPanel, event, false, // do not log whole notebook for doc changes
82
- exporter);
81
+ await pioneer.publishEvent(notebookPanel, event, exporter, false // do not log whole notebook for doc changes
82
+ );
83
83
  }
84
84
  }));
85
85
  };
@@ -116,7 +116,7 @@ class CellExecuteEventProducer {
116
116
  kernelError: args.success ? null : args.error
117
117
  }
118
118
  };
119
- await pioneer.publishEvent(notebookPanel, event, (_b = (_a = exporter.activeEvents) === null || _a === void 0 ? void 0 : _a.find(o => o.name == CellExecuteEventProducer.id)) === null || _b === void 0 ? void 0 : _b.logWholeNotebook, exporter);
119
+ await pioneer.publishEvent(notebookPanel, event, exporter, (_b = (_a = exporter.activeEvents) === null || _a === void 0 ? void 0 : _a.find(o => o.name == CellExecuteEventProducer.id)) === null || _b === void 0 ? void 0 : _b.logWholeNotebook);
120
120
  }
121
121
  });
122
122
  }
@@ -130,8 +130,7 @@ class CellRemoveEventProducer {
130
130
  var _a, _b;
131
131
  if (args.type === 'remove') {
132
132
  const removedCell = {
133
- newIndex: args.newIndex,
134
- oldIndex: args.oldIndex
133
+ index: args.oldIndex
135
134
  };
136
135
  const event = {
137
136
  eventName: CellRemoveEventProducer.id,
@@ -140,7 +139,7 @@ class CellRemoveEventProducer {
140
139
  cells: [removedCell]
141
140
  }
142
141
  };
143
- await pioneer.publishEvent(notebookPanel, event, (_b = (_a = exporter.activeEvents) === null || _a === void 0 ? void 0 : _a.find(o => o.name == CellRemoveEventProducer.id)) === null || _b === void 0 ? void 0 : _b.logWholeNotebook, exporter);
142
+ await pioneer.publishEvent(notebookPanel, event, exporter, (_b = (_a = exporter.activeEvents) === null || _a === void 0 ? void 0 : _a.find(o => o.name == CellRemoveEventProducer.id)) === null || _b === void 0 ? void 0 : _b.logWholeNotebook);
144
143
  }
145
144
  });
146
145
  }
@@ -164,7 +163,7 @@ class ClipboardCopyEventProducer {
164
163
  selection: text
165
164
  }
166
165
  };
167
- await pioneer.publishEvent(notebookPanel, event, (_d = (_c = exporter.activeEvents) === null || _c === void 0 ? void 0 : _c.find(o => o.name == ClipboardCopyEventProducer.id)) === null || _d === void 0 ? void 0 : _d.logWholeNotebook, exporter);
166
+ await pioneer.publishEvent(notebookPanel, event, exporter, (_d = (_c = exporter.activeEvents) === null || _c === void 0 ? void 0 : _c.find(o => o.name == ClipboardCopyEventProducer.id)) === null || _d === void 0 ? void 0 : _d.logWholeNotebook);
168
167
  });
169
168
  }
170
169
  }
@@ -187,7 +186,7 @@ class ClipboardCutEventProducer {
187
186
  selection: text
188
187
  }
189
188
  };
190
- await pioneer.publishEvent(notebookPanel, event, (_d = (_c = exporter.activeEvents) === null || _c === void 0 ? void 0 : _c.find(o => o.name == ClipboardCutEventProducer.id)) === null || _d === void 0 ? void 0 : _d.logWholeNotebook, exporter);
189
+ await pioneer.publishEvent(notebookPanel, event, exporter, (_d = (_c = exporter.activeEvents) === null || _c === void 0 ? void 0 : _c.find(o => o.name == ClipboardCutEventProducer.id)) === null || _d === void 0 ? void 0 : _d.logWholeNotebook);
191
190
  });
192
191
  }
193
192
  }
@@ -210,7 +209,7 @@ class ClipboardPasteEventProducer {
210
209
  selection: text
211
210
  }
212
211
  };
213
- await pioneer.publishEvent(notebookPanel, event, (_c = (_b = exporter.activeEvents) === null || _b === void 0 ? void 0 : _b.find(o => o.name == ClipboardPasteEventProducer.id)) === null || _c === void 0 ? void 0 : _c.logWholeNotebook, exporter);
212
+ await pioneer.publishEvent(notebookPanel, event, exporter, (_c = (_b = exporter.activeEvents) === null || _b === void 0 ? void 0 : _b.find(o => o.name == ClipboardPasteEventProducer.id)) === null || _c === void 0 ? void 0 : _c.logWholeNotebook);
214
213
  });
215
214
  }
216
215
  }
@@ -227,7 +226,7 @@ class NotebookHiddenEventProducer {
227
226
  eventTime: Date.now(),
228
227
  eventInfo: null
229
228
  };
230
- await pioneer.publishEvent(notebookPanel, event, (_b = (_a = exporter.activeEvents) === null || _a === void 0 ? void 0 : _a.find(o => o.name == NotebookHiddenEventProducer.id)) === null || _b === void 0 ? void 0 : _b.logWholeNotebook, exporter);
229
+ await pioneer.publishEvent(notebookPanel, event, exporter, (_b = (_a = exporter.activeEvents) === null || _a === void 0 ? void 0 : _a.find(o => o.name == NotebookHiddenEventProducer.id)) === null || _b === void 0 ? void 0 : _b.logWholeNotebook);
231
230
  }
232
231
  });
233
232
  }
@@ -248,7 +247,7 @@ class NotebookOpenEventProducer {
248
247
  environ: await requestAPI('environ')
249
248
  }
250
249
  };
251
- await pioneer.publishEvent(notebookPanel, event, (_b = (_a = exporter.activeEvents) === null || _a === void 0 ? void 0 : _a.find(o => o.name == NotebookOpenEventProducer.id)) === null || _b === void 0 ? void 0 : _b.logWholeNotebook, exporter);
250
+ await pioneer.publishEvent(notebookPanel, event, exporter, (_b = (_a = exporter.activeEvents) === null || _a === void 0 ? void 0 : _a.find(o => o.name == NotebookOpenEventProducer.id)) === null || _b === void 0 ? void 0 : _b.logWholeNotebook);
252
251
  this.produced = true;
253
252
  }
254
253
  }
@@ -265,7 +264,7 @@ class NotebookSaveEventProducer {
265
264
  eventTime: Date.now(),
266
265
  eventInfo: null
267
266
  };
268
- await pioneer.publishEvent(notebookPanel, event, (_b = (_a = exporter.activeEvents) === null || _a === void 0 ? void 0 : _a.find(o => o.name == NotebookSaveEventProducer.id)) === null || _b === void 0 ? void 0 : _b.logWholeNotebook, exporter);
267
+ await pioneer.publishEvent(notebookPanel, event, exporter, (_b = (_a = exporter.activeEvents) === null || _a === void 0 ? void 0 : _a.find(o => o.name == NotebookSaveEventProducer.id)) === null || _b === void 0 ? void 0 : _b.logWholeNotebook);
269
268
  }
270
269
  });
271
270
  }
@@ -290,7 +289,7 @@ const getVisibleCells = (notebookPanel) => {
290
289
  }
291
290
  return visibleCells;
292
291
  };
293
- class NotebookScrollProducer {
292
+ class NotebookScrollEventProducer {
294
293
  constructor() {
295
294
  this.timeout = 0;
296
295
  }
@@ -301,18 +300,18 @@ class NotebookScrollProducer {
301
300
  clearTimeout(this.timeout);
302
301
  await new Promise(resolve => (this.timeout = window.setTimeout(resolve, 1500))); // wait 1.5 seconds before preceding
303
302
  const event = {
304
- eventName: NotebookScrollProducer.id,
303
+ eventName: NotebookScrollEventProducer.id,
305
304
  eventTime: Date.now(),
306
305
  eventInfo: {
307
306
  cells: getVisibleCells(notebookPanel)
308
307
  }
309
308
  };
310
- await pioneer.publishEvent(notebookPanel, event, (_b = (_a = exporter.activeEvents) === null || _a === void 0 ? void 0 : _a.find(o => o.name == NotebookScrollProducer.id)) === null || _b === void 0 ? void 0 : _b.logWholeNotebook, exporter);
309
+ await pioneer.publishEvent(notebookPanel, event, exporter, (_b = (_a = exporter.activeEvents) === null || _a === void 0 ? void 0 : _a.find(o => o.name == NotebookScrollEventProducer.id)) === null || _b === void 0 ? void 0 : _b.logWholeNotebook);
311
310
  });
312
311
  }
313
312
  }
314
- NotebookScrollProducer.id = 'NotebookScrollEvent';
315
- export { NotebookScrollProducer };
313
+ NotebookScrollEventProducer.id = 'NotebookScrollEvent';
314
+ export { NotebookScrollEventProducer };
316
315
  class NotebookVisibleEventProducer {
317
316
  listen(notebookPanel, pioneer, exporter) {
318
317
  document.addEventListener('visibilitychange', async () => {
@@ -326,7 +325,7 @@ class NotebookVisibleEventProducer {
326
325
  cells: getVisibleCells(notebookPanel)
327
326
  }
328
327
  };
329
- await pioneer.publishEvent(notebookPanel, event, (_b = (_a = exporter.activeEvents) === null || _a === void 0 ? void 0 : _a.find(o => o.name == NotebookVisibleEventProducer.id)) === null || _b === void 0 ? void 0 : _b.logWholeNotebook, exporter);
328
+ await pioneer.publishEvent(notebookPanel, event, exporter, (_b = (_a = exporter.activeEvents) === null || _a === void 0 ? void 0 : _a.find(o => o.name == NotebookVisibleEventProducer.id)) === null || _b === void 0 ? void 0 : _b.logWholeNotebook);
330
329
  }
331
330
  });
332
331
  }
@@ -345,6 +344,6 @@ export const producerCollection = [
345
344
  NotebookHiddenEventProducer,
346
345
  NotebookOpenEventProducer,
347
346
  NotebookSaveEventProducer,
348
- NotebookScrollProducer,
347
+ NotebookScrollEventProducer,
349
348
  NotebookVisibleEventProducer
350
349
  ];
package/lib/types.d.ts CHANGED
@@ -1,20 +1,58 @@
1
1
  export interface ActiveEvent {
2
+ /**
3
+ * Name of the active event (the static id associate with the event class)
4
+ */
2
5
  name: string;
6
+ /**
7
+ * Whether to log the whole notebook or not when the event is triggered
8
+ */
3
9
  logWholeNotebook: boolean;
4
10
  }
5
11
  export interface ExporterArgs {
12
+ /**
13
+ * Exporter ID
14
+ */
6
15
  id: string;
16
+ /**
17
+ * Local file path (required for file exporter)
18
+ */
19
+ path?: string;
20
+ /**
21
+ * Http endpoint (required for remote exporter)
22
+ */
7
23
  url?: string;
24
+ /**
25
+ * Additional parameters to pass to the http endpoint (optional for remote exporter)
26
+ */
8
27
  params?: Object;
9
- path?: string;
28
+ /**
29
+ * Environment variables to pass to the http endpoint (optional for remote exporter)
30
+ */
10
31
  env?: Object[];
11
32
  }
12
33
  export interface Exporter {
34
+ /**
35
+ * Exporter type, should be one of "console_exporter", "command_line_exporter", "file_exporter", "remote_exporter" or "custom_exporter"
36
+ */
13
37
  type: string;
38
+ /**
39
+ * Arguments to pass to the exporter function
40
+ */
14
41
  args?: ExporterArgs;
42
+ /**
43
+ * An array of active events defined inside of individual exporters. It overrides the global activeEvents configuration defined in the configuration file.
44
+ * The extension would only generate and export data for valid events ( 1. that have an id associated with the event class, 2. the event name is included in activeEvents ).
45
+ * The extension will export the entire notebook content only for valid events when the logWholeNotebook flag is True.
46
+ */
15
47
  activeEvents?: ActiveEvent[];
16
48
  }
17
49
  export interface Config {
50
+ /**
51
+ * An array of active events
52
+ */
18
53
  activeEvents: ActiveEvent[];
54
+ /**
55
+ * An array of exporters
56
+ */
19
57
  exporters: Exporter[];
20
58
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jupyterlab-pioneer",
3
- "version": "0.1.7",
3
+ "version": "0.1.9",
4
4
  "description": "A JupyterLab extension.",
5
5
  "keywords": [
6
6
  "jupyter",