0.1.4 • Published 9 months ago

jupyterlab-telemetry-producer-demo v0.1.4

Weekly downloads
-
License
BSD-3-Clause
Repository
github
Last release
9 months ago

JupyterLab Telemetry Producer Demo

PyPI npm

A JupyterLab extension that generates telemetry data when users click on a button.

This extension relies on the jupyterlab-telemetry-router extension.

Getting started

Requirements

  • JupyterLab >= 4.0.0

Install

To install the extension, execute:

pip install jupyterlab-telemetry-producer-demo

The telemetry router extension is automatically installed when the telemetry producer is installed.

Users need to write their own router configuration file (or use the configuration example) and place it in the correct directory before starting Jupyter Lab with the telemetry system.

Examples of router configurations are here.

Examples of producer configurations are here

Uninstall

To remove the extension, execute:

pip uninstall jupyterlab-telemetry-producer-demo

How to implement a custom telemetry producer extension

Set up development environment

conda create -n telemetry-demo --override-channels --strict-channel-priority -c conda-forge -c nodefaults jupyterlab=4 nodejs=18 copier=8 jinja2-time jupyter-packaging git

conda activate telemetry-demo

Implement the extension from scratch

Initialize from the extension template

mkdir jupyterlab-telemetry-producer-demo

cd jupyterlab-telemetry-producer-demo

copier copy --UNSAFE https://github.com/jupyterlab/extension-template .

Add jupyterlab-telemetry-router as a dependency in pyproject.toml.

dependencies = [
    "jupyter_server>=2.0.1,<3",
    "jupyterlab-telemetry-router"
]

Note: You will need NodeJS to build the extension package.

The jlpm command is JupyterLab's pinned version of yarn that is installed with JupyterLab. You may use yarn or npm in lieu of jlpm below.

# Install package in development mode
pip install -e "."
# Link your development version of the extension with JupyterLab
jupyter labextension develop . --overwrite
# Server extension must be manually installed in develop mode
jupyter server extension enable jupyterlab-telemetry-producer-demo
# Rebuild extension Typescript source after making changes
jlpm build

You can watch the source directory and run JupyterLab at the same time in different terminals to watch for changes in the extension's source and automatically rebuild the extension.

# Watch the source directory in one terminal, automatically rebuilding when needed
jlpm watch
# Run JupyterLab in another terminal
jupyter lab

Implement the extension based on the demo extension

# Clone the repo to your local environment
git clone https://github.com/educational-technology-collective/jupyterlab-telemetry-producer-demo
# Change directory to the jupyterlab-telemetry-producer-demo directory
cd jupyterlab-telemetry-producer-demo
# Install package in development mode
pip install -e "."
# Link your development version of the extension with JupyterLab
jupyter labextension develop . --overwrite
# Server extension must be manually installed in develop mode
jupyter server extension enable jupyterlab-telemetry-producer-demo
# Rebuild extension Typescript source after making changes
jlpm build
# Or watch the source directory in one terminal, automatically rebuilding when needed
jlpm watch
# Run JupyterLab in another terminal
jupyter lab

With the watch command running, every saved change will immediately be built locally and available in your running JupyterLab. Refresh JupyterLab to load the change in your browser (you may need to wait several seconds for the extension to be rebuilt).

By default, the jlpm build command generates the source maps for this extension to make it easier to debug using the browser dev tools. To also generate source maps for the JupyterLab core extensions, you can run the following command:

jupyter lab build --minimize=False

Development Workflow

Client Side

  • Make changes to the TypeScript client extension.
  • Refresh the browser.
  • Observe the changes in the running application.

Server Side

  • Make changes to the Python server extension.
  • Stop the Jupyter server.
  • Start the Jupyter server.
  • Observe the changes in the running application.

Useful links

https://jupyterlab.readthedocs.io/en/stable/extension/extension_tutorial.html

https://jupyter-server.readthedocs.io/en/latest/operators/configuring-extensions.html

https://github.com/educational-technology-collective/jupyterlab-telemetry-router

https://github.com/educational-technology-collective/jupyterlab-telemetry-producer

Development uninstall

# Server extension must be manually disabled in develop mode
jupyter server extension disable jupyterlab-telemetry-producer-demo
pip uninstall jupyterlab-telemetry-producer-demo

In development mode, you will also need to remove the symlink created by jupyter labextension develop command. To find its location, you can run jupyter labextension list to figure out where the labextensions folder is located. Then you can remove the symlink named jupyterlab-telemetry-producer-demo within that folder.

Packaging the extension

See RELEASE

How to utilize the telemetry router extension to export telemetry data

Overview

The telemetry-router extension helps to monitor notebook states and export telemetry data to the console, local file, or any remote endpoints.

The telemetry router extension provides two methods to the producer extension, loadNotebookPanel and publishEvent.

loadNotebookPanel should be called first when activating the producer extension, to associate the telemetry events with the correct notebook panel before exporting data.

publishEvent could be called whenever we want to publish the event and export telemetry data to the desired endpoints. The publishEvent method takes two arguments, eventDetail: Object and logNotebookContent: Boolean.

