Related
i have a very simple python/typer program.
i also use the poetry as build tool.
This is a snippet of my pyproject.toml file:
name = "cat-cli"
version = "0.1.3"
description = "Cat Cli"
Is there a simple way get the version number specified in the toml file into my python program?
Thank you in advance
The canonical way of getting the version number of an installed package, is to use importlib.metadata or its backport importlib-metadata if you are on Python <3.8.
try:
from importlib import metadata
except ImportError:
import importlib_metadata as metadata
version = metadata.version("mypackage")
You could use a package like tomli to read the poetry configuration file and get the version using something like:
import tomli
with open("pyproject.toml", mode="r") as config:
toml_file = tomli.load(config)
toml_file['tool.poetry']['version'] should get you the version string, assuming you have the tool.poetry table.
Follow this guide to get you started
I have installed the eccodes library using Conda, but when I try to import it in Python I get "Cannot find the ecCodes library".
Why do I get this error and how can I resolve it? I think that Python does not know where to find the library.
I used the commands found here. That is,
conda install -c conda-forge eccodes
pip3 install --upgrade eccodes
I am using a Windows machine.
After asking a colleague we found a solution by running the code
import ecmwflibs
Now eccodes is recognised
He found this because the error message was raised by the script in
~/Anaconda3/Lib/site-packages/gribapi/bindings.py
#
# (C) Copyright 2017- ECMWF.
#
# This software is licensed under the terms of the Apache Licence Version 2.0
# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
#
# In applying this licence, ECMWF does not waive the privileges and immunities
# granted to it by virtue of its status as an intergovernmental organisation nor
# does it submit to any jurisdiction.
#
# Authors:
# Alessandro Amici - B-Open - https://bopen.eu
# Shahram Najm - ECMWF - https://www.ecmwf.int
#
from __future__ import absolute_import, division, print_function, unicode_literals
import logging
import pkgutil
import cffi
__version__ = "1.4.2"
LOG = logging.getLogger(__name__)
try:
import ecmwflibs as findlibs
except ImportError:
import findlibs
library_path = findlibs.find("eccodes")
if library_path is None:
raise RuntimeError("Cannot find the ecCodes library")
# default encoding for ecCodes strings
ENC = "ascii"
ffi = cffi.FFI()
CDEF = pkgutil.get_data(__name__, "grib_api.h")
CDEF += pkgutil.get_data(__name__, "eccodes.h")
ffi.cdef(CDEF.decode("utf-8").replace("\r", "\n"))
lib = ffi.dlopen(library_path)
I wouldn't mess with Pip here. Conda Forge provides both the compiled library (eccodes) and the Python bindings (python-eccodes). The latter lists the former as a dependency, so it should be sufficient to use:
conda install -c conda-forge python-eccodes
I know how to see installed Python packages using pip, just use pip freeze. But is there any way to see the date and time when package is installed or updated with pip?
If it's not necessary to differ between updated and installed, you can use the change time of the package file.
Like that for Python 2 with pip < 10:
import pip, os, time
for package in pip.get_installed_distributions():
print "%s: %s" % (package, time.ctime(os.path.getctime(package.location)))
or like that for newer versions (tested with Python 3.7 and installed setuptools 40.8 which bring pkg_resources):
import pkg_resources, os, time
for package in pkg_resources.working_set:
print("%s: %s" % (package, time.ctime(os.path.getctime(package.location))))
an output will look like numpy 1.12.1: Tue Feb 12 21:36:37 2019 in both cases.
Btw: Instead of using pip freeze you can use pip list which is able to provide some more information, like outdated packages via pip list -o.
Unfortunately, python packaging makes this a bit complicated since there is no consistent place that lists where the package files or module directories are placed.
Here's the best I've come up with:
#!/usr/bin/env python
# Prints when python packages were installed
from __future__ import print_function
from datetime import datetime
import os
import pip
if __name__ == "__main__":
packages = []
for package in pip.get_installed_distributions():
package_name_version = str(package)
try:
module_dir = next(package._get_metadata('top_level.txt'))
package_location = os.path.join(package.location, module_dir)
os.stat(package_location)
except (StopIteration, OSError):
try:
package_location = os.path.join(package.location, package.key)
os.stat(package_location)
except:
package_location = package.location
modification_time = os.path.getctime(package_location)
modification_time = datetime.fromtimestamp(modification_time)
packages.append([
modification_time,
package_name_version
])
for modification_time, package_name_version in sorted(packages):
print("{0} - {1}".format(modification_time,
package_name_version))
Solution 1 : packages.date.py :
import os
import time
from pip._internal.utils.misc import get_installed_distributions
for package in get_installed_distributions():
print (package, time.ctime(os.path.getctime(package.location)))
Solution 2 : packages.alt.date.py :
#!/usr/bin/env python
# Prints when python packages were installed
from __future__ import print_function
from datetime import datetime
from pip._internal.utils.misc import get_installed_distributions
import os
if __name__ == "__main__":
packages = []
for package in get_installed_distributions():
package_name_version = str(package)
try:
module_dir = next(package._get_metadata('top_level.txt'))
package_location = os.path.join(package.location, module_dir)
os.stat(package_location)
except (StopIteration, OSError):
try:
package_location = os.path.join(package.location, package.key)
os.stat(package_location)
except:
package_location = package.location
modification_time = os.path.getctime(package_location)
modification_time = datetime.fromtimestamp(modification_time)
packages.append([
modification_time,
package_name_version
])
for modification_time, package_name_version in sorted(packages):
print("{0} - {1}".format(modification_time,
package_name_version))
Solution 1 & 2 compatibility :
updated solution for pip v10.x
python v2, v2.7, v3, v3.5, v3.7
I was recently looking for this too. But although there are many good answers here, the real issue is that since pip is not keeping logs by default, we have to resort to using the file creation and modification times, known as ctime and mtime, respectively. (See MAC-times.) Unfortunately, using this method has two side effects:
Different OS's and FS's handles the ctime/mtime differently (if even available)
Python installations are using many different directories, and some remain after installations while others are created on the fly when running. Making it hard to know exaclty what files to check the dates on.
However, there is a tool called pip-date that try to combine a few different methods.
pip install pip-date
You could use the --log option:
--log <path> Path to a verbose appending log. This log is inactive by default.
E.g:
$ pip install --log ~/.pip/pip.append.log gunicorn
Or you can set it in your pip.conf to be enabled by default:
[global]
log = <path>
Then all the pip operations will be logged verbosely into the specified file along with a log separator and timestamp, e.g.:
$ pip install --log ~/.pip/pip.append.log gunicorn
$ pip install --log ~/.pip/pip.append.log --upgrade gunicorn
logs the following to ~/.pip/pip.append.log:
------------------------------------------------------------
/usr/bin/pip run on Mon Jul 14 14:35:36 2014
Downloading/unpacking gunicorn
...
Successfully installed gunicorn
Cleaning up...
------------------------------------------------------------
/usr/bin/pip run on Mon Jul 14 14:35:57 2014
Getting page https://pypi.python.org/simple/gunicorn/
URLs to search for versions for gunicorn in /usr/lib/python2.7/site-packages:
* https://pypi.python.org/simple/gunicorn/
...
Requirement already up-to-date: gunicorn in /usr/lib/python2.7/site-packages
Cleaning up...
You could parse out what you need from this log. While not the nicest it's a standard pip facility.
I don't know all pip options but for one module you can get list of its files
and then you can check its dates using python or bash.
For example list of files in requests module
pip show --files requests
result:
Name: requests
Version: 2.2.1
Location: /usr/local/lib/python2.7/dist-packages
Requires:
Files:
../requests/hooks.py
../requests/status_codes.py
../requests/auth.py
../requests/models.py
etc.
BTW: you can use --help to see more options for some functions
pip --help
pip list --help
pip show --help
etc.
pip freeze gives you all the installed packages. Assuming you know the folder:
time.ctime(os.path.getctime(file))
should give you the creation time of a file, i.e. date of when the package has been installed or updated.
Trying to install a GeoDjango on my machine. I'm really new to Python and being brought into a project that has been a very tricky install for the other team members. I installed Python 2.7 and GEOS using brew, and running PSQL 9.2.4 but keep getting this error when I try to get the webserver running:
__import__(name)
File "/Users/armynante/Desktop/uclass-files/uclass-env/lib/python2.7/site
packages/django/contrib/gis/geometry/backend/geos.py", line 1, in <module>
from django.contrib.gis.geos import (
File "/Users/armynante/Desktop/uclass-files/uclass-env/lib/python2.7/site
packages/django/contrib/gis/geos/__init__.py", line 6, in <module>
from django.contrib.gis.geos.geometry import GEOSGeometry, wkt_regex, hex_regex
File "/Users/armynante/Desktop/uclass-files/uclass-env/lib/python2.7/site
packages/django/contrib/gis/geos/geometry.py", line 14, in <module>
from django.contrib.gis.geos.coordseq import GEOSCoordSeq
File "/Users/armynante/Desktop/uclass-files/uclass-env/lib/python2.7/site-
packages/django/contrib/gis/geos/coordseq.py", line 9, in <module>
from django.contrib.gis.geos.libgeos import CS_PTR
File "/Users/armynante/Desktop/uclass-files/uclass-env/lib/python2.7/site-
packages/django/contrib/gis/geos/libgeos.py", line 119, in <module>
_verinfo = geos_version_info()
File "/Users/armynante/Desktop/uclass-files/uclass-env/lib/python2.7/site
packages/django/contrib/gis/geos/libgeos.py", line 115, in geos_version_info
if not m: raise GEOSException('Could not parse version info string "%s"' % ver)
django.contrib.gis.geos.error.GEOSException: Could not parse version info string
"3.4.2-CAPI-1.8.2 r3921"
Cant seem to find anything relevant to this trace on SO or the web. I think it might be a regex failure? I'm currently trying to reinstall PSQL and GEOS to see if I can get it running.
Here is my requirements file:
django==1.4
psycopg2==2.4.4
py-bcrypt==0.4
python-memcached==1.48
south==0.7.3
# Debug Tools
sqlparse==0.1.3
django-debug-toolbar==0.9.1
django-devserver==0.3.1
# Deployment
fabric==1.4
# AWS
# boto==2.1.1
django-storages==1.1.4
django-ses==0.4.1
# ECL
http://packages.elmcitylabs.com/ecl_django-0.5.3.tar.gz#ecl_django
http://packages.elmcitylabs.com/ecl_google-0.2.14.tar.gz#ecl_google
# https://packages.elmcitylabs.com/ecl_tools-0.3.7.tar.gz#ecl_tools
# https://packages.elmcitylabs.com/chargemaster-0.2.19.tar.gz
# https://packages.elmcitylabs.com/ecl_facebook-0.3.12.tar.gz#ecl_facebook
# https://packages.elmcitylabs.com/ecl_twitter-0.3.3.tar.gz#ecl_twitter
# Search
#https://github.com/elmcitylabs/django-haystack/tarball/issue-522#django-haystack
-e git+https://github.com/toastdriven/django-haystack.git#egg=django-haystack
pysolr==2.1.0-beta
# whoosh==2.3.2
# Misc
# PIL
# django-shorturls==1.0.1
# suds==0.4
django-mptt
sorl-thumbnail
stripe
pytz==2013b
This is my solution (obviously it is ugly, like my English, but works).
The problem is that the versions string has an white space unwanted in the RegEx.
The error says:
GEOSException: Could not parse version info string "3.4.2-CAPI-1.8.2 r3921"
And the geos_version_info warns:
Regular expression should be able to parse version strings such as
'3.0.0rc4-CAPI-1.3.3', '3.0.0-CAPI-1.4.1' or '3.4.0dev-CAPI-1.8.0'
Edit this file: site-packages/django/contrib/gis/geos/libgeos.py
Look for the function: geos_version_info
And change this line:
ver = geos_version().decode()
With this line:
ver = geos_version().decode().split(' ')[0]
There is also another problem, where there is a whitespace at the end but no more information is provided. Such version also doesn't match version regular expression, so strip()-ping the version may be expected behaviour as a quick fix. In my example it was: '3.8.0-CAPI-1.13.1 '
In the latest GEOS install, the above answer didn't work... but was close to the problem.
I changed the regex right above the geos_version_info():
from:
version_regex = re.compile(r'^(?P<version>(?P<major>\d+)\.(?P<minor>\d+)\.(?P<subminor>\d+))((rc(?P<release_candidate>\d+))|dev)?-CAPI-(?P<capi_version>\d+\.\d+\.\d+)$')
to be:
version_regex = re.compile(r'^(?P<version>(?P<major>\d+)\.(?P<minor>\d+)\.(?P<subminor>\d+))((rc(?P<release_candidate>\d+))|dev)?-CAPI-(?P<capi_version>\d+\.\d+\.\d+).*$')
Notice the .* added to the end of the regex.
I think this is broken again. A recent upgrade on our FreeBSD server led to this error:
django.contrib.gis.geos.error.GEOSException: Could not parse version info string "3.6.2-CAPI-1.10.2 4d2925d6"
Looks like the regex in Django's libgeos.py needs to be updated again to account for this different syntax. Nachopro's solution still serves as a workaround.
It appears that this has been fixed in Django as of last March or so. See also Django bug 20036. So upgrading to Django 1.5.4 will solve the problem.
For those folks who don't have 3.6.1 previously installed:
brew unlink geos
Install 3.6.1 with brew install https://raw.githubusercontent.com/Homebrew/homebrew-core/145b22e8330e094ee148861e72e26c03e73d34a1/Formula/geos.rb.
brew info geos should show 3.6.1 starred:
Brew just released geos 3.8.0 that of course breaks Django 1.11 again.
The previous version, 3.7.3, was oh so very helpfully cleared by the all new all automatic cleanup now running on upgrades, so no brew switch geos 3.7.3 for me.
I ended up using this post to understand how to find the previous version number and commit hash:
cd $( brew --prefix )/Homebrew/Library/Taps/homebrew/homebrew-core
git log -- Formula/geos.rb | less
# find the version you need in the file, copy its hash
brew unlink geos
brew install https://raw.githubusercontent.com/Homebrew/homebrew-core/<yourcommithash>/Formula/geos.rb
After all this, the download for geos 3.7.3 fails SHA256 checksum validation for some reason... so I ended up trying 3.7.2, that actually worked.
For now the command to reinstall 3.7.2 on Catalina is:
brew install https://raw.githubusercontent.com/Homebrew/homebrew-core/823b700ab61eeec57f34d50be2cc34a285fb5abc/Formula/geos.rb
If one cannot for any reason edit the site packages themselves, this ugly hack did it for me without having to act on the environment itself:
try:
__import__('django.contrib.gis.geos.libgeos', fromlist=['version_regex'])
except Exception as e:
import re
att = __import__('django.contrib.gis.geos.libgeos', fromlist=['version_regex'])
setattr(att, 'version_regex', re.compile(
'^(?P<version>(?P<major>\\d+)\\.(?P<minor>\\d+)\\.(?P<subminor>\\d+))((rc(?P<release_candidate>\\d+))|dev)?-CAPI-(?P<capi_version>\\d+\\.\\d+\\.\\d+)( r\\d+)?( \\w+)?.*$'))
assert str(type(e)) == "<class 'django.contrib.gis.geos.error.GEOSException'>", str(e)
It is based on JayCrossler's answer.
Update
The above executes code found within the django.contrib.gis.geos.__init__.py module, which already tries to use the problematic part, rendering the above solution unusable (for python 2.7+). This can be worked around as:
import sys
try:
import django.contrib.gis.geos.libgeos
except Exception as e:
import re
setattr(sys.modules['django.contrib.gis.geos.libgeos'],'version_regex', re.compile(
'^(?P<version>(?P<major>\\d+)\\.(?P<minor>\\d+)\\.(?P<subminor>\\d+))((rc(?P<release_candidate>\\d+))|dev)?-CAPI-(?P<capi_version>\\d+\\.\\d+\\.\\d+)( r\\d+)?( \\w+)?.*$'))
assert str(type(e)) == "<class 'django.contrib.gis.geos.error.GEOSException'>", str(e)
Where basically we are acting directly on the module in sys.modules instead of trying to get it from another import that will fail.
This can be fixed by trying the following,
brew switch geos 3.6.1
I fixed the issue by installing PostGIS with Postgres using https://postgresapp.com/downloads.html.
Install PostGIS (2.2): brew install postgis
To unlink geos if version is higher than 3.6.1: brew unlink geos
Install Geos (3.6.1): brew install https://raw.githubusercontent.com/Homebrew/homebrew-core/145b22e8330e094ee148861e72e26c03e73d34a1/Formula/geos.rb
Switch geos version(latest version is 3.7.2 which is not supported by Django 1.11.3): brew switch geos 3.6.1
Login to database and create postgis extensions: CREATE EXTENSION postgis;
Test postgis extension: SELECT ST_Distance('LINESTRING(-122.33 47.606, 0.0 51.5)'::geography, 'POINT(-21.96 64.15)'::geography);
Check postgis version: SELECT PostGIS_full_version();
What's a good way to check if a package is installed while within a Python script? I know it's easy from the interpreter, but I need to do it within a script.
I guess I could check if there's a directory on the system that's created during the installation, but I feel like there's a better way. I'm trying to make sure the Skype4Py package is installed, and if not I'll install it.
My ideas for accomplishing the check
check for a directory in the typical install path
try to import the package and if an exception is throw, then install package
If you mean a python script, just do something like this:
Python 3.3+ use sys.modules and find_spec:
import importlib.util
import sys
# For illustrative purposes.
name = 'itertools'
if name in sys.modules:
print(f"{name!r} already in sys.modules")
elif (spec := importlib.util.find_spec(name)) is not None:
# If you choose to perform the actual import ...
module = importlib.util.module_from_spec(spec)
sys.modules[name] = module
spec.loader.exec_module(module)
print(f"{name!r} has been imported")
else:
print(f"can't find the {name!r} module")
Python 3:
try:
import mymodule
except ImportError as e:
pass # module doesn't exist, deal with it.
Python 2:
try:
import mymodule
except ImportError, e:
pass # module doesn't exist, deal with it.
As of Python 3.3, you can use the find_spec() method
import importlib.util
# For illustrative purposes.
package_name = 'pandas'
spec = importlib.util.find_spec(package_name)
if spec is None:
print(package_name +" is not installed")
Updated answer
A better way of doing this is:
import subprocess
import sys
reqs = subprocess.check_output([sys.executable, '-m', 'pip', 'freeze'])
installed_packages = [r.decode().split('==')[0] for r in reqs.split()]
The result:
print(installed_packages)
[
"Django",
"six",
"requests",
]
Check if requests is installed:
if 'requests' in installed_packages:
# Do something
Why this way? Sometimes you have app name collisions. Importing from the app namespace doesn't give you the full picture of what's installed on the system.
Note, that proposed solution works:
When using pip to install from PyPI or from any other alternative source (like pip install http://some.site/package-name.zip or any other archive type).
When installing manually using python setup.py install.
When installing from system repositories, like sudo apt install python-requests.
Cases when it might not work:
When installing in development mode, like python setup.py develop.
When installing in development mode, like pip install -e /path/to/package/source/.
Old answer
A better way of doing this is:
import pip
installed_packages = pip.get_installed_distributions()
For pip>=10.x use:
from pip._internal.utils.misc import get_installed_distributions
Why this way? Sometimes you have app name collisions. Importing from the app namespace doesn't give you the full picture of what's installed on the system.
As a result, you get a list of pkg_resources.Distribution objects. See the following as an example:
print installed_packages
[
"Django 1.6.4 (/path-to-your-env/lib/python2.7/site-packages)",
"six 1.6.1 (/path-to-your-env/lib/python2.7/site-packages)",
"requests 2.5.0 (/path-to-your-env/lib/python2.7/site-packages)",
]
Make a list of it:
flat_installed_packages = [package.project_name for package in installed_packages]
[
"Django",
"six",
"requests",
]
Check if requests is installed:
if 'requests' in flat_installed_packages:
# Do something
If you want to have the check from the terminal, you can run
pip3 show package_name
and if nothing is returned, the package is not installed.
If perhaps you want to automate this check, so that for example you can install it if missing, you can have the following in your bash script:
pip3 show package_name 1>/dev/null #pip for Python 2
if [ $? == 0 ]; then
echo "Installed" #Replace with your actions
else
echo "Not Installed" #Replace with your actions, 'pip3 install --upgrade package_name' ?
fi
Open your command prompt type
pip3 list
As an extension of this answer:
For Python 2.*, pip show <package_name> will perform the same task.
For example pip show numpy will return the following or alike:
Name: numpy
Version: 1.11.1
Summary: NumPy: array processing for numbers, strings, records, and objects.
Home-page: http://www.numpy.org
Author: NumPy Developers
Author-email: numpy-discussion#scipy.org
License: BSD
Location: /home/***/anaconda2/lib/python2.7/site-packages
Requires:
Required-by: smop, pandas, tables, spectrum, seaborn, patsy, odo, numpy-stl, numba, nfft, netCDF4, MDAnalysis, matplotlib, h5py, GridDataFormats, dynd, datashape, Bottleneck, blaze, astropy
In the Terminal type
pip show some_package_name
Example
pip show matplotlib
You can use the pkg_resources module from setuptools. For example:
import pkg_resources
package_name = 'cool_package'
try:
cool_package_dist_info = pkg_resources.get_distribution(package_name)
except pkg_resources.DistributionNotFound:
print('{} not installed'.format(package_name))
else:
print(cool_package_dist_info)
Note that there is a difference between python module and a python package. A package can contain multiple modules and module's names might not match the package name.
if pip list | grep -q \^'PACKAGENAME\s'
# installed ...
else
# not installed ...
fi
You can use this:
class myError(exception):
pass # Or do some thing like this.
try:
import mymodule
except ImportError as e:
raise myError("error was occurred")
Method 1
to search weather a package exists or not use pip3 list command
#**pip3 list** will display all the packages and **grep** command will search for a particular package
pip3 list | grep your_package_name_here
Method 2
You can use ImportError
try:
import your_package_name
except ImportError as error:
print(error,':( not found')
Method 3
!pip install your_package_name
import your_package_name
...
...
I'd like to add some thoughts/findings of mine to this topic.
I'm writing a script that checks all requirements for a custom made program. There are many checks with python modules too.
There's a little issue with the
try:
import ..
except:
..
solution.
In my case one of the python modules called python-nmap, but you import it with import nmap and as you see the names mismatch. Therefore the test with the above solution returns a False result, and it also imports the module on hit, but maybe no need to use a lot of memory for a simple test/check.
I also found that
import pip
installed_packages = pip.get_installed_distributions()
installed_packages will have only the packages has been installed with pip.
On my system pip freeze returns over 40 python modules, while installed_packages has only 1, the one I installed manually (python-nmap).
Another solution below that I know it may not relevant to the question, but I think it's a good practice to keep the test function separate from the one that performs the install it might be useful for some.
The solution that worked for me. It based on this answer How to check if a python module exists without importing it
from imp import find_module
def checkPythonmod(mod):
try:
op = find_module(mod)
return True
except ImportError:
return False
NOTE: this solution can't find the module by the name python-nmap too, I have to use nmap instead (easy to live with) but in this case the module won't be loaded to the memory whatsoever.
I would like to comment to #ice.nicer reply but I cannot, so ...
My observations is that packages with dashes are saved with underscores, not only with dots as pointed out by #dwich comment
For example, you do pip3 install sphinx-rtd-theme, but:
importlib.util.find_spec(sphinx_rtd_theme) returns an Object
importlib.util.find_spec(sphinx-rtd-theme) returns None
importlib.util.find_spec(sphinx.rtd.theme) raises ModuleNotFoundError
Moreover, some names are totally changed.
For example, you do pip3 install pyyaml but it is saved simply as yaml
I am using python3.8
If you'd like your script to install missing packages and continue, you could do something like this (on example of 'krbV' module in 'python-krbV' package):
import pip
import sys
for m, pkg in [('krbV', 'python-krbV')]:
try:
setattr(sys.modules[__name__], m, __import__(m))
except ImportError:
pip.main(['install', pkg])
setattr(sys.modules[__name__], m, __import__(m))
A quick way is to use python command line tool.
Simply type import <your module name>
You see an error if module is missing.
$ python
Python 2.7.6 (default, Jun 22 2015, 17:58:13)
>>> import sys
>>> import jocker
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ImportError: No module named jocker
$
Hmmm ... the closest I saw to a convenient answer was using the command line to try the import. But I prefer to even avoid that.
How about 'pip freeze | grep pkgname'? I tried it and it works well. It also shows you the version it has and whether it is installed under version control (install) or editable (develop).
I've always used pylibcheck to check if a lib is installed or not, simply download it by doing pip install pylibcheck and the could could be like this
import pylibcheck
if not pylibcheck.checkPackage("mypackage"):
#not installed
it also supports tuples and lists so you can check multiple packages and if they are installed or not
import pylibcheck
packages = ["package1", "package2", "package3"]
if pylibcheck.checkPackage(packages):
#not installed
you can also install libs with it if you want to do that, recommend you check the official pypi
The top voted solution which uses techniques like importlib.util.find_spec and sys.modules and catching import exceptions works for most packages but fails in some edge cases (such as the beautifulsoup package) where the package name used in imports is somewhat different (bs4 in this case) than the one used in setup file configuration. For these edge cases, this solution doesn't work unless you pass the package name used in imports instead of the one used in requirements.txt or pip installations.
For my use case, I needed to write a package checker that checks installed packages based on requirements.txt, so this solution didn't work. What I ended up using was subprocess.check to call the pip module explicitly to check for the package installation:
import subprocess
for pkg in packages:
try:
subprocess.check_output('py -m pip show ' + pkg)
except subprocess.CalledProcessError as ex:
not_found.append(pkg)
It's a bit slower than the other methods but more reliable and handles the edge cases.
Go option #2. If ImportError is thrown, then the package is not installed (or not in sys.path).
Is there any chance to use the snippets given below? When I run this code, it returns "module pandas is not installed"
a = "pandas"
try:
import a
print("module ",a," is installed")
except ModuleNotFoundError:
print("module ",a," is not installed")
But when I run the code given below:
try:
import pandas
print("module is installed")
except ModuleNotFoundError:
print("module is not installed")
It returns "module pandas is installed".
What is the difference between them?