jupyterlab-pioneer 0.1.8 → 0.1.10

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
@@ -38,12 +38,13 @@ The configuration file controls the activated events and data exporters.
38
38
 
39
39
  To add a data exporter, users should assign a callable function along with function arguments when configuring `exporters`.
40
40
 
41
- This extension provides 4 default exporters.
41
+ This extension provides 5 default exporters.
42
42
 
43
- - [`console_exporter`](https://github.com/educational-technology-collective/jupyterlab-pioneer/blob/main/jupyterlab_pioneer/default_exporters.py#L9), which sends telemetry data to the browser console
44
- - [`command_line_exporter`](https://github.com/educational-technology-collective/jupyterlab-pioneer/blob/main/jupyterlab_pioneer/default_exporters.py#L32), which sends telemetry data to the python console jupyter is running on
45
- - [`file_exporter`](https://github.com/educational-technology-collective/jupyterlab-pioneer/blob/main/jupyterlab_pioneer/default_exporters.py#L57), which saves telemetry data to local file
46
- - [`remote_exporter`](https://github.com/educational-technology-collective/jupyterlab-pioneer/blob/main/jupyterlab_pioneer/default_exporters.py#L85), which sends telemetry data to a remote http endpoint
43
+ - [`console_exporter`](https://github.com/educational-technology-collective/jupyterlab-pioneer/blob/main/jupyterlab_pioneer/default_exporters.py#L22), which sends telemetry data to the browser console
44
+ - [`command_line_exporter`](https://github.com/educational-technology-collective/jupyterlab-pioneer/blob/main/jupyterlab_pioneer/default_exporters.py#L48), which sends telemetry data to the python console jupyter is running on
45
+ - [`file_exporter`](https://github.com/educational-technology-collective/jupyterlab-pioneer/blob/main/jupyterlab_pioneer/default_exporters.py#L76), which saves telemetry data to local file
46
+ - [`remote_exporter`](https://github.com/educational-technology-collective/jupyterlab-pioneer/blob/main/jupyterlab_pioneer/default_exporters.py#L106), which sends telemetry data to a remote http endpoint
47
+ - [`opentelemetry_exporter`](https://github.com/educational-technology-collective/jupyterlab-pioneer/blob/main/jupyterlab_pioneer/default_exporters.py#L162), which sends telemetry data via otlp.
47
48
 
48
49
  Additionally, users can write customized exporters in the configuration file.
49
50
 
@@ -66,9 +67,8 @@ Check jupyter server [doc](https://jupyter-server.readthedocs.io/en/latest/opera
66
67
  }
67
68
  ```
68
69
 
69
- The extension would only generate and export data for valid events ( 1. that have an id associated with the event class, 2. and the event name is included in `activeEvents`
70
- ).
71
- The extension will export the entire notebook content only for valid events with the `logWholeNotebook` flag == True.
70
+ The extension would only generate and export data for valid event that has an id associated with the event class, and the event name is included in `activeEvents`.
71
+ The extension will export the entire notebook content only for valid events when the `logWholeNotebook` flag is True.
72
72
 
73
73
  `exporters`: An array of exporters. Each exporter in the array should have the following structure:
74
74
 
@@ -122,11 +122,13 @@ jupyter labextension list
122
122
  ### Development install
123
123
 
124
124
  #### (Optional) create conda environment from the provided `environment.yml` file
125
+
125
126
  ```bash
126
127
  conda env create -f environment.yml
127
128
  ```
128
129
 
129
130
  #### Clone and build the extension package
131
+
130
132
  Note: You will need NodeJS to build the extension package.
131
133
 
132
134
  The `jlpm` command is JupyterLab's pinned version of
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", "opentelemetry_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.8",
3
+ "version": "0.1.10",
4
4
  "description": "A JupyterLab extension.",
5
5
  "keywords": [
6
6
  "jupyter",