Help installing Python Library

Hi, apologies in advance for the noob question.

I have been using NixOS for about 6-8 months now and it has been a pretty good experience compared with other distros, mainly due to the stability (which comes from the reproducibility of the packaging system). For a university project I now need to install a Python library that is not in nixpkgs (Control). I have been struggling to find any clear resources on how to do this, as they all assume familiarity with Python packaging (with pypi or pipenv or poetry or what have you), or they assume an in-depth understanding of Nix. I have neither.

My question is: what is the best way to install the Control Python library and how can I make it easier to install other non-Nix libraries in the future? Should I just create a virtual machine or container running some other distribution of Linux?

Thanks.

1 Like

use venv, bro, this is true way

Okay, so how would I do it with venv? Should I get rid of all the Python stuff in my configuration.nix, and then write a requirements.txt file?

Something like this would probably work: nixpkgs/pkgs/development/python-modules/requests/default.nix at dd457de7e08c6d06789b1f5b88fc9327f4d96309 · NixOS/nixpkgs · GitHub
Another option could be poetry2nix.

If that all doesn’t tell you much I recommend having a look at: https://nix.dev/
And maybe this as well: Scrive Nix Workshop - Scrive Nix Workshop

Packaging software is quite a different thing to do than just using NixOS but it’s a worthwhile thing to learn.

1 Like

You have a lot of great options in the Python - NixOS Wiki page, but I personally find devenv the easiest and cleanest one so far. It also has first-class support for native libraries, so you don’t have to worry about whether a package will work or not.

After you install devenv, just run the following command inside your project to get started:

$ devenv init

Then, you can write a requirement.txt if you don’t have one, yet:

# requirememnt.txt
control==0.10.0

We could have directly added the packages in venv.requirements, but it might be cleaner to just read them, instead:

# devenv.nix
{ pkgs, lib, config, inputs, ... }:

{
  languages.python = {
    enable = true;
    venv.enable = true;
    venv.requirements = lib.readFile ./requirememnt.txt;
  };

  enterShell = ''
    python -c "import control as ct" && echo "No errors!"
  '';
}

Finally, when we run the shell:

$ devenv shell
• Building shell ...
✔ Building shell in 1.1s.
• Entering shell
No errors!

Of course devenv is capable of a lot of things like running processes and services for you. If you’re interested to know more, I highly recommend you read the documentation.

4 Likes

Thanks, that seems to be just what I am looking for. I assume that python -c line is just to test whether it worked as intended?

Thanks everyone for your help, and @eljamm especially.

1 Like

You’re absolutely welcome :grin:

You’re right, we’re passing the program directly from the command line instead of running it from a file. So if python failed to load the module, we would have an error instead and the echo command wouldn’t run.

Therefore we have a quick way to know whether the library has been installed correctly or not.

1 Like