Packaging a Python app with extra scripts

Hi friends!

I recently created a package for a Python app using the conventional buildPythonApplication, and all is well but for a special case I haven’t been able to find another example of in Nixpkgs: in addition to the app, the source ships with a few independent scripts (with python3 shebangs) that depend on not only the same modules that the app depends on but also the app itself (as a module). These scripts are called via command options to extend the functionality of the app. The problem is that because the scripts are not actually part of the app, they don’t get wrapped, which means when executed they fail with a bunch of ModuleNotFoundErrors.

I tried wrapping them independently with the wrapProgram "$out/lib/python3.8/site-packages/$f" --prefix PYTHONPATH : "$out/${python.sitePackages}" trick, which satisfies the dependency on the app, but the app’s build inputs remain inaccessible to these scripts.

To try and sum this up in a single question: is there an established way to wrap both an app and its support scripts from a single package such that all dependencies are commonly accessible (without the need for a development shell because this is supposed to be a standalone app)? In the worst case, I suppose I could patch the source to absorb the scripts into the app itself, but that seems excessive. Hopefully, there’s a simple solution I simply haven’t thought of!

Thanks!

1 Like

The solution was simple after all: add the additional dependencies to PYTHONPATH for wrapProgram. I ended up with something like this:

# (for each script $f...)
wrapProgram "$out/lib/${python.libPrefix}/site-packages/$f" \
  --prefix PYTHONPATH : "$out/${python.sitePackages}" \
  --prefix PYTHONPATH : "${lib.concatStringsSep ":" (map (p: p + "/lib/${python.libPrefix}/site-packages") (python.pkgs.requiredPythonModules propagatedBuildInputs))}"

This is a fairly common solution by itself, but it took me a while to arrive at it for this package because wrapProgram here only applies to these extra scripts—as mentioned above, the app itself gets by on buildPythonApplication alone.

3 Likes

I also found that:

  postFixup = ''
    wrapProgram "$out/bin/mssql-cli" \
      --prefix PYTHONPATH : "$PYTHONPATH"
  '';

seems to work in my use-case, no idea how these two solutions compare.

1 Like