Executable nix-shell for directly calling a binary from pip

Related to this issue, I thought an elegant way to solve this would be to write an executable nix-shell definition, which installs a target script from/with pip and executes it. I have been experimenting with mach-nix for this, but it doesn’t seem to work.

So say my goal is to instantiate an env in which I can install pandoc-xnos and run it.

For now I came up with the following pandoc-xnos.nix, which can be specified directly as filter executable for pandoc(omatic):

#!/usr/bin/env nix-shell
#!nix-shell --pure pandoc-xnos.nix

{ pkgs ? import <nixpkgs> {} }:

pkgs.mkShell {
  buildInputs = with pkgs; [
    (python39.withPackages (p: with p; [ pip ]))
  ];
  shellHook = ''
    python -m venv $XDG_RUNTIME_DIR/pandoc-filters 1>&2
    . $XDG_RUNTIME_DIR/pandoc-filters/bin/activate 1>&2
    pip install pandoc-xnos 1>&2
    pandoc-xnos
    deactivate 1>&2
    # rm -rf $XDG_RUNTIME_DIR/pandoc-filters 1>&2
  '';
}

However this seems quite a dirty hack, since it doesn’t clean up and is far from pure. It would arguably be better to work via the nix store somehow and then rely on garbage collect? But then it would also be better if different python based pandoc filters could use the same semi-temporary python env, at least between garbage collects?

Hmm, I’m a bit confused why this is necessary… What’s wrong with simply using

nix-shell -p python3Packages.pandoc-xnos --run pandoc-xnos

?

pandoc-xnos is not in pythonPackages, it’s only available via pip or poetry

Oh, well then I’d suggest packaging it! I promise it’s really not that hard. Start from an example like python3Packages.in-place: init at 0.5.0 by samuela · Pull Request #138759 · NixOS/nixpkgs · GitHub and then just modify it to suite your needs.

@samuela Thanks, sounds like a good idea, will look into it when I find some time…

EDIT: indeed it was as easy as you said, so here it is: Add python pandoc-xnos by ppenguin · Pull Request #164328 · NixOS/nixpkgs · GitHub