mach-nix
mach-nix copied to clipboard
How to use a wheel from local file?
Hi, I wonder how I can pass a local .whl file to mach-nix, to be included in the final python environment. (The wheel file I need is not hosted on pypi. I plan to use nixpkgs' requireFile
to get it.)
I tried passing it in packagesExtra
, but that doesn't work:
[...]
unpacking source archive /nix/store/w8a0dh4gkq17xc46m778xxrszc33s8k4-tensorboard-1.15.0-py3-none-any.whl
do not know how to unpack source archive /nix/store/w8a0dh4gkq17xc46m778xxrszc33s8k4-tensorboard-1.15.0-py3-none-any.whl
builder for '/nix/store/g98f6z283kjpkb1hj8i8p811ivzgs4zq-package-requirements.drv' failed with exit code 1
(The above file is just for testing.)
Simplified wheel support is indeed a missing feature in mach-nix
But you can still use buildPythonPackage
from mach-nix and manually set format = "wheel"
.
example:
mach-nix.mkPython {
packagesExtra = [
(mach-nix.buildPythonPackage {
pname = "requests";
version = "2.25.0";
format = "wheel";
src = /tmp/requests-2.25.0-py2.py3-none-any.whl;
requirements = ''
chardet
idna
urllib3
certifi
'';
})
];
}
Just make sure to set pname, version and requirements accordingly, otherwise it will fail since it doesn't yet support automatic metadata extraction from wheels.
That works, thanks!
FYI, I'm testing import-from-derivation to get the requirements.txt contents from the wheel itself, by collecting Requires-Dist:
lines from ${unpacked_wheel_file}/${wheel_name}.dist-info/METADATA"
with Nix' builtins.match
. Seems to work. Nix snippet below.
requirements =
let
text = builtins.readFile "${unpacked_wheel_file}/${wheel_name}.dist-info/METADATA";
lines = builtins.filter (x: x != [] && x != "") (builtins.split "\n" text);
# toRequirement :: String -> String (or null)
toRequirement = line:
let
m =
builtins.match "Requires-Dist: (.*)" line;
in
if m == null
then null
else
# Return the match group, unless it contains "; extra ==" (ref.
# https://github.com/DavHau/mach-nix/pull/419).
let
req = builtins.elemAt m 0; # the first match group
in
if builtins.match ".*; extra == .*" req == []
then null
else req;
requirementsLines = (lib.filter (x: x != null) (map toRequirement lines));
requirementsText = lib.concatStringsSep "\n" requirementsLines;
in
#builtins.trace "Extracted requirements.txt from METADATA:\n${requirementsText}"
requirementsText;
UPDATED(2022-04-07): Filter out Provides-Extra lines, ref. https://github.com/DavHau/mach-nix/pull/419.
Nice, something like this should also go into mach-nix.
But since we're already doing IFD, we could also just use wheel2json
from the wheel-inspect
package, then parse the json with nix.
Cross-reference: https://github.com/DavHau/mach-nix/issues/276.