try import if not, install in python - python

I'm trying to install automatically each library in python if it isn't installed.
#!/usr/bin/python
# -*- coding: utf-8 -*-
from pip._internal import main
pkgs = ['Bio==0.1.0','argparse==1.4.0']
for package in pkgs:
try:
import package
except ImportError:
main(['install', package])
But, this error occurs:
Collecting Bio==0.1.0
Using cached https://files.pythonhosted.org/packages/14/c2/43663d53b93ef7b4d42cd3550631552887f36db02c0150d803c69ba636a6/bio-0.1.0-py2.py3-none-any.whl
Installing collected packages: Bio
Successfully installed Bio-0.1.0
Collecting argparse==1.4.0
Using cached https://files.pythonhosted.org/packages/f2/94/3af39d34be01a24a6e65433d19e107099374224905f1e0cc6bbe1fd22a2f/argparse-1.4.0-py2.py3-none-any.whl
ERROR: Could not install packages due to an EnvironmentError: [Errno2] No such file or directory: '/tmp/pip-req-tracker-6sqtap8q/139713c65f8ac559a034717470dc5a6e30a6db86bdc3d69fe2bc0e63'
I notice that this occur always after the first library installation, e.g.: If I change ['Bio','argparse'] for ['argparse','Bio'], then argparse will be installed, but Bio will not.

Do not do this.
Instead:
either actually package your Python project properly with accurate dependencies (look up setuptools, poetry, flit, or any other similar project);
or instruct your users to install your project's dependencies themselves, you can facilitate this by providing a pip-compatible requirements.txt file.
Additional note here is how to "Using pip from your program".

Related

Python cannot import name 'find_namespace_packages' from 'setuptools' package

I'm currently creating a python library and need to use the 'find_namespace_packages' from the 'setuptools' package. However python throwing out the following ImportError message whenever it runs:
ImportError: cannot import name 'find_namespace_packages' from 'setuptools'
However it has no trouble importing the other functions from 'setuptools' like 'setup' and 'find_packages'.
How do I troubleshoot it?
I have uninstalled and reinstalled 'setuptools' multiple times already and updated Spyder and Anaconda.
Also here is a sample of my code:
from setuptools import setup, find_namespace_packages
setup(
name="sample",
version="0.0.1",
packages=find_namespace_packages()
)
I am currently using Python 3.7.5 and setuptools is on version 49.6.0
As mentioned in the question's comments, the solution is to run
pip install -U setuptools
And afterwards retry installing all the packages, e.g.
pip install -e .

ModuleNotFoundError after successful pip install in Google Colaboratory

I'm trying to import a package I wrote into a Google Colaboratory notebook. I uploaded the package contents to my Drive, then ran:
[ ] from google.colab import drive
[ ] drive.mount('content/gdrive/')
[ ] ! pip install --user /content/gdrive/My\ Drive/my-package
Processing ./gdrive/My Drive/my-package
Building wheels for collected packages: my-package
Building wheel for my-package (setup.py) ... done
Created wheel for my-package:
Stored in directory:
Successfully built my-package
Installing collected packages: my-package
Successfully installed my-package-1.0.0.dev1
pip list shows the package has been successfully installed. However, imports of the package fail with a ModuleNotFoundError.
I've successfully pip installed and imported my-package on my local machine. I've also successfully installed and imported another Python package through the same Colab notebook using pip install --user. As mentioned here, I've also tried restarting the kernel.
This may be related to this related but unanswered question.
The github page you linked to about restarting the runtime was a little ambiguous IMO, so I just wanted to clarify:
You need to run the !pip install cell. Then "Restart Runtime." Then run your import statement cell.
I might suggest you "Reset all Runtimes" before performing these steps, just to make sure you have a clean slate.
-- If the above steps are what you already did:
Are you using a Python 2 or 3 notebook? (not 100% sure why that would matter, but more info would be good)
Did you pip install to your local machine from the google drive link? (If not, try to see if that works and report back)
The editable install (or setuptools development-mode) appends the module path to an easy-install.pth file. The site module processes these files when python is started and appends the paths to sys.path. That's why it works only after restarting the runtime.
One can avoid restarting the colab notebook by importing the site module and (re)running site.main().
%pip install -e pkg
import site
site.main()
import pkg
However in the example below this has the effect of removing the current directory from sys.path and replacing it with its absolute path.
%pip install -e "git+https://github.com/jd/tenacity#egg=tenacity"
print("\nTrying to import tenacity")
try:
import tenacity
except ImportError as exc:
print("ImportError")
print(exc)
print()
import sys, site
print("\n##### sys.path original #####")
for p in sys.path:
print(f"'{p}'")
print()
site.main()
print("\n##### sys.path after site.main() #####")
for p in sys.path:
print(f"'{p}'")
print()
import tenacity
print(f"\nImported tenacity from {tenacity.__file__}")
Prints
Obtaining tenacity from git+https://github.com/jd/tenacity#egg=tenacity
Cloning https://github.com/jd/tenacity to ./src/tenacity
Running command git clone -q https://github.com/jd/tenacity /content/src/tenacity
Requirement already satisfied: six>=1.9.0 in /usr/local/lib/python3.6/dist-packages (from tenacity) (1.15.0)
Installing collected packages: tenacity
Running setup.py develop for tenacity
Successfully installed tenacity
Trying to import tenacity
ImportError
No module named 'tenacity'
##### sys.path original #####
''
'/env/python'
'/usr/lib/python36.zip'
'/usr/lib/python3.6'
'/usr/lib/python3.6/lib-dynload'
'/usr/local/lib/python3.6/dist-packages'
'/usr/lib/python3/dist-packages'
'/usr/local/lib/python3.6/dist-packages/IPython/extensions'
'/root/.ipython'
##### sys.path after site.main() #####
'/content'
'/env/python'
'/usr/lib/python36.zip'
'/usr/lib/python3.6'
'/usr/lib/python3.6/lib-dynload'
'/usr/local/lib/python3.6/dist-packages'
'/usr/lib/python3/dist-packages'
'/usr/local/lib/python3.6/dist-packages/IPython/extensions'
'/root/.ipython'
'/content/src/tenacity'
Imported tenacity from /content/src/tenacity/tenacity/__init__.py
Example colab notebook: https://colab.research.google.com/drive/1S5EU-MirhaTWz1JJVdos3GcojmOSLC1C?usp=sharing
Stumbled onto this via the blog post: https://yidatao.github.io/2016-05-10/Python-easyinstall-generates-pth-file/
Thanks to #jojo's suggestion, I uninstalled and reinstalled the package on my local machine and was able to diagnose the problem. On both my local machine and in Colab I was able to successfully install and import the package only when including the -e (editable) flag in the pip command (pip install --user -e /content/gdrive/My\ Drive/my-package), and restarting the runtime after installation). I have no idea why including the -e flag would make a difference; please comment if you have any insight!

