Repository: jupyter/echo_kernel (language: python)

Issue:
is the install.py script still relevant given data_files support in `setup.py`?
Hi there,

Thank you for creating this reference custom kernel!

Through some investigations, I thought that the recommended path is to use data_files support in `setup.py`, as opposed to manually moving files into the `share/jupyter/kernels/` directory. I also noticed that the `kernel.json` pattern (mentioned in https://jupyter-client.readthedocs.io/en/stable/kernels.html) is not used here.

Is this current repo not up to date with the most recent ipykernel developments, or did I mis-read some instructions?

Thanks so much for the help!


Discussion / hints:
I agree @yifanwu as far as I can tell this no longer installs correctly.  Am I missing something here, or are the Jupyter docs out of sync with the committed code and both out of sync with the demo repos?

I've tried with v1.1, using Py 3.10.11 on macOS:

```
IPython          : 8.22.1
ipykernel        : 6.29.3
ipywidgets       : not installed
jupyter_client   : 8.6.0
jupyter_core     : 5.7.1
jupyter_server   : 2.12.5
jupyterlab       : 4.1.2
nbclient         : 0.9.0
nbconvert        : 7.16.1
nbformat         : 5.9.2
notebook         : not installed
qtconsole        : not installed
traitlets        : 5.14.1
```
The echo kernel is using [hatch](https://github.com/jupyter/echo_kernel/blob/b483ceb1b50425bf37157ddc1e0f338e21917647/pyproject.toml#L50) to install the kernel, which works on PyPI and conda-forge. install.py is still there but could be removed, simplified, and absorbed into [jupyter/echo_kernel@main/hatch_build.py](https://github.com/jupyter/echo_kernel/blob/main/hatch_build.py?rgh-link-date=2024-03-02T22%3A13%3A09Z).

Fix patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index ee9292d..616f2fc 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,4 +1,4 @@
-# Changes in jupyter-core
+# Changes in echo kernel
 
 <!-- <START NEW CHANGELOG ENTRY> -->
 
diff --git a/echo_kernel/install.py b/echo_kernel/install.py
deleted file mode 100644
index e0592dd..0000000
--- a/echo_kernel/install.py
+++ /dev/null
@@ -1,59 +0,0 @@
-import argparse
-import json
-import os
-import sys
-import shutil
-
-from jupyter_client.kernelspec import KernelSpecManager
-from tempfile import TemporaryDirectory
-
-kernel_json = {
-    "argv": [sys.executable, "-m", "echo_kernel", "-f", "{connection_file}"],
-    "display_name": "Echo",
-    "language": "text",
-}
-
-
-def install_my_kernel_spec(user=True, prefix=None):
-    with TemporaryDirectory() as td:
-        os.chmod(td, 0o755) # Starts off as 700, not user readable
-        with open(os.path.join(td, 'kernel.json'), 'w') as f:
-            json.dump(kernel_json, f, sort_keys=True)
-        print('Installing Jupyter kernel spec')
-        # requires logo files in kernel root directory
-        cur_path = os.path.dirname(os.path.realpath(__file__))
-        for logo in ["logo-32x32.png", "logo-64x64.png"]:
-            try:
-                shutil.copy(os.path.join(cur_path, logo), td)
-            except FileNotFoundError:
-                print("Custom logo files not found. Default logos will be used.")
-        
-        KernelSpecManager().install_kernel_spec(td, 'echo', user=user, prefix=prefix)
-
-
-def _is_root():
-    try:
-        return os.geteuid() == 0
-    except AttributeError:
-        return False # assume not an admin on non-Unix platforms
-
-def main(argv=None):
-    ap = argparse.ArgumentParser()
-    ap.add_argument('--user', action='store_true',
-        help="Install to the per-user kernels registry. Default if not root.")
-    ap.add_argument('--sys-prefix', action='store_true',
-        help="Install to sys.prefix (e.g. a virtualenv or conda env)")
-    ap.add_argument('--prefix',
-        help="Install to the given prefix. "
-             "Kernelspec will be installed in {PREFIX}/share/jupyter/kernels/")
-    args = ap.parse_args(argv)
-
-    if args.sys_prefix:
-        args.prefix = sys.prefix
-    if not args.prefix and not _is_root():
-        args.user = True
-
-    install_my_kernel_spec(user=args.user, prefix=args.prefix)
-
-if __name__ == '__main__':
-    main()
diff --git a/hatch_build.py b/hatch_build.py
index 4616a4d..2ed5700 100644
--- a/hatch_build.py
+++ b/hatch_build.py
@@ -3,13 +3,40 @@
 from hatchling.builders.hooks.plugin.interface import BuildHookInterface
 
 
+import argparse
+import json
+import os
+import sys
+import shutil
+
+from jupyter_client.kernelspec import KernelSpecManager
+from tempfile import TemporaryDirectory
+
+kernel_json = {
+    "argv": [sys.executable, "-m", "echo_kernel", "-f", "{connection_file}"],
+    "display_name": "Echo",
+    "language": "text",
+}
+
 class CustomHook(BuildHookInterface):
     def initialize(self, version, build_data):
         here = os.path.abspath(os.path.dirname(__file__))
         sys.path.insert(0, here)
+        prefix = os.path.join(here, 'data_kernelspec')
 
-        from echo_kernel.install import install_my_kernel_spec
+        with TemporaryDirectory() as td:
+            os.chmod(td, 0o755) # Starts off as 700, not user readable
+            with open(os.path.join(td, 'kernel.json'), 'w') as f:
+                json.dump(kernel_json, f, sort_keys=True)
+            print('Installing Jupyter kernel spec')
 
-        prefix = os.path.join(here, 'data_kernelspec')
-        install_my_kernel_spec(False, prefix)
+            # Requires logo files in kernel root directory
+            cur_path = os.path.dirname(os.path.realpath(__file__))
+            for logo in ["logo-32x32.png", "logo-64x64.png"]:
+                try:
+                    shutil.copy(os.path.join(cur_path, logo), td)
+                except FileNotFoundError:
+                    print("Custom logo files not found. Default logos will be used.")
+
+            KernelSpecManager().install_kernel_spec(td, 'echo', user=False, prefix=prefix)
 


Test patch:
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index c2b989d..a488ec6 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -23,14 +23,14 @@ jobs:
       fail-fast: false
       matrix:
         os: [ubuntu-latest, windows-latest, macos-latest]
-        python-version: ["3.8", "3.11"]
+        python-version: ["3.8", "3.12"]
         include:
           - os: windows-latest
-            python-version: "3.9"
+            python-version: "3.10"
           - os: ubuntu-latest
-            python-version: "pypy-3.8"
+            python-version: "pypy-3.9"
           - os: macos-latest
-            python-version: "3.10"
+            python-version: "3.11"
     steps:
       - uses: actions/checkout@v2
       - uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1
@@ -44,9 +44,6 @@ jobs:
         run: |
           cd $HOME
           jupyter kernelspec list | grep echo
-          jupyter kernelspec remove -y echo
-          python -m echo_kernel.install
-          jupyter kernelspec list | grep echo
 
   check_release:
     runs-on: ubuntu-latest