如何用 nix 打包单个 Python 脚本?

How to package a single Python script with nix?

我有一个名为 myscript.py 的 Python 脚本,我想将其打包为 nix 派生 mkDerivation.

唯一的要求是我的 Python 脚本具有 运行 时间依赖性,例如 consul Python 库(它本身取决于 requestssix Python 库)。

例如myscript.py

#!/usr/bin/env python3

import consul
print('hi')

怎么做?

我不知道如何传递 mkDerivation 单个脚本(它的 src 似乎总是想要一个目录,或者 fetchgit 或类似的),也不能'不知道如何在 运行 时间使依赖库可用。

当您只有一个 Python 文件作为脚本时,您的 mkDerivation 中不需要 src,也不需要解压任何源代码。

默认mkDerivation会尝试解压你的源代码;为防止这种情况,只需设置 unpackPhase = "true";(这是 /bin/true,什么都不做的程序)。

myscript-package = pkgs.stdenv.mkDerivation {
  name = "myscript";
  buildInputs = [
    (pkgs.python36.withPackages (pythonPackages: with pythonPackages; [
      consul
      six
      requests2
    ]))
  ];
  unpackPhase = "true";
  installPhase = ''
    mkdir -p $out/bin
    cp ${./myscript.py} $out/bin/myscript
    chmod +x $out/bin/myscript
  '';
};

如果您的脚本是可执行的(我们用上面的 chmod +x 确保这一点)nix 将自动用调用正确的特定 python 解释器的行替换您的 #!/usr/bin/env python3 行(上面示例中 python36 的那个),并且在具有您在 buildInputs 中指定的 Python 包的环境中执行此操作。

如果您使用 NixOS,您也可以将您的包放入 environment.systemPackages,并且 myscript 将在该 NixOS 的 shell 中可用。

这个辅助函数真不错:

pkgs.writers.writePython3Bin "github-owner-repos" { libraries = [ pkgs.python3Packages.PyGithub ]; } ''
 import os
 import sys
 from github import Github

 if __name__ == '__main__':
     gh = Github(os.environ['GITHUB_TOKEN'])

     for repo in gh.get_user(login=sys.argv[1]).get_repos():
         print(repo.ssh_url)
''

https://github.com/nixos/nixpkgs/blob/master/pkgs/build-support/writers/default.nix#L319