Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How should I handle importing third-party libraries within my setup.py script?

I'm developing a Python application and in the process of branching off a release. I've got a PyPI server set up on a company server and I've copied a source distribution of my package onto it.

I checked that the package was being hosted on the server and then tried installing it on my local development machine. I ended up with this output:

$ pip3 install --trusted-host 172.16.1.92 -i http://172.16.1.92:5001/simple/ <my-package>
Collecting <my-package>
  Downloading http://172.16.1.92:5001/packages/<my-package>-0.2.0.zip
    Complete output from command python setup.py egg_info:
    Traceback (most recent call last):
      File "<string>", line 1, in <module>
      File "C:\Users\<me>\AppData\Local\Temp\pip-build-ubb3jkpr\<my-package>\setup.py", line 9, in <module>
        import appdirs
    ModuleNotFoundError: No module named 'appdirs'

    ----------------------------------------
Command "python setup.py egg_info" failed with error code 1 in C:\Users\<me>\AppData\Local\Temp\pip-build-ubb3jkpr\<my-package>\

The reason is that I'm trying to import a third-party library appdirs in my setup.py, which is necessary for me to compute the data_files argument to setup():

try:
    from setuptools import setup
except ImportError:
    from distutils.core import setup

import os
from collections import defaultdict

import appdirs
from <my-package>.version import __version__ as <my-package>_version

APP_NAME = '<my-app>'
APP_AUTHOR = '<company>'
SYSTEM_COMPONENT_PLUGIN_DIR = os.path.join(appdirs.user_data_dir(APP_NAME, APP_AUTHOR), 'components')

# ...

setup(
    # ...
    data_files=component_files,
)

However, I don't have appdirs installed on my local dev machine and I don't expect the end users to have it either.

Is it acceptable to rely on third-party libraries like this in setup.py, and if so what is the recommended approach to using them? Is there a way I can ensure appdirs gets installed before it's imported in setup.py, or should I just document that appdirs is a required package to install my package?

like image 332
Tagc Avatar asked Jun 01 '17 13:06

Tagc


People also ask

How do you add an external library in Python?

Download the file linked here and then run it by running python get-pip.py in your terminal from the location where you downloaded the file. Once you have pip up and running, you can install external libraries which aren't part of standard library using pip in the terminal.

How do I install Python packages from setup py?

Installing Python Packages with Setup.py To install a package that includes a setup.py file, open a command or terminal window and: cd into the root directory where setup.py is located. Enter: python setup.py install.


2 Answers

You could use pip to install the package programmatically if the import fails:

try:
    import appdirs
except ImportError:
    import pip
    pip.main(['install', 'appdirs'])
    import appdirs

In some circumstances you may need to use importlib or __import__ to import the package after pip.main or referesh the PATH variable. It could also be worthwhile to include a verification if the user really wants to install that package before installing it.

I used a lot of the examples from "Installing python module within code" and I haven't personally tried used this in setup.py files but it looks like it could be a solution for your question.

like image 161
MSeifert Avatar answered Sep 30 '22 20:09

MSeifert


You can mention install_requires with the dependencies list. Please check the python packaging guide here. Also you can provide a requirements.txt file so that it can be run at once using "pip install -r"

like image 30
Venu Avatar answered Sep 30 '22 21:09

Venu