Skip to content

Added provider-consumer example (multiple related packages). #245

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

Open
wants to merge 32 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
3e2dfa5
Initial provider-consumer sample, WIP.
ericsnekbytes Aug 31, 2023
7442fe6
Fixed method name.
ericsnekbytes Aug 31, 2023
0c731cf
Added comments to the provider-consumer samples.
ericsnekbytes Sep 1, 2023
f3fe812
Added comments to provider/consumer example.
ericsnekbytes Sep 1, 2023
14350de
Comment cleanup.
ericsnekbytes Sep 1, 2023
2eb6512
Minor formatting.
ericsnekbytes Sep 1, 2023
9d115b5
Updated project description text.
ericsnekbytes Sep 1, 2023
03f9cc9
Updated project description text.
ericsnekbytes Sep 1, 2023
de11b88
Minor formatting.
ericsnekbytes Sep 1, 2023
7a5c3c0
Minor formatting.
ericsnekbytes Sep 1, 2023
82d1ad5
Added third provider-consumer sub example, an additional consumer.
ericsnekbytes Sep 1, 2023
76438b9
Added step counter signal for display updates.
ericsnekbytes Sep 26, 2023
c086518
Update readme
ericsnekbytes Sep 28, 2023
e46c5b9
Renamed folders to match poackage names.
ericsnekbytes Sep 28, 2023
9645adf
Updated local dependency paths.
ericsnekbytes Sep 28, 2023
8bab7f7
Updated extension specific READMEs.
ericsnekbytes Sep 28, 2023
44238f1
Added preview, updated README.
ericsnekbytes Sep 28, 2023
efbe9a2
Added singleton package metadata notes.
ericsnekbytes Sep 28, 2023
8b3872c
Update README/fix links.
ericsnekbytes Sep 29, 2023
afee7d7
Updated titles/links.
ericsnekbytes Sep 29, 2023
e1a5525
Update titles/links in READMEs.
ericsnekbytes Sep 29, 2023
2689a44
Updated root package metadata.
ericsnekbytes Oct 2, 2023
164b0ad
Merge branch 'main' into provider_consumer_example
ericsnekbytes Jan 24, 2024
b1452cd
Workaround for dependency 'any' usage and version conflicts.
ericsnekbytes Jun 9, 2025
e420ec7
Linting.
ericsnekbytes Jun 9, 2025
ea8a711
Fix linting errors for unrelated packages.
ericsnekbytes Jun 9, 2025
626490b
Modify tsconfigs: Re-enable implicit any checks, add skipLibCheck.
ericsnekbytes Jun 9, 2025
bfb24cc
Extra linting.
ericsnekbytes Jun 9, 2025
cb58d6c
Revised to address feedback.
ericsnekbytes Jun 9, 2025
101cfd6
Added explanation of declaration merging.
ericsnekbytes Jun 9, 2025
1e56e65
Add changes from PR feedback.
ericsnekbytes Jun 9, 2025
7b0f58e
Add updated version of entities with types.
ericsnekbytes Jun 10, 2025
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
3 changes: 3 additions & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ jobs:
- launcher
- kernel-messaging
- kernel-output
- leap_counter_extension
- log-messages
- main-menu
- metadata-form
Expand All @@ -38,6 +39,8 @@ jobs:
- shout-button-message
- signals
- state
- step_counter
- step_counter_extension
- toolbar-button
- toparea-text-widget
- widgets
Expand Down
39 changes: 39 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,14 @@
1. [Kernel Messaging](#kernel-messaging)
1. [Kernel Output](#kernel-output)
1. [Launcher](#launcher)
1. [Leap Counter (Reusability 1C)](#leap-counter-reusability-1c)
1. [Log Messages](#log-messages)
1. [Main Menu](#main-menu)
1. [Metadata Form](#metadata-form)
1. [MIME Renderer](#mime-renderer)
1. [Notifications](#notifications)
1. [Step Counter (Reusability 1A)](#step-counter-reusability-1a)
1. [Step Counter Extension (Reusability 1B)](#step-counter-extension-reusability-1b)
1. [React Widget](#react-widget)
1. _[Server Hello World](#server-hello-world)_
1. [Settings](#settings)
Expand Down Expand Up @@ -114,6 +117,7 @@ Start with the [Hello World](hello-world) and then jump to the topic you are int
- [Kernel Messaging](kernel-messaging)
- [Kernel Output](kernel-output)
- [Launcher](launcher)
- [Leap Counter](leap_counter_extension)
- [Log Messages](log-messages)
- [Main Menu](main-menu)
- [Metadata Form](metadata-form)
Expand All @@ -123,6 +127,8 @@ Start with the [Hello World](hello-world) and then jump to the topic you are int
- [Server Hello World](server-extension)
- [Settings](settings)
- [Signals](signals)
- [Step Counter (Reusability 1A)](step_counter)
- [Step Counter Extension (Reusability 1B)](step_counter_extension)
- [State](state)
- [Toolbar item](toolbar-button)
- [Widgets](widgets)
Expand Down Expand Up @@ -262,6 +268,17 @@ Start your extension from the Launcher.

[![Launcher](launcher/preview.gif)](launcher)

### [Leap Counter (Reusability 1C)](leap_counter_extension)

Create your own reusable plugin components with Jupyter's "Provider-
Consumer Pattern". This is one of three related extension examples
that demonstrate JupyterLab's provider-consumer pattern, where plugins
can depend on and reuse features from one another. The three packages
that make up the complete example are "step_counter", "step_counter_extension",
and "leap_counter_extension".

[![Leap counter extension](step_counter/preview.png)](leap_counter_extension)

### [Log Messages](log-messages)

Send a log message to the log console.
Expand Down Expand Up @@ -316,6 +333,28 @@ Use Signals to allow Widgets communicate with each others.

[![Button with Signal](signals/preview.png)](signals)

### [Step Counter (Reusability 1A)](step_counter)

Create your own reusable plugin components with Jupyter's "Provider-
Consumer Pattern". This is one of three related extension examples
that demonstrate JupyterLab's provider-consumer pattern, where plugins
can depend on and reuse features from one another. The three packages
that make up the complete example are "step_counter", "step_counter_extension",
and "leap_counter_extension".

[![Step counter](step_counter/preview.png)](step_counter)

### [Step Counter Extension (Reusability 1B)](step_counter_extension)

Create your own reusable plugin components with Jupyter's "Provider-
Consumer Pattern". This is one of three related extension examples
that demonstrate JupyterLab's provider-consumer pattern, where plugins
can depend on and reuse features from one another. The three packages
that make up the complete example are "step_counter", "step_counter_extension",
and "leap_counter_extension".

[![Step counter extension](step_counter/preview.png)](step_counter_extension)

### [State](state)

Use State persistence in an extension.
Expand Down
5 changes: 3 additions & 2 deletions context-menu/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,9 @@ const extension: JupyterFrontEndPlugin<void> = {
caption: "Example context menu button for file browser's items.",
icon: buildIcon,
execute: () => {
const file = factory.tracker.currentWidget?.selectedItems().next()
.value;
const file = factory.tracker.currentWidget
?.selectedItems()
.next().value;

if (file) {
showDialog({
Expand Down
2 changes: 1 addition & 1 deletion documents/src/model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -395,7 +395,7 @@ export class ExampleDoc extends YDocument<ExampleDocChange> {
? data
? JSON.parse(data)
: { x: 0, y: 0 }
: data ?? '';
: (data ?? '');
}

/**
Expand Down
15 changes: 15 additions & 0 deletions leap_counter_extension/.copier-answers.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Changes here will be overwritten by Copier; NEVER EDIT MANUALLY
_commit: v4.2.0
_src_path: https://github.com/jupyterlab/extension-template
author_email: [email protected]
author_name: My Name
has_binder: false
has_settings: false
kind: frontend
labextension_name: leap_counter_extension
project_short_description: Adds a leap counter/button (1 of 3 related examples). This
extension holds the UI/interface.
python_name: leap_counter_extension
repository: ''
test: true

125 changes: 125 additions & 0 deletions leap_counter_extension/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
*.bundle.*
lib/
node_modules/
*.log
.eslintcache
.stylelintcache
*.egg-info/
.ipynb_checkpoints
*.tsbuildinfo
leap_counter_extension/labextension
# Version file is handled by hatchling
leap_counter_extension/_version.py

# Integration tests
ui-tests/test-results/
ui-tests/playwright-report/

# Created by https://www.gitignore.io/api/python
# Edit at https://www.gitignore.io/?templates=python

### Python ###
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class

# C extensions
*.so

# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
pip-wheel-metadata/
share/python-wheels/
.installed.cfg
*.egg
MANIFEST

# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec

# Installer logs
pip-log.txt
pip-delete-this-directory.txt

# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage/
coverage.xml
*.cover
.hypothesis/
.pytest_cache/

# Translations
*.mo
*.pot

# Scrapy stuff:
.scrapy

# Sphinx documentation
docs/_build/

# PyBuilder
target/

# pyenv
.python-version

# celery beat schedule file
celerybeat-schedule

# SageMath parsed files
*.sage.py

# Spyder project settings
.spyderproject
.spyproject

# Rope project settings
.ropeproject

# Mr Developer
.mr.developer.cfg
.project
.pydevproject

# mkdocs documentation
/site

# mypy
.mypy_cache/
.dmypy.json
dmypy.json

# Pyre type checker
.pyre/

# End of https://www.gitignore.io/api/python

# OSX files
.DS_Store

# Yarn cache
.yarn/
6 changes: 6 additions & 0 deletions leap_counter_extension/.prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
node_modules
**/node_modules
**/lib
**/package.json
!/package.json
leap_counter_extension
1 change: 1 addition & 0 deletions leap_counter_extension/.yarnrc.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
nodeLinker: node-modules
Empty file added leap_counter_extension/LICENSE
Empty file.
32 changes: 32 additions & 0 deletions leap_counter_extension/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Leap Counter (Reusability 1C) (leap_counter_extension)

This multi-part example comes from the [Jupyter Plugin System guide](https://jupyterlab.readthedocs.io/en/latest/extension/plugin_system.html),
and demonstrates Jupyter's provider/consumer pattern. You can find
details about this example on that page.

This is one of three related extension examples that demonstrate
JupyterLab's provider-consumer pattern, where plugins can depend
on and reuse features from one another. The three packages that
make up the complete example are:

1. The step_counter package. This package holds a token, a
class + an interface that make up a stock implementation of
the "step_counter" service, and a provider plugin that
makes an instance of the Counter available to JupyterLab
as a service object.

2. The step_counter_extension package, that holds a
UI/interface in JupyterLab for users to count their steps that
connects with/consumes the step_counter service object via a
consumer plugin.

3. (\*) The leap_counter_extension package (this one), that holds an alternate
way for users to count steps (a leap is 5 steps). Like the step_counter_extension
package, this holds a UI/interface in JupyterLab, and a consumer
plugin that also requests/consumes the step_counter service
object. The leap_counter_extension package demonstrates how
an unrelated plugin can depend on and reuse features from
an existing plugin. Users can install either the
step_counter_extension, the leap_counter_extension or both
to get whichever features they prefer (with both reusing
the step_counter service object).
1 change: 1 addition & 0 deletions leap_counter_extension/babel.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module.exports = require('@jupyterlab/testutils/lib/babel.config');
5 changes: 5 additions & 0 deletions leap_counter_extension/install.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"packageManager": "python",
"packageName": "leap_counter_extension",
"uninstallInstructions": "Use your Python package manager (pip, conda, etc.) to uninstall the package leap_counter_extension"
}
28 changes: 28 additions & 0 deletions leap_counter_extension/jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
const jestJupyterLab = require('@jupyterlab/testutils/lib/jest-config');

const esModules = [
'@codemirror',
'@jupyter/ydoc',
'@jupyterlab/',
'lib0',
'nanoid',
'vscode-ws-jsonrpc',
'y-protocols',
'y-websocket',
'yjs'
].join('|');

const baseConfig = jestJupyterLab(__dirname);

module.exports = {
...baseConfig,
automock: false,
collectCoverageFrom: [
'src/**/*.{ts,tsx}',
'!src/**/*.d.ts',
'!src/**/.ipynb_checkpoints/*'
],
coverageReporters: ['lcov', 'text'],
testRegex: 'src/.*/.*.spec.ts[x]?$',
transformIgnorePatterns: [`/node_modules/(?!${esModules}).+`]
};
16 changes: 16 additions & 0 deletions leap_counter_extension/leap_counter_extension/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
try:
from ._version import __version__
except ImportError:
# Fallback when using the package in dev mode without installing
# in editable mode with pip. It is highly recommended to install
# the package from a stable release or in editable mode: https://pip.pypa.io/en/stable/topics/local-project-installs/#editable-installs
import warnings
warnings.warn("Importing 'leap_counter_extension' outside a proper installation.")
__version__ = "dev"


def _jupyter_labextension_paths():
return [{
"src": "labextension",
"dest": "leap_counter_extension"
}]
Loading
Loading