There is generally no limitation on the structure of the eventDetail object, as long as the information is wrapped in a serializable javascript object. logNotebookContent is optional and should be a Boolean object. Only if it is provided and is true, the router will send out the entire notebook content along with the event data.

When publishEvent is called, the router checks if the notebook panel is loaded properly, and then insert the notebook session ID, notebook file path, and the notebook content (when logNotebookContent is true) into the data. Then, the router checks the type of each exporter, processes and sends out the data one by one. If env and params are provided in the configuration file when defining the desired exporter, the router would extract the environment variables and add the params to the exported data. Finally, the router will assemble the responses from the exporters in an array and print the response array in the console.

Router Configuration

The telemetry router extension is driven by the configuration file. In this way, users can define exporters easily without touching the extension code.

The jupyterlab-telemetry-router extension provides 3 types of default exporters, console exporter, file exporter and remote exporter.

console exporter logs data in the console.

file exporter logs data into the local file indicated by path.

remote exporter posts data to the remote endpoint indicated by url.

The extension would extract the environment variable for each of the keys presented in env, and add the result to the data when exporting.

The extension would add params directly to data when exporting. This feature is useful when users want to post data to lambda functions and wants to have additional parameters.

Syntax

type and id are required for all exporters.

path is required for file exporters only.

url is required for remote exporters only.

env and params are optional.

When the extension is being activated, a syntax check will be done first. Missing required fields would prevent Jupyter Lab from starting.

Configuration file name & path

Jupyter Server expects the configuration file to be named after the extension’s name like so: jupyter_{extension name defined in application.py}_config.py. In our case, the extension name is defined here. So, the configuration file name is jupyter_jupyterlab_telemetry_router_config.py.

Jupyter Server looks for an extension’s config file in a set of specific paths. The configuration file should be saved into one of the config directories provided by jupyter --path.

For more details, see https://jupyter-server.readthedocs.io/en/latest/operators/configuring-extensions.html.

Example

## in jupyter_jupyterlab_telemetry_router_config.py
c.JupyterLabTelemetryRouterApp.exporters = [
    {
        'type': 'console',
        'id': 'ConsoleExporter',
    },
    {
        'type': 'file',
        'id': 'FileExporter',
        'path': 'log',
    },
    {
        'type': 'remote',
        'id': 'S3Exporter',
        'url': 'https://telemetry.mentoracademy.org/telemetry-edtech-labs-si-umich-edu/dev/test-telemetry',
        'env': ['WORKSPACE_ID']
    }
]

(Optional) Event Producer

There is no specific restrictions on when and where the telemetry router should be invoked. However, when writing complex event producer libraries, we recommend developers write an event producer class for each event, implement a listen() class method, and call the producer's listen() method when the producer extension is being activated. Within the listen() method, you may write the logic of how the extension listens to Jupyter signals or DOM events and how to use the telemetryRouter.publishEvent() function to export telemetry data.

For detailed examples, see https://github.com/educational-technology-collective/telemetry-producer/blob/main/src/events.ts and https://github.com/educational-technology-collective/telemetry-producer/blob/main/src/index.ts#L31.

(Optional) Producer Configuration

Unlike the telemetry router extension, using a configuration file is not required when implementing telemetry producer extensions.

In this telemetry producer demo extension, there is only one event and actually does not need to go through the configuration.

However, writing code on top of the configuration file might be very useful when the event library is complex, and when the telemetry system is going to be deployed under different contexts with different needs of telemetry events.

Configuration file name & path

Jupyter Server expects the configuration file to be named after the extension’s name like so: jupyter_{extension name defined in application.py}_config.py. In our case, the configuration file name is jupyter_jupyterlab_telemetry_producer_demo_config.py.

Jupyter Server looks for an extension’s config file in a set of specific paths. Use jupyter --paths command to list these paths and place the configuration file in any of the paths.

For more details, see https://jupyter-server.readthedocs.io/en/latest/operators/configuring-extensions.html.

Recommended Syntax

We recommend developers to use the following configuration syntax when writing their own telemetry producers.

activateEvents: required. An array of the ids of the events. Only valid event producers (1. has an id associated with the event producer class, and 2. the event id is included in activatedEvents) will be activated.

logNotebookContentEvents: optional. An array of the ids of the events. Only valid event producers (1. has an id associated with the event producer class, and 2. the event id is included in logNotebookContentEvents) will have the router export the entire notebook content along with the event data.

## in jupyter_jupyterlab_telemetry_producer_demo_config.py

c.JupyterLabTelemetryProducerDemoApp.activeEvents = [
    'ClickButtonEvent',
]

c.JupyterLabTelemetryProducerDemoApp.logNotebookContentEvents = [
    'ClickButtonEvent',
]

Troubleshoot

If you are seeing the frontend extension, but it is not working, check that the server extension is enabled:

jupyter server extension list

If the server extension is installed and enabled, but you are not seeing the frontend extension, check the frontend extension is installed:

jupyter labextension list