pythonpypipython-packaginghatch

How to automatically download or warn about a non-PyPi dependency of a Python package?


I have a Python package, which is distributed on PyPi. It depends on number of other packages available on PyPi and on Psi4, which is only distributed on Conda repositories (https://anaconda.org/psi4/psi4), not on PyPi.

Now, my package is distributed as wheel package via hatchling, so my pyproject.toml looks similar to this:

[build-system] 
requires = ["hatchling"] 
build-backend = "hatchling.build" 

[project] 
name = "My project" 
version = "1.0.0" 
authors = [ ] 
description = "New method" 
readme = "README.md" requires-python = ">=3.12" 
classifiers = [     
    "Programming Language :: Python :: 3",     
    "License :: OSI Approved :: GNU General Public License v3 (GPLv3)",     
    "Operating System :: POSIX :: Linux", ] 

dependencies = [     
    "qiskit==1..0",     
    "qiskit-nature>=0.5.1",
    "numpy>=1.23.0",     
    "deprecated>=1.2.0"] 

Is there any way to deal with such an external dependency automatically? Ideally it'd download and install Psi4 from its repositories, but if not, is there any way to get at least a warning before the download from PyPi starts?

I had a look around and found this related question, which, unfortunately, got no answers:


Solution

  • If you use a setup.py instead of pyproject.toml, you can add an installation check for psi4. pyproject.toml does not natively support conda packages.

    For setup.py, you can approach it like:

    import subprocess
    import sys
    
    try:
        import psi4
    except ImportError:
        subprocess.check_call([sys.executable, "-m", "conda", "install", "-c", "psi4", "psi4"])
    
    from setuptools import setup
    
    setup(
        # Your package configuration here
    )
    

    For more information on setuptools and how to create it to replicate the work of your pyproject.toml see here.

    Additionally, You can add in your README.md about the conda dependency.

    When the pypi package is downloaded, setup.py is run automatically and therefore you can also add a warning in there too if you dont want to install it directly.

    This approach work with sdist and not with wheels as they bypass it as mentioned in the comments by @phd.

    For wheels, you can add a piece of code in your project itself to check for psi4 and either warn and exit or install it.

    before you begin your work in the code file add something like this:

    try:
        import psi4
    except ImportError:
        raise ImportError("Psi4 is required but not installed. Please install it via Conda: "
                          "`conda install -c conda-forge psi4`.")
    

    Additionally, You can add it in your README.md and also add a long description where it is stated properly that psi4 is a requirement.