3

I have a Python library (https://github.com/jcrozum/PyStableMotifs) that I want to publish on PyPI. It depends on another library (https://github.com/hklarner/PyBoolNet) that I do not control and that is only available on GitHub, and in particular, it is not available on PyPI. My setup.py looks like this:

from setuptools import
setup(
    ... <other metadata> ...,
    install_requires=[
    'PyBoolNet @ git+https://github.com/hklarner/PyBoolNet@2.3.0',
    ... <other packages> ...
    ]
)

Running pip install git+https://github.com/jcrozum/PyStableMotifs works perfectly, but I can't upload this to PyPI because of the following error from twine:

Invalid value for requires_dist. Error: Can't have direct dependency: 'PyBoolNet @ git+https://github.com/hklarner/PyBoolNet@2.3.0'

My understanding is that direct links are forbidden by PyPI for security reasons. Nonetheless, PyBoolNet is a hard requirement for PyStableMotifs. What do I do? Give up on PyPI?

I just want pip install PyStableMotifs to work for my users. Ideally, this command should install the dependencies and I should not have to maintain two versions of setup.py.

Failing that, I have considered creating a "dummy" package on PyPI directing users to install using the command pip install git+https://github.com/jcrozum/PyStableMotifs. Is this a bad idea (or even possible)?

Are there already established best practices for this situation or other common workarounds?

EDIT: For now, I have a clunky and totally unsatisfying workaround. I'm keeping two versions; a GitHub version that works perfectly, and a PyPI version that has the PyBoolNet requirement removed. If the user tries to import PyStableMotifs without PyBoolNet installed, an error message is shown that has install instructions for PyBoolNet. This is far from ideal in my mind, but it will have to do until I can find a better solution or until PyPI fixes this bug (or removes this feature, depending on who you ask).

  • You would need to get `PyBoolNet` on an index somehow, not necessarily on PyPI, but of course it'd be easier for end users if that dependency is on PyPI as well. – sinoroc Jun 21 '21 at 21:30
  • 1
    Why would that help? I mean, obviously if it were on PyPI there'd be no issue, but if it were on some other index, wouldn't PyPI block that just like it blocks github? – Jordan Rozum Jun 21 '21 at 22:04
  • @JordanRozum: by "another index" he means "upload somewhere else _instead_ of PyPI", and instruct `pip` to install from there. PyPI would not block it because PyPI would not be involved at all. – MestreLion Feb 12 '23 at 08:55

1 Answers1

4

My recommendation would be to get rid of the direct URL in install_requires, and tell your users where they can find that dependency PyBoolNet since it is not on PyPI. Don't force them on a specific installation method, but show them an example.

Maybe simply tell your users something like:

This project depends on PyBoolNet, which is not available on PyPI. One place where you can find it is at: https://github.com/hklarner/PyBoolNet.

One way to install PyStableMotifs as well as its dependency PyBoolNet is to run the following command:

python -m pip install 'git+https://github.com/hklarner/PyBoolNet@2.3.0#egg=PyBoolNet' PyStableMotifs

You could additionnally prepare a requirements.txt file and tell your users:

Install with the following command:

python -m pip install --requirement https://raw.githubusercontent.com/jcrozum/PyStableMotifs/master/requirements.txt

The content of requirements.txt could be something like:

git+https://github.com/hklarner/PyBoolNet@2.3.0#egg=PyBoolNet
PyStableMotifs

But in the end, you should really let your users choose how to install that dependency. Your project only need to declare that it depends on that library but not how to install it.

sinoroc
  • 18,409
  • 2
  • 39
  • 70
  • This works, and it's basically what I'm doing for now, but it defeats my #1 reason for putting the package on PyPI: easy installation without having to look anything up. I don't see a reason to give users a choice on how to install PyBoolNet though; there's only one supported install method. Besides, this choice is already possible with pip's --no-deps option, right? – Jordan Rozum Jun 22 '21 at 20:01
  • Agreed, it is not great for the user experience. There really is no easy way out that I know of. -- You could consider taking care of the publishing on PyPI yourself. I don't know what the licensing of that library is. -- You could "_vendor_" that library. – sinoroc Jun 22 '21 at 20:24
  • 2
    It would probably not be appropriate for me to do that without permission, regardless of whether or not the license allows for it. But maybe I'll approach the authors about the possibility of a PyPI upload. – Jordan Rozum Jun 22 '21 at 21:46
  • Exactly. If I were you I would contact them and ask them to upload on PyPI and offer help with that if you can. – sinoroc Jun 23 '21 at 06:47
  • While this isn't ideal, I think it's probably the best solution possible within the restrictions PyPI has imposed, so I'll mark this as answered. Thanks for your help and advice. – Jordan Rozum Jun 25 '21 at 22:17