Installing a package in editable mode#

This tutorial shows how to install a Python package in editable mode within Juice. This is useful when you are developing a package and want to test it without having to rebuild and reinstall the package every time you make a change.

This tutorial applies to both of the following scenarios:

  • Packages that are already installed in your Juice environment and that you want to replace with an editable version.

  • Packages that are not yet installed and that you want to install in editable mode.

Prerequisites#

  1. You are logged in to Juice and have opened the JupyterLab interface.

  2. You have a lab repository set up in Juice at ~/shared/lib/lab. If your lab repository is at a different location, simply replace ~/shared/lib/lab with the actual path to your lab repository in the steps below.

1. Configuring the package as an editable dependency#

  1. Clone the repository of the package you want to install into ~/shared/lib. For example, if you want to install <example-package> from GitHub, run the following commands in a terminal:

    cd ~/shared/lib
    git clone https://<url to your repository>.git
    

    This will create a new directory ~/shared/lib/<example-package-directory> containing the source code of the package.

  2. Add the package as an editable dependency of the lab repository. Open ~/shared/lib/lab/pyproject.toml in a text editor and make the following changes:

    1. Add the package to the project.dependencies list. For example:

      [project]
      dependencies = [
          # ...
          # Existing dependencies
          # ...
          "<example-package>",
      ]
      

      Note that the package name should match the name specified in the pyproject.toml of the package you are adding. This is not necessarily the same as the name of the directory containing the package!

    2. Configure the package as an editable source by adding it to the [tool.uv.sources] section. For example:

      [tool.uv.sources]
      "<example-package>" = { path = "../<example-package-directory>", editable = true }
      

      Again, make sure to replace <example-package> with the actual name of the package and <example-package-directory> with the actual name of the directory containing the package. If there is already a [tool.uv.sources] section in the pyproject.toml, simply add the new package to that section.

  3. Validate the changes by running the following command from a terminal.

    uv sync
    

    This will validate the pyproject.toml and temporarily install the package in editable mode just for your singleuser container. If there are any errors in the pyproject.toml, they will be displayed in the terminal output.

    Warning

    After this command completes, the package is temporarily installed, and only within your own singleuser container! This means that:

    • The change will be lost when you restart your singleuser container.

    • Services and other users will not have this change yet.

    In the next section, we will show how to persist the change and make it available for services and other users as well.

  4. If you want to confirm that the package is indeed installed in editable mode, you can run the following command from a terminal:

    uv pip list | grep <example-package>
    

    This should show the package name, version and installation location, which should point to the source directory of the package (i.e., ~/shared/lib/<example-package-directory>). For example:

    <example-package>       0.0.1       /home/user/shared/lib/<example-package-directory>
    

2. Persisting the changes to services and for other users#

  1. To persist the changes, you need to rebuild and restart relevant Juice environments.

    • To make the changes available to a service, you need to rebuild and restart the relevant environment. To rebuild and restart a service, use the following snippet in a local IPython kernel.

      from orangeqs.juice.client import service
      
      service.rebuild_service("device")
      service.restart_service("device")
      

      Replace "device" with the actual name of the service you want to apply the changes to.

    • To make the change available after restarting your singleuser container and to other users, you need to rebuild the singleuser environment. To do this, use the following snippet:

      from orangeqs.juice.client import service
      
      service.rebuild_service("singleuser")
      

      Then restart your personal JupyterLab server from the Hub Control Panel. You can find this panel under File > Hub Control Panel from the JupyterHub UI.

  2. If you want to do one final check that the changes have been applied correctly, you can run the following command from an IPython kernel console (thus not from a terminal).

    • If you want to check a service, connect your kernel to the relevant service (e.g. “Service: device”).

    • If you want to check your singleuser container, use a local kernel (e.g. “Python 3 (ipykernel)”).

    !uv pip list | grep <example-package>
    

    Again, this should show the package name, version and editable installation location.

Summary

Below is a short summary of the actions we did during this tutorial and what effects they have.

Action

Effect

Run uv sync in a terminal

Temporarily apply the change, but only within your singleuser container. The change will be lost when you restart your singleuser container, and services and other users will not have this change.

Rebuild and restart a service

Makes the change available to that service.

Rebuild the singleuser environment and restart your JupyterLab server

Makes the change available after restarting your singleuser container and to other users.