

Painlessly developing Python on NixOS with pipenv
source link: https://sid-kap.github.io/posts/2018-03-08-nix-pipenv.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Painlessly developing Python on NixOS with pipenv
Painlessly developing Python on NixOS with pipenv
8 March 2018
3 minute read
For a long time, I’ve wanted to develop Python code on NixOS, but using Nix to manage dependencies was a major pain. If the dependencies you want are already in Nixpkgs, then you’re good, but otherwise you need to use things like pypi2nix to turn Pypi packages into nix derivations. This never quite worked out for me, so I ended up writing the nix derivations myself… which sucked.
I’ve been aware of pipenv for a while now, and it seemed like the ideal solution. It gives Nix/Stack/Yarn-like reproducibility, while still being actively maintained, unlike some of these Nix-specific Python package tools. I had never managed to get this to work for me, but I’ve finally got a configuration working on Nix.
First attempt
My original instinct was to throw together a default.nix
file:
with import <nixpkgs> {};
mkDerivation {
name = "my-python-project";
buildInputs = [ python36 pipenv ];
}
and just open nix-shell
and run all my pipenv
commands from there.
The problem
Unfortunately, whenever I tried to install a package that required compiling lots of C source (like numpy or pandas), the pipenv install
command would take forever, and often either seg-fault in the process or just never complete.
From using pipenv
on other, non-NixOS machines, I knew that installing numpy and pandas was much faster on those machines, but I didn’t know why. Finally, I found out that on OS X, Windows, and some distributions of Linux, Python installs “wheels”, which contain the prebuilt binary code, rather than building from source. It only does this on Linux if it detects that your distribution supports wheels from the manylinux project. A quick test reveals that my Python distribution is not manylinux-compatible:
[sidharth@nixos:~]$ python3
Python 3.6.4 (default, Dec 19 2017, 05:36:13)
[GCC 6.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import _manylinux
>>> _manylinux.manylinux1_compatible
False
The solution
In order to use manylinux whl
s to get fast package installs, I needed to
- set up my system so that manylinux whls work (i.e. make it many-linux compatible),
- convince Python that my system is manylinux-compatible.
Step 1
The first step is to make an environment that follows the manylinux1
policy:
with import <nixpkgs> {};
buildFHSUserEnv {
name = "my-python-env";
targetPkgs = pkgs: with pkgs; [
python3
pipenv
which
gcc
binutils
# All the C libraries that a manylinux_1 wheel might depend on:
ncurses
xorg.libX11
xorg.libXext
xorg.libXrender
xorg.libICE
xorg.libSM
glib
];
runScript = "$SHELL";
}
This creates an environment that contains all the C libraries that a manylinux_1
wheel might depend on, all in /usr/lib/
, where the binaries expect it. Save this in default.nix
, run nix-build
, and you can enter this environment with ./result/bin/my-python-env
.
Step 2
To convince Python that this environment is manylinux_1
-compatible, you need _manylinux.manylinux1_compatible
to be true. We can do this by making a file called _manylinux.py
that contains:
print("in _manylinux.py")
manylinux1_compatible = True
To make sure that pipenv
finds this code, you need to save this file somewhere in your PYTHONPATH
. I did this by adding
let
manyLinuxFile =
writeTextDir "_manylinux.py"
''
print("in _manylinux.py")
manylinux1_compatible = True
'';
to the top of my default.nix
, and by adding the following to my derivation in default.nix
:
profile = ''
export PYTHONPATH=${manyLinuxFile.out}:/usr/lib/python3.6/site-packages
'';
Conclusion
With the above steps, I am able to pipenv install
any package, and it uses the whl
, as long as I am within my nix environment (by running ./result/bin/my-python-env
). Hooray!
Recommend
-
182
Pipenv: Python Development Workflow for Humans [ ~ Dependency Scanning by PyUp.io ~ ] Pipenv is a tool that aims to bring the best of all packaging worlds (bund...
-
86
README.md No longer actively maintained I'm no longer using vim-nerdtree-tabs and i'm no longer maintaining it actively. In case you forked it and moved the code forward, e.g. by fixing...
-
15
-
11
Pipenv:新一代Python项目依赖管理工具 发表回复 UPDATE(2019/8/31):不要用 Pipenv...
-
9
Tech talk Tools to Scale Your SaaS Startup Painlessly Building a SaaS
-
6
使用 pipenv 代替 virtualenv 管理 python 包第一次接触到 pipenv 是因为看到 @董明伟大神的《使用 pipenv 管理你的项目》,之前可能和大家的选择类似使用 virtualenv 或者 pyenv 来管理 python 的包环境。virtualenv 是针对 python 的包的多版本管理,通过将 p...
-
7
PipEnv 安装 $ pip install --user pipenv # 升级 pipenv $ pip install --user pipenv --upgrade # 如果不知道如何将 shell 找不到的命令添加到系统环境变量则这样寻找 $ python -m site --user-base ...
-
8
Article Pipenv and S2i: A better way to manage Python dependencies in containers ...
-
9
Python Hands-on How to manage Python projects with Pipenv Have your Python projects become a rat’s nest? Pipenv provides a clean and easy way t...
-
12
Support is great. Feedback is even better."Really appreciate any feedback or feature requests."The makers of Pact English
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK