Building Jupyter package

I am trying to set up a development shell for nbgrader, but I’m running into a problem that I expect might be an issue for other Jupyter projects as well.

After cloning the repo, I have the following shell.nix:

{ pkgs ? import <nixpkgs> { } }:

let
  nbgrader = pkgs.python3.pkgs.buildPythonPackage rec {
    name = "nbgrader";
    format = "pyproject";
    src = ./.;
    buildInputs = with pkgs.python3Packages; [
      hatchling
      hatch-jupyter-builder
    ];
    propagatedBuildInputs = with pkgs; [
      nodejs
      python3Packages.jupyterlab
    ];
  };

in pkgs.mkShell {
  packages = with pkgs; [
    nbgrader
  ];
}

I am encountering

Traceback (most recent call last):
    File "/nix/store/xi185mgy9nhbm3xjrv03jhbf215ayriz-python3.10-pip-22.2.2/lib/python3.10/site-packages/pip/_vendor/pep517/in_process/_in_process.py", line 156, in prepare_metadata_for_build_wheel
      hook = backend.prepare_metadata_for_build_wheel
  AttributeError: module 'hatchling.build' has no attribute 'prepare_metadata_for_build_wheel'

  During handling of the above exception, another exception occurred:

  Traceback (most recent call last):
    File "/nix/store/xi185mgy9nhbm3xjrv03jhbf215ayriz-python3.10-pip-22.2.2/lib/python3.10/site-packages/pip/_vendor/pep517/in_process/_in_process.py", line 363, in <module>
      main()
    File "/nix/store/xi185mgy9nhbm3xjrv03jhbf215ayriz-python3.10-pip-22.2.2/lib/python3.10/site-packages/pip/_vendor/pep517/in_process/_in_process.py", line 345, in main
      json_out['return_val'] = hook(**hook_input['kwargs'])
    File "/nix/store/xi185mgy9nhbm3xjrv03jhbf215ayriz-python3.10-pip-22.2.2/lib/python3.10/site-packages/pip/_vendor/pep517/in_process/_in_process.py", line 160, in prepare_metadata_for_build_wheel
      whl_basename = backend.build_wheel(metadata_directory, config_settings)
    File "/nix/store/gm4iddmj056609q8l0m02wh9fgyzhpdq-python3.10-hatchling-1.11.1/lib/python3.10/site-packages/hatchling/build.py", line 41, in build_wheel
      return os.path.basename(next(builder.build(wheel_directory, ['standard'])))
    File "/nix/store/gm4iddmj056609q8l0m02wh9fgyzhpdq-python3.10-hatchling-1.11.1/lib/python3.10/site-packages/hatchling/builders/plugin/interface.py", line 136, in build
      build_hook.initialize(version, build_data)
    File "/nix/store/492afciypca22gmh0rjggh0y7w0fms0v-python3.10-hatch-jupyter-builder-0.8.2/lib/python3.10/site-packages/hatch_jupyter_builder/plugin.py", line 83, in initialize
      raise e
    File "/nix/store/492afciypca22gmh0rjggh0y7w0fms0v-python3.10-hatch-jupyter-builder-0.8.2/lib/python3.10/site-packages/hatch_jupyter_builder/plugin.py", line 78, in initialize
      build_func(self.target_name, version, **build_kwargs)
    File "/nix/store/492afciypca22gmh0rjggh0y7w0fms0v-python3.10-hatch-jupyter-builder-0.8.2/lib/python3.10/site-packages/hatch_jupyter_builder/utils.py", line 105, in npm_builder
      npm_cmd = normalize_cmd(npm)
    File "/nix/store/492afciypca22gmh0rjggh0y7w0fms0v-python3.10-hatch-jupyter-builder-0.8.2/lib/python3.10/site-packages/hatch_jupyter_builder/utils.py", line 202, in normalize_cmd
      raise ValueError(
  ValueError: Aborting. Could not find cmd (jlpm) in path. If command is not expected to be in user's path, use an absolute path.

which complains about jlpm not being in path. (Even though it is the later error, I am under the impression that fixing jlpm will fix the hatchling error, but that might be wrong.) But jlpm is provided by the jupyterlab python package, as verifiable by nix-shell -p python3Packages.jupyter.

At this point, I am not sure what else to try, so I would appreciate some input if anyone has an idea. Sorry if I am doing something in the unintended way, this is me trying to learn Nix by doing.

I thought of taking a look at nixpkgs. There is no nbgrader packaged, but jupyterlab also uses jlpm, where buildPythonPackage.format = "setuptools"; is used.

Thinking that might solve my problem, changing the format in my shell.nix and adding missing packages to propagatedBuildInputs as it complained, I managed to get the shell working. Now, it looks like I can import the package in python, but the command-line interface is not working:

$ nbgrader
Traceback (most recent call last):
  File "/nix/store/5pwzm7y19s8x70didkyy6928xg4b6vv6-python3.10-nbgrader/bin/.nbgrader-wrapped", line 6, in <module>
    from nbgrader.apps.nbgraderapp import main
ModuleNotFoundError: No module named 'nbgrader'

And I think this just circumvents the desired behavior of building and enabling some JupyterLab extensions.