..

3 Minute Guide for Python on NixOS

Get python

Can’t figure out how to use python and all the templates are dummy verbose? Run nix flake init --template github:nix-community/poetry2nix. This gets you the flake you need.

The flake will look like this

{
  description = "Application packaged using poetry2nix";

  inputs = {
    flake-utils.url = "github:numtide/flake-utils";
    nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
    poetry2nix = {
      url = "github:nix-community/poetry2nix";
      inputs.nixpkgs.follows = "nixpkgs";
    };
  };

  outputs = { self, nixpkgs, flake-utils, poetry2nix }:
    flake-utils.lib.eachDefaultSystem (system:
      let
        # see https://github.com/nix-community/poetry2nix/tree/master#api for more functions and examples.
        pkgs = nixpkgs.legacyPackages.${system};
        inherit (poetry2nix.lib.mkPoetry2Nix { inherit pkgs; }) mkPoetryApplication;
      in
      {
        packages = {
          myapp = mkPoetryApplication { projectDir = self; };
          default = self.packages.${system}.myapp;
        };

        devShells.default = pkgs.mkShell {
          inputsFrom = [ self.packages.${system}.myapp ];
          packages = [ pkgs.poetry ];
        };
      });
}
  

Run nix flake update if you want more recent packages, but it doesn’t matter.

Add libraries from pip

Run nix flake develop to go into devshell. Now, you can add dependencies from pip just by doing poetry add <name of package>. It’ll get added to your pyproject.toml, which is where dependencies are tracked. Ctrl + D to back out of the shell, nix flake develop again to go back into it with the new dependencies. There, you’re done.

Want to add a nixpkgs dependency like jupyter? Just add pkgs.jupyter to devShells.default.pkgs.mkShell.packages like so

devShells.default = pkgs.mkShell {
  inputsFrom = [ self.packages.${system}.myapp ];
  packages = [ pkgs.poetry pkgs.jupyter];
};

Exit and re-enter the shell.

Can’t enter dev-shell because something’s not building

If something isn’t building right or it’s building a package from scratch and you don’t want to do that, add preferWheels = true like so:

packages = {
  myapp = mkPoetryApplication { projectDir = self; python = pkgs.python311; preferWheels = true;};
  default = self.packages.${system}.myapp;
};

This will pull prebuilt binaries from pip instead of trying to build from nixpkgs.

Change version of python used

Edit python = pkgs.python311 to whatever, and also update the number in your pyproject.toml. Exit and re-enter.