No module named yaml (brew broke my python, again)

homebrew has again broken python for about third time. Im now having issues getting dependencies to work again. At this point I am unable to install yaml.
Collecting yaml
Could not find a version that satisfies the requirement yaml (from versions: )
No matching distribution found for yaml
Some other suggestions have said to try pyaml, which again simply tries to import yaml and fails
Traceback (most recent call last):
File "script.py", line 13, in <module>
import pyaml
File "/~/virtualenv/project/lib/python2.7/site-packages/pyaml/__init__.py", line 6, in <module>
import os, sys, io, yaml
ImportError: No module named yaml
Anyone have an idea how to get this sorted out?
There are two packages with somewhat unfortunate naming in the Python Package Index.
pip install pyyaml lets you import yaml. This package enables Python to parse YAML files.
pip install pyaml lets you import pyaml. This package allows pretty-printing of YAML files from Python, among other things. It requires pyyaml to be installed.
So the way forward for you is:
Install pyyaml, preferably using pip
Install pyaml
Profit
Step 0 would be to run everything from a virtual environment to prevent homebrew from messing with your Python ever again. This option also lets you run multiple versions of Python, not just the one required by homebrew.
The solution for me turned out to be homebrew changing python to python2, which I believe precludes using the brew version instead of the system version
eg python script.py >> python2 script.py
Additionally, linking the system version of python to the brew python2 version helped as well:
cd /usr/local/bin && ln -s ../Cellar/python/2.7.13_1/bin/python2 python
I'm also hesitant the accepted answer will work, as pyaml is still attempting to import yaml, via __init__.py; which does not exist even after installing both packages
$ pip install pyaml
Collecting pyaml
Using cached pyaml-17.7.2-py2.py3-none-any.whl
Requirement already satisfied: PyYAML in ~/Library/Python/2.7/lib/python/site-packages (from pyaml)
Installing collected packages: pyaml
Successfully installed pyaml-17.7.2
$ pip install yaml
Collecting yaml
Could not find a version that satisfies the requirement yaml (from versions: )
No matching distribution found for yaml
eg
File "/~/virtualenv/project/lib/python2.7/site-packages/pyaml/__init__.py", line 6, in <module>
import os, sys, io, yaml

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?
I'm ignoring licensing issues in this answer. You definetly need to take these into account before you really do a release.
Is it acceptable to rely on third-party libraries like this in setup.py
Yes, it is acceptable but generally these should be minimized, especially if these are modules which have no obvious use for the end-user. Noone likes to have packages they don't need or use.
what is the recommended approach to using them?
There are basically 3 options:
Bootstrap them (for example use pip to programmatically install packages). For example setuptools provides an ez_setup.py file that can be used to bootstrap setuptools. Maybe that can be customized to download and install appdirs.
Include them (especially if it's a small package) in your project. For example appdirs is basically just a single file module. Pretty easy to copy and maintain in your project. Be very careful with licensing issues when you do that!
Fail gracefully when it's not possible to import them and let the user install them. For example:
try:
import appdirs
except ImportError:
raise ImportError('this package requires "appdirs" to be installed. '
'Install it first: "pip install appdirs".')
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.
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"

Setup.py attempts to import the package it is installing

UPDATE
This is a bug in the setup.py of the package
Attempting to install certain packages using pip and I get this error:
pip install saspy
command python setup.py egg_info failed with error code 1
Upon reading the traceback I see that it failed while attempting to import saspy.This is an excerpt from the setup.py which is indeed attempting to import from saspy, while installing saspy. How is this supposed to work? I am using setuptools 36.0.1, pip 9.0.1 and (long story) python 2.7.8.
try:
from setuptools import setup
except ImportError:
from distutils.core import setup
from saspy import __version__
with open('README.md') as f:
readme = f.read()
This is a buggy setup.py. It's a common mistake, since with a source installation, you can import the package from the unpacked source tree before it's been installed.
saspy requires Python3. I would expect this issue is due to using Python2 to try to install it. Though I have never seen that error before when installing it.

Categories

Resources