Instructions on installing PyGraphviz (Python package using setuptools C/C++ extension module) in a local venv?

I wanted to install pygraphviz using poetry, but I got the following error:

$ poetry add pygraphviz
...
  pygraphviz/graphviz_wrap.c:3023:10: 致命的エラー: graphviz/cgraph.h: No such file or directory
   3023 | #include "graphviz/cgraph.h"
        |          ^~~~~~~~~~~~~~~~~~~
  コンパイルを停止しました。
  error: command '/home/z/.nix-profile/bin/gcc' failed with exit code 1
  

  at /nix/store/aasf21i1lqwa7gl5nbxg9hrq775pdsl9-python3.12-poetry-1.8.4/lib/python3.12/site-packages/poetry/installation/chef.py:164 in _prepare
      160│ 
      161│                 error = ChefBuildError("\n\n".join(message_parts))
      162│ 
      163│             if error is not None:
    → 164│                 raise error from None
      165│ 
      166│             return path
      167│ 
      168│     def _prepare_sdist(self, archive: Path, destination: Path | None = None) -> Path:

Note: This error originates from the build backend, and is likely not a problem with poetry but with pygraphviz (1.14) not supporting PEP 517 builds. You can verify this by running 'pip wheel --no-cache-dir --use-pep517 "pygraphviz (==1.14)"'.

My understanding is that envfs and nix-ld are tools for binaries and libraries, respectively, and could not be used to resolve this error which is for a source file. Is it correct?

Anyway I ran the following command and I still got and error:
(Note that dot is one of the binaries in pkgs.graphviz)

$ export C_INCLUDE_PATH=$(nix-store -r $(which dot))/include
$ poetry add pygraphviz
...
  gcc -shared -L/nix/store/eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee-bzip2-1.0.8/lib -L/nix/store/eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee-expat-2.6.4/lib -L/nix/store/eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee-libffi-3.4.6/lib -L/nix/store/a7x8s7d3bhn41dqrai6nf5xszizb7fm2-libxcrypt-4.4.36/lib -L/nix/store/eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee-mpdecimal-4.0.0/lib -L/nix/store/eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee-ncurses-6.4.20221231/lib -L/nix/store/eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee-openssl-3.3.2/lib -L/nix/store/eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee-sqlite-3.46.1/lib -L/nix/store/eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee-xz-5.6.3/lib -L/nix/store/eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee-zlib-1.3.1/lib -L/nix/store/78mhfhbhfhvx95hjv9hkjx8m0vadynjv-tzdata-2024b/lib -L/nix/store/eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee-gdbm-1.24-lib/lib -L/nix/store/eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee-readline-8.2p13/lib -L/nix/store/eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee-bzip2-1.0.8/lib -L/nix/store/eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee-expat-2.6.4/lib -L/nix/store/eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee-libffi-3.4.6/lib -L/nix/store/a7x8s7d3bhn41dqrai6nf5xszizb7fm2-libxcrypt-4.4.36/lib -L/nix/store/eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee-mpdecimal-4.0.0/lib -L/nix/store/eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee-ncurses-6.4.20221231/lib -L/nix/store/eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee-openssl-3.3.2/lib -L/nix/store/eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee-sqlite-3.46.1/lib -L/nix/store/eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee-xz-5.6.3/lib -L/nix/store/eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee-zlib-1.3.1/lib -L/nix/store/78mhfhbhfhvx95hjv9hkjx8m0vadynjv-tzdata-2024b/lib -L/nix/store/eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee-gdbm-1.24-lib/lib -L/nix/store/eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee-readline-8.2p13/lib build/temp.linux-x86_64-cpython-312/pygraphviz/graphviz_wrap.o -L/nix/store/kjgslpdqchx1sm7a5h9xibi5rrqcqfnl-python3-3.12.8/lib -lcdt -lcgraph -lgvc -o build/lib.linux-x86_64-cpython-312/pygraphviz/_graphviz.cpython-312-x86_64-linux-gnu.so
  /nix/store/vk4mlknqk9yjbqa68a7rvpfxfdw3rad7-binutils-2.43.1/bin/ld: -lcdt が見つかりません: No such file or directory
  /nix/store/vk4mlknqk9yjbqa68a7rvpfxfdw3rad7-binutils-2.43.1/bin/ld: -lcgraph が見つかりません: No such file or directory
  /nix/store/vk4mlknqk9yjbqa68a7rvpfxfdw3rad7-binutils-2.43.1/bin/ld: -lgvc が見つかりません: No such file or directory
  collect2: エラー: ld はステータス 1 で終了しました
  error: command '/home/z/.nix-profile/bin/gcc' failed with exit code 1

I added graphviz to nix-ld.libraries but it has no effect (same error occurs) while I can confirm that import numpy does not raise error (both after running export LD_LIBRARY_PATH = $NIX_LD_LIBRARY_PATH). (Why?)

  programs.nix-ld = {
    enable = true;
    libraries = (with pkgs; [
      zlib
      zstd
      stdenv.cc.cc
      curl
      openssl
      attr
      libssh
      bzip2
      libxml2
      acl
      libsodium
      util-linux
      xz
      systemd
      # pygraphviz-specific deps
      graphviz
      coreutils
    ]);
  };

So I had to set $LIBRARY_PATH as well.

$ export C_INCLUDE_PATH=$(nix-store -r $(which dot))/include
$ export LIBRARY_PATH=$(nix-store -r $(which dot))/lib
$ poetry add pygraphviz==1.10

Updating dependencies
Resolving dependencies... (0.7s)

Package operations: 0 installs, 1 update, 0 removals

  - Downgrading pygraphviz (1.14 -> 1.10)

Writing lock file

The above method worked to a point, but is there a better way to do this?

Usually managing projects’ dependencies on a NixOS machine is not done directly with tools like Poetry, who are designed for Systems with FHS in mind. I know there exists this project:

But personally I never used it. I personally use a flake.nix with a devShell, along with direnv to automate the exporting of environment variables required for running my Python projects. This approach is the most minimalist, but it is not very portable if you are working on a project along with people who use other Python package mangers.

1 Like