Python: Difference between revisions

Python environments with Nix: add poetry shell.nix example
Dyego (talk | contribs)
m add Using nix-shell alongside pip section
Line 107: Line 107:


Next time you enter the shell specified by this file, Nix will build and include the Python package you have written.
Next time you enter the shell specified by this file, Nix will build and include the Python package you have written.
==== Using nix-shell alongside pip  ====
When working on a collaborative python project you may want to be able to <code>pip install -r requirements.txt</code> if the project isn't packaged for nix specifically.
The problem is that a lot of python packages won't work out of the box when you pip install them.
To fix this issue, you can create a nix shell that will use <code>pip</code> for the packages that are installing properly, but will fix the environment for the packages that are causing issues.
You can accomplish this by adding these two files to the root of your project:
<syntaxhighlight lang="nix" line="1">
# shell.nix
{ pkgs ? import <nixpkgs> {} }:
let
  myPython = pkgs.python311;
  pythonPackages = pkgs.python311Packages;
  pythonWithPkgs = myPython.withPackages (pythonPkgs: with pythonPkgs; [
    # This list contains tools for Python development.
    # You can also add other tools, like black.
    #
    # Note that even if you add Python packages here like PyTorch or Tensorflow,
    # they will be reinstalled when running `pip -r requirements.txt` because
    # virtualenv is used below in the shellHook.
    ipython
    pip
    setuptools
    virtualenvwrapper
    wheel
    black
  ]);
  extraLibPackages = [
    # If you want to use CUDA, you should uncomment this line.
    # linuxPackages.nvidia_x11
  ];
  extraBuildInputs = with pkgs; [
    # this list contains packages that you want to be available at runtime and might not be able to be installed propely via pip
    # pythonPackages.pandas
    # pythonPackages.requests
  ];
in
import ./python-shell.nix {
    extraBuildInputs=extraBuildInputs;
    extraLibPackages=extraLibPackages;
    myPython=myPython;
    pythonWithPkgs=pythonWithPkgs;
}
</syntaxhighlight>
<syntaxhighlight lang="nix" line="1">
# python-shell.nix
{ pkgs ? import <nixpkgs> {}, extraBuildInputs ? [], myPython ? pkgs.python3, extraLibPackages ? [], pythonWithPkgs? myPython }:
let
    buildInputs  = with pkgs; [
        clang
        llvmPackages_16.bintools
        rustup
    ] ++ extraBuildInputs;
  lib-path = with pkgs; lib.makeLibraryPath buildInputs;
shell = pkgs.mkShell {
  buildInputs = [
    # my python and packages
      pythonWithPkgs
     
      # other packages needed for compiling python libs
      pkgs.readline
      pkgs.libffi
      pkgs.openssl
      # unfortunately needed because of messing with LD_LIBRARY_PATH below
      pkgs.git
      pkgs.openssh
      pkgs.rsync
  ] ++ extraBuildInputs;
  shellHook = ''
      # Allow the use of wheels.
      SOURCE_DATE_EPOCH=$(date +%s)
      # Augment the dynamic linker path
      export "LD_LIBRARY_PATH=$LD_LIBRARY_PATH:${lib-path}"
      # Setup the virtual environment if it doesn't already exist.
      VENV=.venv
      if test ! -d $VENV; then
        virtualenv $VENV
      fi
      source ./$VENV/bin/activate
      export PYTHONPATH=$PYTHONPATH:`pwd`/$VENV/${myPython.sitePackages}/
  '';
};
in
shell
</syntaxhighlight>


=== Using poetry ===
=== Using poetry ===