Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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 Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ all: $(NOTEBOOK_WHEEL)
jupyter lite build --contents content --output-dir dist
cp -f index.html dist/index.html

register-kernel:
$(PYTHON3) ./install-kernel.py

#: Remove Jupyter Cache file
clean-cache:
rm .jupyterlite.doit.db || true;
Expand Down
8 changes: 7 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,13 @@ source .venv/bin/activate
pip install -r requirements.txt
```

The above also needs to be done only once.
Alternatively, you can use pyenv:
```console
pyenv local 3.14 # or whatever Python you use
pip install -r requirements.txt
```

Like initializing Git submodules, setting up the Python environment needs to be done only once.

Once the virtual environment has been set up with the packages installed, to run the server:

Expand Down
Binary file added img/logo-32x32.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/logo-64x64.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
107 changes: 107 additions & 0 deletions install-kernel.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
#!/bin/env python3
"""
A Command-line program to create a JSON kernel.json for Mathics3 JupyLite kernel.
"""
import argparse
import json
import os
import os.path as osp
import shutil
import sys
from tempfile import TemporaryDirectory

from jupyter_client.kernelspec import KernelSpecManager

KERNEL_NAME = "Mathics3-Live"
DISPLAY_NAME = "Mathics3 (using Jupyterlite)"
# The source directory for icons relative to the project root
ICON_SOURCE_DIR = osp.normpath(osp.join(osp.dirname(__file__), "img"))

kernel_json = {
"argv": [
sys.executable,
"-m",
"mathics3_kernel.frontend.jupyter", # The module that handles the kernel loop
"-f",
"{connection_file}",
],
"display_name": DISPLAY_NAME,
"language": "mathematica",
}


def install_my_kernel_spec(user=True, prefix=None):
"""
Creates a JSON 'kernel.json' file custom for the Mathics3 JupyterLite kernel of
this project.
"""
with TemporaryDirectory(prefix="kernel-", suffix=".json") as td:
os.chmod(td, 0o755) # Ensure Jupyter can read the directory

# Write the kernel.json file
with open(os.path.join(td, "kernel.json"), "w") as f:
json.dump(kernel_json, f, sort_keys=True, indent=4)

# Jupyter specifically looks for logo-32x32.png and logo-64x64.png
icon_found = False
if osp.isdir(ICON_SOURCE_DIR):
for icon_name in ["logo-32x32.png", "logo-64x64.png"]:
src_path = osp.normpath(osp.join(ICON_SOURCE_DIR, icon_name))
if osp.exists(src_path):
print(f"Found icon: {icon_name}, adding to kernelspec...")
shutil.copy(src_path, td)
icon_found = True

if not icon_found:
print(
f"Warning: No icons found in {ICON_SOURCE_DIR}/. Kernel will install without a logo."
)

print(f"Installing Jupyter kernel spec for {DISPLAY_NAME}...")
try:
KernelSpecManager().install_kernel_spec(
td, KERNEL_NAME, user=user, prefix=prefix
)
print(
"Successfully installed Mathics3 kernel in mathics3-jupyter/kernel.json"
)
except Exception as e:
print(f"Failed to install kernel: {e}")


def _is_root():
try:
return os.getuid() == 0
except AttributeError:
return False # Windows


def main(argv=None):
parser = argparse.ArgumentParser(
description=f"Install the {DISPLAY_NAME} kernel spec for Jupyter."
)
parser.add_argument(
"--user",
action="store_true",
help="Install to the per-user kernelspec directory",
)
parser.add_argument(
"--sys-prefix",
action="store_true",
help="Install to Python's sys.prefix (e.g. venv)",
)
parser.add_argument("--prefix", help="Install to the given prefix")

args = parser.parse_args(argv)

if args.sys_prefix:
args.prefix = sys.prefix
if not args.prefix and not args.user and _is_root():
args.user = False

install_my_kernel_spec(user=args.user or True, prefix=args.prefix)
print("Installation complete.")


if __name__ == "__main__":
main()
4 changes: 2 additions & 2 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Core modules (mandatory)
jupyterlite-core==0.4.1
jupyterlab~=4.2.5
notebook~=7.2.2
jupyterlab>=4.5.7
notebook~=7.5.6


# Python kernel (optional)
Expand Down