Adding an "unstructured" project to a flake

Hello,

I am trying to add a package to a flake. The package is laid out as follows:

baz
├── README.md
├── requirements.txt
├── resources
├── scripts
├── src
├── target
└── tests

where requirements.txt specifies python dependencies.

The advised installation procedure is basically:

virtualenv -p python3.7 venv
source venv/bin/activate
pip install -r requirements.txt
export PYTHONPATH=`pwd`

The application is run using

python src/main.py ...

The project seems to be mostly Python but doesn’t conform to Python packaging conventions.

My intuition is that the package could be handled by using by wrapping the main.py (like here) and (somehow) providing the requirements as buildInputs. But I am really not so sure.

I would be grateful of any guidance, advice, and recommendations on this.

Thanks!

Check out mach-nix or dream2nix if you want flake generators for Python

I have tried using a conventional derivation with the python deps handled by mach-nix like this:

Flake:

{
  description = "A Baz flake";
  
  inputs = {
    nixpkgs.url = github:NixOS/nixpkgs/nixos-21.11;
    flake-utils.url = "github:numtide/flake-utils";
    mach-nix = {
      url = "mach-nix/3.5.0";
    };
  };

  outputs = { self, nixpkgs, flake-utils, mach-nix }:
    flake-utils.lib.eachDefaultSystem (system:
      let 
        pkgs = import nixpkgs { inherit system; };
        machNix = mach-nix.lib."${system}";
        
        baz = pkgs.callPackage ./baz.nix { inherit machNix pkgs; };
                
      in rec {
        defaultPackage = packages.baz;
        packages.baz = baz;         
        packages.baz-wrapped = pkgs.writeScriptBin "baz" 
        ''
        python -c 'import scipy'
        '';

        devShell =  pkgs.mkShell {
          buildInputs = [
            pkgs.git
            pkgs.python3
            pkgs.python3Packages.ipython
            self.packages.${system}.baz
            self.packages.${system}.baz-wrapped
          ];
        };
        
      }
    );
}

Where the baz derivation (./baz.nix) is as

{pkgs, stdenv, machNix}:
let
  python-deps = machNix.mkPython {
      requirements = ''
      scipy
     '';
  };
in
stdenv.mkDerivation {
  name = "baz";
 
  src = builtins.fetchGit{
    url = "https://.../baz.git";
    ref = "master";
    rev = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
  }; 

  buildInputs = [
    python-deps
  ];
  
  installPhase = ''
    mkdir -p $out
    cp -r $src/*  $out
  '';
}

However, the Python dependency (scipy) is unknown to the baz script as demonstrated:

nix develop
baz
Traceback (most recent call last):
  File "<string>", line 1, in <module>
ModuleNotFoundError: No module named 'scipy'

I suppose I could look to somehow include the PYTHONPATH in the baz-wrapped, but … I’m not so sure that’s a good idea. maybe I’m going about this all wrong.

For those avidly following this thread, adding the PYTHONPATH to the wrapper script defined in the flake appears to suffice in the dev shell:

...
 packages.baz-wrapped = pkgs.writeScriptBin "baz" 
     ''
     export PYTHONPATH=${python-deps}/${python-deps.sitePackages}:$PYTHONPATH
     python ${packages.baz}/src/main.py
     '';
...