Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Shipping applications

uv2nix primarily builds virtual environments, not individual applications.

Sometimes the fact that an application is written in Python & using a virtualenv is an implementation detail that you don’t want to expose in your Nix package.

For such cases pyproject.nix provides a utility function mkApplication:

{
    packages = forAllSystems (
      system:
      let
        pythonSet = pythonSets.${system};
        pkgs = nixpkgs.legacyPackages.${system};
        inherit (pkgs.callPackages pyproject-nix.build.util { }) mkApplication;
      in
      {
        # Create a derivation that wraps the venv but that only links package
        # content present in pythonSet.hello-world.
        #
        # This means that files such as:
        # - Python interpreters
        # - Activation scripts
        # - pyvenv.cfg
        #
        # Are excluded but things like binaries, man pages, systemd units etc are included.
        default = mkApplication {
          venv = pythonSet.mkVirtualEnv "application-env" workspace.deps.default;
          package = pythonSet.hello-world;
      };
}

Additional data

When shipping an application you might want to ship additional data such as shell completions.

To ship additional data in the same derivation as the application derivation use an override:

(mkApplication {
  venv = pythonSet.mkVirtualEnv "application-env" workspace.deps.default;
  package = pythonSet.hello-world;
}).overrideAttrs(old: {
  nativeBuildInputs = old.nativeBuildInputs ++ [ pkgs.installShellFiles ];
  postInstall = ''
    installShellCompletion --cmd ${cmd} \
      --bash <($out/bin/${cmd} --show-completion bash) \
      --fish <($out/bin/${cmd} --show-completion fish) \
      --zsh <($out/bin/${cmd} --show-completion zsh)
  '';
})