Install python package with optional dependencies

How to install a Python package with optional dependencies? I.e. with pip I would do pip install httpx[cli] but how to do that with flox? Running flox install nixpkgs#python310Packages.httpx does not install the optional dependencies (as expected)?

edit: After I got some help from #nixos IRC, I tried flox install nixpkgs#python310Packages.httpx.optional-dependencies.cli which errors with error: value is a list while a set was expected.

edit2: Maybe this is a case where editing a more declarative config would make sense?

Howdy, and thanks for writing us.

This is actually an issue that I had to deal with recently with Python packages in the flox CLI. This is something we’re hoping to improve in the future, but the good news is that I can probably help you out.

You’re right that you’re going to need to make a declaration for this - for two reasons.

  1. The optional-dependencies.cli value is a list of derivations, not single derivation. So if you want all of them you’ll need to “link”/join
  2. The CLI currently won’t let you access sub-attributes easily .

So you’ll want to create a flox.nix file ( flox init -t project; ) and add the following file to ./pkgs/httpx-cli/default.nix:

# ./pkgs/httpx-cli/default.nix
{ symlinkJoin, python310Packages, ... }: symlinkJoin {
  name  = "httpx-cli";
  paths = python310Packages.httpx.optional-dependencies.cli;
}

To build and install to an env:

$ flox build '.#httpx-cli';
$ ls ./result/lib/python3.10/site-packages; 
click  click-8.1.3.dist-info  pygments  Pygments-2.14.0.dist-info  rich  rich-13.3.1.dist-info
$ flox create -e custom-example;
created environment custom-example (x86_64-linux)
$ flox install -e custom-example python3;
Installed 'python3' package(s) into 'custom-example' environment.
$ flox install -e custom-example "$( readlink -f ./result; )";
Installed '/nix/store/7ch5cbz3bcszwrq5f4szal6vnq5mlbwq-httpx-cli' package(s) into 'custom-example' environment.
# append `PYTHONPATH':
$ flox edit -e custom-example;
{
  shell.hook = ''
    PYTHONPATH="''${PYTHONPATH:+$PYTHONPATH:}/nix/store/7ch5cbz3bcszwrq5f4szal6vnq5mlbwq-httpx-cli/lib/python3.10/site-packages";
    export PYTHONPATH;
  '';
  packages."/nix/store/7ch5cbz3bcszwrq5f4szal6vnq5mlbwq-httpx-cli" = {};
  packages.nixpkgs-flox.python3 = {};
}
$ flox activate -e custom-example;
flox [custom-example default] $ python3
Python 3.10.10 (main, Feb  7 2023, 12:19:31) [GCC 12.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import click
>>> quit()

Let me know if that helps and if you have any follow up questions.

I am going to ask the engineering team about an alternative to using readlink -f ./result; and will let you know if they have an further advice.

Thanks for your reply and the instructions.

I followed the steps, but flox build '.#httpx-cli' fails with ERROR: No matching installables found.

Could you share the contents of your flox.nix file?

Also can you confirm that the path is exactly ./pkgs/httpx-cli/default.nix? The “name” of the package matches the folder name, so a different name could cause this failure.

I did not touch flox.nix after flox init -t project so the contents are:

{
  # flox environment
  #
  # To learn basics about flox commands see:
  #   https://floxdev.com/docs/basics
  #
  # Check other options you can configure in this file:
  #   https://floxdev.com/docs/reference/flox-nix-config
  #
  # Get help:
  #   https://discourse.flox.dev
  #
  # Happy hacking!

  # Look for more packages with `flox search` command.
  #packages.nixpkgs-flox.go = {};
  #packages.nixpkgs-flox.nodejs = {}

  # Set environment variables
  #environmentVariables.LANG = "en_US.UTF-8";

  # Run shell hook when you enter flox environment
  #shell.hook = ''
  #  echo "Welcome to flox environment"
  #'';
}

and I triple-checked the folder name as I suspected that as well:

$ ls -la
total 48
drwxr-xr-x 5 pbz pbz  4096 Apr 17 11:40 .
drwxr-x--- 8 pbz pbz  4096 Apr 17 11:44 ..
drwxr-xr-x 2 pbz pbz  4096 Apr 17 11:40 .flox
drwxr-xr-x 7 pbz pbz  4096 Apr 17 11:40 .git
-rw-r--r-- 1 pbz pbz 19100 Apr 17 11:40 flake.lock
-rw-r--r-- 1 pbz pbz   170 Apr 17 11:38 flake.nix
-rw-r--r-- 1 pbz pbz   629 Apr 17 11:38 flox.nix
drwxr-xr-x 3 pbz pbz  4096 Apr 17 11:38 pkgs
$ ls pkgs/httpx-cli/default.nix
-rw-r--r-- 1 pbz pbz 172 Apr 17 11:44 pkgs/httpx-cli/default.nix

You may need to git add ./pkgs; I forgot to include that in my example.

Once you add the files to your git repo flox build '.#httpx-cli'; should work.

That did the trick. Thanks again for helping out, the support and detailed walkthrough!

No problem, happy to help :slightly_smiling_face: