Packaging/Python
See Language-specific package helpers for a list of tools to package python packages.
Prepare Packaging
When you want to package a new software from a local checkout with the inputs coming from nixpkgs (and not virtualenv+pip) you can use the following shell.nix
[1]:
with import <nixpkgs> {};
with pkgs.python3Packages;
buildPythonPackage rec {
name = "mypackage";
src = ./path/to/source;
propagatedBuildInputs = [ pytest numpy pkgs.libsndfile ];
}
You can now run nix-shell
and it will drop you in a shell similar to the python setup.py develop
mode which uses the local code in ./path/to/source as input. propagatedBuildInputs
will contain the packages you need in your project.
After you've finished developing you can replace the relative path with fetchFromGitHub { ... }
or fetchPypi { ... }
.
Pip and Virtualenv enabled nix-shell
It might be the case that you simply need to prototype fast small projects with pip
and virtualenv
without the need for relying on the dependencies being already packaged in nixpkgs.
{{Notice|Keep in mind that the virtualenv symlinks will be invalidated if you update your system!||
For a local working python environment you can use the following shell.nix
[2].
with import <nixpkgs> {};
stdenv.mkDerivation {
name = "pip-env";
buildInputs = [
# System requirements.
readline
# Python requirements (enough to get a virtualenv going).
python27Full
python27Packages.virtualenv
python27Packages.pip
];
src = null;
shellHook = ''
# Allow the use of wheels.
SOURCE_DATE_EPOCH=$(date +%s)
# Augment the dynamic linker path
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:${R}/lib/R/lib:${readline}/lib
'';
}
When invoked with nix-shell, this environment gives you a readline-enabled Python, plus virtualenv and pip, from which you can create a virtual environment and then proceed to fill it with pip-installed packages from requirements.txt or any other source of packages.
And the only other thing you need to do is figure out which non-Python packages your pip-installable packages will need, and include them in buildInputs.
Caveats
ModuleNotFoundError: No module named 'pkg_resources'
If you see this runtime error
ModuleNotFoundError: No module named 'pkg_resources'
add setuptools
to your derivation
buildPythonPackage {
# ...
propagatedBuildInputs = [
# ...
setuptools
];
}
Please report such issues at https://github.com/NixOS/nixpkgs/issues
HTTP 404 with fetchPypi
example error:
curl: (22) The requested URL returned error: 404
error: cannot download stt-1.2.0.tar.gz from any mirror
when we look at https://pypi.org/project/stt/#files we see only *.whl
files
this means, this is a binary release, and we must build the package from source
replace this
src = fetchPypi { inherit pname version; sha256 = ""; };
with this
src = fetchFromGitHub { owner = "todo"; repo = "todo"; rev = "todo"; sha256 = ""; };
TODO or use buildPythonPackage { format = "wheel"; }
?
setup.py
The setup.py
file is required by buildPythonPackage
,
but it's missing in some packages
setup.py example:
from setuptools import setup
with open('requirements.txt') as f:
install_requires = f.read().splitlines()
setup(
name='someprogram',
#packages=['someprogram'],
version='0.1.0',
#author='...',
#description='...',
install_requires=install_requires,
scripts=[
'someprogram.py',
],
entry_points={
#'console_scripts': ['someprogram=some_module:main']
},
)
In this example, someprogram.py
would be installed as $out/bin/someprogram.py
To rename the binary, for example to remove the .py
file extension, you can use postInstall
buildPythonPackage {
# ...
postInstall = ''
mv -v $out/bin/someprogram.py $out/bin/someprogram
'';
}
requirements.txt
requirements.txt
in it's simplest form is a list of python packages
numpy Requests Pillow
buildPythonPackage
will check these dependencies, but you still must declare the nix dependencies in buildInputs
, propagatedBuildInputs
, checkInputs
, ...
Automatic packaging
TODO https://github.com/nix-community/poetry2nix
See also
- buildPythonPackage implementation
- Python in the nixpkgs manual