From 11fd0ba8435e53e6808c4e5b281c48046248da01 Mon Sep 17 00:00:00 2001 From: Canyu Chen Date: Mon, 23 Jun 2025 22:50:28 +0800 Subject: [PATCH 1/7] Add pip installation --- .../README.md | 102 +++++++++++++++++- .../__init__.py | 22 ++++ .../_version.py | 16 +++ .../package.json | 2 +- .../pyproject.toml | 49 +++++++++ 5 files changed, 189 insertions(+), 2 deletions(-) create mode 100644 sdks/python/apache_beam/runners/interactive/extensions/apache-beam-jupyterlab-sidepanel/apache_beam_jupyterlab_sidepanel/__init__.py create mode 100644 sdks/python/apache_beam/runners/interactive/extensions/apache-beam-jupyterlab-sidepanel/apache_beam_jupyterlab_sidepanel/_version.py create mode 100644 sdks/python/apache_beam/runners/interactive/extensions/apache-beam-jupyterlab-sidepanel/pyproject.toml diff --git a/sdks/python/apache_beam/runners/interactive/extensions/apache-beam-jupyterlab-sidepanel/README.md b/sdks/python/apache_beam/runners/interactive/extensions/apache-beam-jupyterlab-sidepanel/README.md index 2a6cd9f34aae..f8297165ed11 100644 --- a/sdks/python/apache_beam/runners/interactive/extensions/apache-beam-jupyterlab-sidepanel/README.md +++ b/sdks/python/apache_beam/runners/interactive/extensions/apache-beam-jupyterlab-sidepanel/README.md @@ -29,14 +29,57 @@ Includes two different side panels: | v3 | v2.0.0-v3.0.0 | | v2 | v1.0.0 | -## Install +## Installation + +There are two ways to install the extension: + +### 1. Via pip (recommended) + +The extension is now available as a Python package on PyPI. +Install it with: + +```bash +pip install apache-beam-jupyterlab-sidepanel +``` + +After installation, rebuild JupyterLab to activate the extension: + +```bash +jupyter lab clean +jupyter lab build +``` + +Then restart JupyterLab. The side panels will be available automatically. + + +### 2. Via JupyterLab Extension Manager (legacy, will be deprecated soon) ```bash jupyter labextension install apache-beam-jupyterlab-sidepanel ``` +This installs the extension using JupyterLab's legacy extension system. + +--- + +## Notes + +- Pip installation is now the preferred method as it handles Python packaging and JupyterLab extension registration seamlessly. +- After any upgrade or reinstallation, always rebuild JupyterLab to ensure the extension is activated. +- For detailed usage and development, refer to the source code and issues on [GitHub](https://github.com/apache/beam). + +--- + ## Contributing +> **Note**: When creating a Python package, the **module name (i.e., the folder name and import path)** must use underscores (`_`) instead of dashes (`-`). Dashes are **not allowed** in Python identifiers. +> However, the **distribution name** (the name used in `pip install ...`) **can** include dashes, and this is a common convention in the Python ecosystem. +> For example: +> +> - `pip install apache-beam-jupyterlab-sidepanel` ✅ +> - `import apache_beam_jupyterlab_sidepanel` ✅ +> - `import apache-beam-jupyterlab-sidepanel` ❌ (invalid syntax) + ### Install The `jlpm` command is JupyterLab's pinned version of @@ -117,8 +160,65 @@ jlpm eslint:check jlpm eslint ``` +### Packaging + +This JupyterLab extension is distributed as a prebuilt Python package, and includes all necessary frontend assets (TypeScript-compiled JavaScript, styles, and metadata). + +#### Build from source + +To build the extension locally and package it into a wheel: + +```bash +# Ensure build dependencies are available +pip install build jupyterlab jupyter_packaging hatch + +# Build the wheel and source tarball +hatch build +``` + +This will generate `dist/*.whl` and `dist/*.tar.gz` files. + +#### Install locally via pip + +```bash +pip install . +``` + +After installation, JupyterLab will automatically discover and enable the extension. You can verify it was installed via: + +```bash +jupyter labextension list +``` + +If properly installed, your extension should appear under the `prebuilt extensions` section. + +#### File layout expectations + +A typical prebuilt extension should include the following structure under your Python package: + +``` +apache_beam_jupyterlab_sidepanel/ +├── __init__.py +├── _version.py +└── labextension/ + ├── package.json + ├── install.json + └── static/ + └── ... +``` + +These will be copied to: + +``` +$PREFIX/share/jupyter/labextensions/apache-beam-jupyterlab-sidepanel/ +``` + ### Uninstall ```bash jupyter labextension uninstall apache-beam-jupyterlab-sidepanel ``` +or +```bash +pip uninstall apache-beam-jupyterlab-sidepanel +``` \ No newline at end of file diff --git a/sdks/python/apache_beam/runners/interactive/extensions/apache-beam-jupyterlab-sidepanel/apache_beam_jupyterlab_sidepanel/__init__.py b/sdks/python/apache_beam/runners/interactive/extensions/apache-beam-jupyterlab-sidepanel/apache_beam_jupyterlab_sidepanel/__init__.py new file mode 100644 index 000000000000..9636a0962da3 --- /dev/null +++ b/sdks/python/apache_beam/runners/interactive/extensions/apache-beam-jupyterlab-sidepanel/apache_beam_jupyterlab_sidepanel/__init__.py @@ -0,0 +1,22 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from ._version import __version__ + +def _jupyter_labextension_paths(): + return [{ + "src": "labextension", + "dest": "apache-beam-jupyterlab-sidepanel" + }] \ No newline at end of file diff --git a/sdks/python/apache_beam/runners/interactive/extensions/apache-beam-jupyterlab-sidepanel/apache_beam_jupyterlab_sidepanel/_version.py b/sdks/python/apache_beam/runners/interactive/extensions/apache-beam-jupyterlab-sidepanel/apache_beam_jupyterlab_sidepanel/_version.py new file mode 100644 index 000000000000..cb2bf55994e4 --- /dev/null +++ b/sdks/python/apache_beam/runners/interactive/extensions/apache-beam-jupyterlab-sidepanel/apache_beam_jupyterlab_sidepanel/_version.py @@ -0,0 +1,16 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +__version__ = "4.0.0" \ No newline at end of file diff --git a/sdks/python/apache_beam/runners/interactive/extensions/apache-beam-jupyterlab-sidepanel/package.json b/sdks/python/apache_beam/runners/interactive/extensions/apache-beam-jupyterlab-sidepanel/package.json index 3905e5fb2c60..8b51461f6cd4 100644 --- a/sdks/python/apache_beam/runners/interactive/extensions/apache-beam-jupyterlab-sidepanel/package.json +++ b/sdks/python/apache_beam/runners/interactive/extensions/apache-beam-jupyterlab-sidepanel/package.json @@ -92,7 +92,7 @@ ], "jupyterlab": { "extension": true, - "outputDir": "apache-beam-jupyterlab-sidepanel/labextension" + "outputDir": "apache_beam_jupyterlab_sidepanel/labextension" }, "test": "jest", "resolutions": { diff --git a/sdks/python/apache_beam/runners/interactive/extensions/apache-beam-jupyterlab-sidepanel/pyproject.toml b/sdks/python/apache_beam/runners/interactive/extensions/apache-beam-jupyterlab-sidepanel/pyproject.toml new file mode 100644 index 000000000000..b9723b89d2de --- /dev/null +++ b/sdks/python/apache_beam/runners/interactive/extensions/apache-beam-jupyterlab-sidepanel/pyproject.toml @@ -0,0 +1,49 @@ +[build-system] +requires = [ + "hatchling>=1.5.0", + "jupyterlab>=4.0.0,<5", + "hatch-nodejs-version>=0.3.2", +] +build-backend = "hatchling.build" + +[project] +name = "apache_beam_jupyterlab_sidepanel" +version = "4.0.0" +description = "JupyterLab Sidepanel for Apache Beam" +readme = "README.md" +requires-python = ">=3.9" +license = { text = "Apache-2.0" } +authors = [{ name = "Apache Beam", email = "dev@beam.apache.org" }] +classifiers = [ + "Framework :: Jupyter", + "Framework :: Jupyter :: JupyterLab", + "Framework :: Jupyter :: JupyterLab :: 4", + "License :: OSI Approved :: Apache Software License", + "Programming Language :: Python :: 3", +] +dependencies = ["jupyterlab>=4.0.0,<5", "jupyter_server>=2.0.0"] + +[tool.hatch.version] +source = "nodejs" + +[tool.hatch.build.targets.sdist] +artifacts = ["apache_beam_jupyterlab_sidepanel/labextension"] + +[tool.hatch.build.targets.wheel.shared-data] +"apache_beam_jupyterlab_sidepanel/labextension" = "share/jupyter/labextensions/apache-beam-jupyterlab-sidepanel" +"install.json" = "share/jupyter/labextensions/apache-beam-jupyterlab-sidepanel/install.json" + +[tool.hatch.build.hooks.jupyter-builder] +dependencies = ["hatch-jupyter-builder>=0.5"] +build-function = "hatch_jupyter_builder.npm_builder" +ensured-targets = [ + "apache_beam_jupyterlab_sidepanel/labextension/static/style.js", + "apache_beam_jupyterlab_sidepanel/labextension/package.json", +] +build-kwargs = { build_cmd = "build:prod", npm = ["jlpm"] } +editable-build-kwargs = { build_cmd = "install:extension", npm = [ + "jlpm", +], source_dir = "src", build_dir = "apache_beam_jupyterlab_sidepanel/labextension" } + +[tool.jupyter-releaser.options] +version_cmd = "hatch version" From 5c81f81211fedb6dac64888c9d4187f3d8984e05 Mon Sep 17 00:00:00 2001 From: Canyu Chen Date: Mon, 23 Jun 2025 22:57:12 +0800 Subject: [PATCH 2/7] update CHANGES.md --- CHANGES.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGES.md b/CHANGES.md index c2c0934cb1d8..7826c25922b3 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -74,6 +74,7 @@ ## New Features / Improvements * X feature added (Java/Python) ([#X](https://github.com/apache/beam/issues/X)). +* Add pip-based install support for JupyterLab Sidepanel extension ([#35397](https://github.com/apache/beam/issues/#35397)). ## Breaking Changes From 73bdc13dada8686d2eade43926973df643263850 Mon Sep 17 00:00:00 2001 From: Canyu Chen Date: Mon, 23 Jun 2025 23:06:34 +0800 Subject: [PATCH 3/7] Add license --- .../pyproject.toml | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/sdks/python/apache_beam/runners/interactive/extensions/apache-beam-jupyterlab-sidepanel/pyproject.toml b/sdks/python/apache_beam/runners/interactive/extensions/apache-beam-jupyterlab-sidepanel/pyproject.toml index b9723b89d2de..e7ec2475b466 100644 --- a/sdks/python/apache_beam/runners/interactive/extensions/apache-beam-jupyterlab-sidepanel/pyproject.toml +++ b/sdks/python/apache_beam/runners/interactive/extensions/apache-beam-jupyterlab-sidepanel/pyproject.toml @@ -1,3 +1,18 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + [build-system] requires = [ "hatchling>=1.5.0", From 80a461af6313a2437d4482f54c8128a24591626d Mon Sep 17 00:00:00 2001 From: Chenzo <120361592+Chenzo1001@users.noreply.github.com> Date: Tue, 24 Jun 2025 10:56:51 +0800 Subject: [PATCH 4/7] update format --- .../apache-beam-jupyterlab-sidepanel/README.md | 11 +++++------ .../apache_beam_jupyterlab_sidepanel/__init__.py | 6 ++---- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/sdks/python/apache_beam/runners/interactive/extensions/apache-beam-jupyterlab-sidepanel/README.md b/sdks/python/apache_beam/runners/interactive/extensions/apache-beam-jupyterlab-sidepanel/README.md index f8297165ed11..9c876bde8c3d 100644 --- a/sdks/python/apache_beam/runners/interactive/extensions/apache-beam-jupyterlab-sidepanel/README.md +++ b/sdks/python/apache_beam/runners/interactive/extensions/apache-beam-jupyterlab-sidepanel/README.md @@ -35,8 +35,7 @@ There are two ways to install the extension: ### 1. Via pip (recommended) -The extension is now available as a Python package on PyPI. -Install it with: +The extension is now available as a Python package on PyPI. You can install it with: ```bash pip install apache-beam-jupyterlab-sidepanel @@ -72,12 +71,12 @@ This installs the extension using JupyterLab's legacy extension system. ## Contributing -> **Note**: When creating a Python package, the **module name (i.e., the folder name and import path)** must use underscores (`_`) instead of dashes (`-`). Dashes are **not allowed** in Python identifiers. -> However, the **distribution name** (the name used in `pip install ...`) **can** include dashes, and this is a common convention in the Python ecosystem. +> **Note**: When creating a Python package, the **module name (i.e., the folder name and import path)** must use underscores (`_`) instead of dashes (`-`). Dashes are **not allowed** in Python identifiers. +> However, the **distribution name** (the name used in `pip install ...`) **can** include dashes, and this is a common convention in the Python ecosystem. > For example: > -> - `pip install apache-beam-jupyterlab-sidepanel` ✅ -> - `import apache_beam_jupyterlab_sidepanel` ✅ +> - `pip install apache-beam-jupyterlab-sidepanel` ✅ +> - `import apache_beam_jupyterlab_sidepanel` ✅ > - `import apache-beam-jupyterlab-sidepanel` ❌ (invalid syntax) ### Install diff --git a/sdks/python/apache_beam/runners/interactive/extensions/apache-beam-jupyterlab-sidepanel/apache_beam_jupyterlab_sidepanel/__init__.py b/sdks/python/apache_beam/runners/interactive/extensions/apache-beam-jupyterlab-sidepanel/apache_beam_jupyterlab_sidepanel/__init__.py index 9636a0962da3..a8232d31dc2a 100644 --- a/sdks/python/apache_beam/runners/interactive/extensions/apache-beam-jupyterlab-sidepanel/apache_beam_jupyterlab_sidepanel/__init__.py +++ b/sdks/python/apache_beam/runners/interactive/extensions/apache-beam-jupyterlab-sidepanel/apache_beam_jupyterlab_sidepanel/__init__.py @@ -15,8 +15,6 @@ from ._version import __version__ + def _jupyter_labextension_paths(): - return [{ - "src": "labextension", - "dest": "apache-beam-jupyterlab-sidepanel" - }] \ No newline at end of file + return [{"src": "labextension", "dest": "apache-beam-jupyterlab-sidepanel"}] \ No newline at end of file From 263a3fee579776817f0bd16bdd4c447cf48052bc Mon Sep 17 00:00:00 2001 From: Chenzo <120361592+Chenzo1001@users.noreply.github.com> Date: Tue, 24 Jun 2025 11:16:44 +0800 Subject: [PATCH 5/7] Fix whitspace problem --- .../extensions/apache-beam-jupyterlab-sidepanel/README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/sdks/python/apache_beam/runners/interactive/extensions/apache-beam-jupyterlab-sidepanel/README.md b/sdks/python/apache_beam/runners/interactive/extensions/apache-beam-jupyterlab-sidepanel/README.md index 9c876bde8c3d..83fddf491f68 100644 --- a/sdks/python/apache_beam/runners/interactive/extensions/apache-beam-jupyterlab-sidepanel/README.md +++ b/sdks/python/apache_beam/runners/interactive/extensions/apache-beam-jupyterlab-sidepanel/README.md @@ -74,7 +74,6 @@ This installs the extension using JupyterLab's legacy extension system. > **Note**: When creating a Python package, the **module name (i.e., the folder name and import path)** must use underscores (`_`) instead of dashes (`-`). Dashes are **not allowed** in Python identifiers. > However, the **distribution name** (the name used in `pip install ...`) **can** include dashes, and this is a common convention in the Python ecosystem. > For example: -> > - `pip install apache-beam-jupyterlab-sidepanel` ✅ > - `import apache_beam_jupyterlab_sidepanel` ✅ > - `import apache-beam-jupyterlab-sidepanel` ❌ (invalid syntax) @@ -220,4 +219,4 @@ jupyter labextension uninstall apache-beam-jupyterlab-sidepanel or ```bash pip uninstall apache-beam-jupyterlab-sidepanel -``` \ No newline at end of file +``` From 2d6f34ab79a046eceb1299d66724a5459a229cf0 Mon Sep 17 00:00:00 2001 From: Chenzo <120361592+Chenzo1001@users.noreply.github.com> Date: Tue, 24 Jun 2025 13:26:31 +0800 Subject: [PATCH 6/7] Fix isort problem --- .../apache_beam_jupyterlab_sidepanel/_version.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sdks/python/apache_beam/runners/interactive/extensions/apache-beam-jupyterlab-sidepanel/apache_beam_jupyterlab_sidepanel/_version.py b/sdks/python/apache_beam/runners/interactive/extensions/apache-beam-jupyterlab-sidepanel/apache_beam_jupyterlab_sidepanel/_version.py index cb2bf55994e4..00c00372be30 100644 --- a/sdks/python/apache_beam/runners/interactive/extensions/apache-beam-jupyterlab-sidepanel/apache_beam_jupyterlab_sidepanel/_version.py +++ b/sdks/python/apache_beam/runners/interactive/extensions/apache-beam-jupyterlab-sidepanel/apache_beam_jupyterlab_sidepanel/_version.py @@ -1,3 +1,5 @@ +# isort: skip_file + # Licensed to the Apache Software Foundation (ASF) under one or more # contributor license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright ownership. @@ -13,4 +15,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "4.0.0" \ No newline at end of file +__version__ = "4.0.0" From b1856645a936777f7a45bdb6b7a191dc19ae889f Mon Sep 17 00:00:00 2001 From: Canyu Chen Date: Wed, 25 Jun 2025 12:56:38 +0800 Subject: [PATCH 7/7] update ignore rules --- .../extensions/apache-beam-jupyterlab-sidepanel/.gitignore | 6 ++++++ .../apache-beam-jupyterlab-sidepanel/pyproject.toml | 3 +++ 2 files changed, 9 insertions(+) create mode 100644 sdks/python/apache_beam/runners/interactive/extensions/apache-beam-jupyterlab-sidepanel/.gitignore diff --git a/sdks/python/apache_beam/runners/interactive/extensions/apache-beam-jupyterlab-sidepanel/.gitignore b/sdks/python/apache_beam/runners/interactive/extensions/apache-beam-jupyterlab-sidepanel/.gitignore new file mode 100644 index 000000000000..477cc2893fe9 --- /dev/null +++ b/sdks/python/apache_beam/runners/interactive/extensions/apache-beam-jupyterlab-sidepanel/.gitignore @@ -0,0 +1,6 @@ +.yarn/ +apache_beam_jupyterlab_sidepanel/labextension/ +lib/ +tsconfig.tsbuildinfo +node_modules/ +dist/ \ No newline at end of file diff --git a/sdks/python/apache_beam/runners/interactive/extensions/apache-beam-jupyterlab-sidepanel/pyproject.toml b/sdks/python/apache_beam/runners/interactive/extensions/apache-beam-jupyterlab-sidepanel/pyproject.toml index e7ec2475b466..6831535a2c1e 100644 --- a/sdks/python/apache_beam/runners/interactive/extensions/apache-beam-jupyterlab-sidepanel/pyproject.toml +++ b/sdks/python/apache_beam/runners/interactive/extensions/apache-beam-jupyterlab-sidepanel/pyproject.toml @@ -41,6 +41,9 @@ dependencies = ["jupyterlab>=4.0.0,<5", "jupyter_server>=2.0.0"] [tool.hatch.version] source = "nodejs" +[tool.hatch.build] +exclude = [".yarn/", "lib/", "node_modules/", "dist/", "tsconfig.tsbuildinfo"] + [tool.hatch.build.targets.sdist] artifacts = ["apache_beam_jupyterlab_sidepanel/labextension"]