Declarative python enviroment

Short description

Hello, I’d like to have a declarative python environment.

I just need three python libraries, duckdb, polars, prefect.

I don’t why I cannot build polars from Pypi.

Thanks in advance!

Issue

…/pipeline_template ->> : nix-shell                                                                                                             on  master [!?] 
these 2 derivations will be built:
  /nix/store/xl43aklgylgz9gvfwyr74lvj7xrjk7hj-python3.12-polars-1.6.0.drv
  /nix/store/d3f223akr88wfk951hzbava26f72p8sg-python3-3.12.4-env.drv
building '/nix/store/xl43aklgylgz9gvfwyr74lvj7xrjk7hj-python3.12-polars-1.6.0.drv'...
Sourcing python-remove-tests-dir-hook
Sourcing python-catch-conflicts-hook.sh
Sourcing python-remove-bin-bytecode-hook.sh
Sourcing pypa-build-hook
Using pypaBuildPhase
Sourcing python-runtime-deps-check-hook
Using pythonRuntimeDepsCheckHook
Sourcing pypa-install-hook
Using pypaInstallPhase
Sourcing python-imports-check-hook.sh
Using pythonImportsCheckPhase
Sourcing python-namespaces-hook
Sourcing python-catch-conflicts-hook.sh
Running phase: unpackPhase
unpacking source archive /nix/store/pqrpak917x4195lz0xzzzwdj9czamk7j-polars-1.6.0.tar.gz
source root is polars-1.6.0
setting SOURCE_DATE_EPOCH to timestamp 1724864614 of file polars-1.6.0/rust-toolchain.toml
Running phase: patchPhase
Running phase: updateAutotoolsGnuConfigScriptsPhase
Running phase: configurePhase
no configure script, doing nothing
Running phase: buildPhase
Executing pypaBuildPhase
Creating a wheel...
* Getting build dependencies for wheel...

Traceback (most recent call last):
  File "/nix/store/jdw00ayxjyis42x0w5vvi6knxc7b6q4p-python3.12-pyproject-hooks-1.0.0/lib/python3.12/site-packages/pyproject_hooks/_impl.py", line 321, in _call_hook
    raise BackendUnavailable(data.get('traceback', ''))
pyproject_hooks._impl.BackendUnavailable: Traceback (most recent call last):
  File "/nix/store/jdw00ayxjyis42x0w5vvi6knxc7b6q4p-python3.12-pyproject-hooks-1.0.0/lib/python3.12/site-packages/pyproject_hooks/_in_process/_in_process.py", line 77, in _build_backend
    obj = import_module(mod_path)
          ^^^^^^^^^^^^^^^^^^^^^^^
  File "/nix/store/04gg5w1s662l329a8kh9xcwyp0k64v5a-python3-3.12.4/lib/python3.12/importlib/__init__.py", line 90, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "<frozen importlib._bootstrap>", line 1387, in _gcd_import
  File "<frozen importlib._bootstrap>", line 1360, in _find_and_load
  File "<frozen importlib._bootstrap>", line 1324, in _find_and_load_unlocked
ModuleNotFoundError: No module named 'maturin'

ERROR Backend 'maturin' is not available.
error: builder for '/nix/store/xl43aklgylgz9gvfwyr74lvj7xrjk7hj-python3.12-polars-1.6.0.drv' failed with exit code 1;
       last 10 log lines:
       >           ^^^^^^^^^^^^^^^^^^^^^^^
       >   File "/nix/store/04gg5w1s662l329a8kh9xcwyp0k64v5a-python3-3.12.4/lib/python3.12/importlib/__init__.py", line 90, in import_module
       >     return _bootstrap._gcd_import(name[level:], package, level)
       >            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
       >   File "<frozen importlib._bootstrap>", line 1387, in _gcd_import
       >   File "<frozen importlib._bootstrap>", line 1360, in _find_and_load
       >   File "<frozen importlib._bootstrap>", line 1324, in _find_and_load_unlocked
       > ModuleNotFoundError: No module named 'maturin'
       >
       > ERROR Backend 'maturin' is not available.
       For full logs, run 'nix log /nix/store/xl43aklgylgz9gvfwyr74lvj7xrjk7hj-python3.12-polars-1.6.0.drv'.
error: 1 dependencies of derivation '/nix/store/d3f223akr88wfk951hzbava26f72p8sg-python3-3.12.4-env.drv' failed to build

shell.nix

# shell.nix
let
  pkgs = import <nixpkgs> {};

  python = pkgs.python3.override {
    self = python;
    packageOverrides = pyfinal: pyprev: {
      toolz = pyfinal.callPackage ./toolz.nix { };
      polars = pyfinal.callPackage ./polars.nix { };
      prefect = pyfinal.callPackage ./prefect.nix { };
    };
  };

in pkgs.mkShell {
  packages = [
    (python.withPackages (python-pkgs: [
      # select Python packages here
      python-pkgs.pandas
      python-pkgs.requests
      python-pkgs.toolz
#      python-pkgs.prefect
      python-pkgs.polars
    ]))
  ];
}

polars.nix

{ lib
, buildPythonPackage
, fetchPypi
, setuptools
, wheel
, pkgs
}:

buildPythonPackage rec {
  pname = "polars";
  version = "1.6.0";

  src = fetchPypi {
    inherit pname version;
    hash = "sha256-1+jV5XeIOpdVvDvpLsv28gvO1oJnvbi9tEASDpBcwZw=";
  };

  nativeBuildInputs = [ pkgs.maturin ];
  
  postPatch = ''
    export PATH=${pkgs.maturin}/bin:$PATH
  ''; 

  # do not run tests
  doCheck = false;

  # specific to buildPythonPackage, see its reference
  pyproject = true;
  build-system = [
    setuptools
    wheel
  ];
}