`eccodes` library not found - python

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

Related

pylucene - ModuleNotFoundError: No module named 'org'

# Common imports:
import sys
from os import path, listdir
from org.apache.lucene.document import Document, Field, StringField, TextField
from org.apache.lucene.util import Version
from org.apache.lucene.store import RAMDirectory
from datetime import datetime
# Indexer imports:
from org.apache.lucene.analysis.miscellaneous import LimitTokenCountAnalyzer
from org.apache.lucene.analysis.standard import StandardAnalyzer
from org.apache.lucene.index import IndexWriter, IndexWriterConfig
# from org.apache.lucene.store import SimpleFSDirectory
# Retriever imports:
from org.apache.lucene.search import IndexSearcher
from org.apache.lucene.index import DirectoryReader
from org.apache.lucene.queryparser.classic import QueryParser
# ---------------------------- global constants ----------------------------- #
BASE_DIR = path.dirname(path.abspath(sys.argv[0]))
INPUT_DIR = BASE_DIR + "/input/"
INDEX_DIR = BASE_DIR + "/lucene_index/"
I'm trying test pylucene library. I have written this code only for import test. It doesn't work. I get
bigissue#vmi995554:~/myluceneproj$ cd /home/bigissue/myluceneproj ; /usr/bin/env /usr/bin/python3.10 /home/bigissue/.vscode/extensions/ms-python.python-2022.16.1/pythonFiles/lib/python/debugpy/adapter/../../debugpy/launcher 36991 -- /home/bigissue/myluceneproj/hello_lucene.py
Traceback (most recent call last):
File "/home/bigissue/myluceneproj/hello_lucene.py", line 29, in <module>
from org.apache.lucene.document import Document, Field, StringField, TextField
ModuleNotFoundError: No module named 'org'
bigissue#vmi995554:~/myluceneproj$
I have run python3.10 -m pip list and there is "lucene" module. if I import lucene work well but python doesn't recognize org module. Why?
UPDATE
I downloaded lucene 9.1 and set environment variable (/etc/environment):
CLASSPATH=".:/usr/lib/jvm/temurin-17-jdk-amd64/lib:/home/bigissue/all_lucene/lucene-9.4.1/modules:/home/bigissue/all_lucene/lucene-9.1.0/modules" export CLASSPATH
I downloaded pylucene-9.1.0 and I have installed it
first jcc
bigissue#vmi995554:~/all_lucene/pylucene-9.1.0$ pwd
/home/bigissue/all_lucene/pylucene-9.1.0/jcc
bigissue#vmi995554:~/all_lucene/pylucene-9.1.0$python3.10 setup.py build
bigissue#vmi995554:~/all_lucene/pylucene-9.1.0$python3.10 setup.py install
I downloaded also ant apache.
then pylucene 9.1
cd ..
I have edit Makefile
vim /home/bigissue/all_lucene/pylucene-9.1.0/Makefile
PREFIX_PYTHON=/usr/bin
ANT=/home/bigissue/all_lucene/apache-ant-1.10.12
PYTHON=$(PREFIX_PYTHON)/python3.10
JCC=$(PYTHON) -m jcc --shared
NUM_FILES=10
bigissue#vmi995554:~/all_lucene/pylucene-9.1.0: make
bigissue#vmi995554:~/all_lucene/pylucene-9.1.0: make install
if I run python3.10 -m pip install | grep -i "lucene" I see it.
bigissue#vmi995554:~/all_lucene/pylucene-9.1.0$ python3.10 -m pip list | grep -i "lucene"
lucene 9.1.0
Now I have imported lucene
import sys
from os import path, listdir
from lucene import *
directory = RAMDirectory()
But I get
ImportError: cannot import name 'RAMDirectory' from 'lucene' (/usr/local/lib/python3.10/dist-packages/lucene-9.1.0-py3.10-linux-x86_64.egg/lucene/__init__.py)
Python doesn't use that kind of imports.
Just import lucene.
If this doesn't fix your problem, sorry!
You can use from lucene import whatever.
See the Features documentation, where it states:
"The PyLucene API exposes all Java Lucene classes in a flat namespace in the PyLucene module."
So, in Java you use import org.apache.lucene.index.IndexReader; but in PyLucene you use from lucene import IndexReader.
Update
Regarding the latest error you mentioned in the comments to your question:
ImportError: cannot import name 'RAMDirectory' from 'lucene'
Lucene's RAMDirectory has been deprecated for a long time - and was finally removed from version 9.0 of Lucene.
You can use a different directory implementation.
Recommended: MMapDirectory - but there are other options such as ByteBuffersDirectory
(Just to note, a new error/issue should really be addressed by asking a new question.)

See when packages were installed / updated using pip

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.

How to tell Python to prefer module from $HOME/lib/python over /usr/lib/python?

In Python, I'm getting an error because it's loading a module from /usr/lib/python2.6/site-packages but I'd like it to use my version in $HOME/python-modules/lib/python2.6/site-packages, which I installed using pip-python --install-option="--prefix=$HOME/python-modules --ignore-installed
How can I tell Python to use my version of the library? Setting PYTHONPATH to $HOME/python-modules/lib/python2.6/site-packages doesn't help, since /usr/lib/... apparently has precedence.
Take a look at the site module for ways to customize your environment.
One way to accomplish this is to add a file to a location currently on sys.path called usercustomize.py, when Python is starting up it will automatically import this file, and you can use it to modify sys.path.
First, set $PYTHONPATH to $HOME (or add $HOME if $PYTHONPATH has a value), then create the file $HOME/usercustomize.py with the following contents:
import sys, os
my_site = os.path.join(os.environ['HOME'],
'python-modules/lib/python2.6/site-packages')
sys.path.insert(0, my_site)
Now when you start Python you should see your custom site-packages directory before the system default on sys.path.
Newer Python versions now have built-in support to search the opendesktop location:
$HOME/.local/lib/pythonX.Y/site-packages
If you put your local modules there you don't have to any sys.path manipulations.
If one has multiple versions of a package installed, say e.g. SciPy:
>>> import scipy; print(scipy.__version__); print(scipy.__file__)
0.17.0
/usr/lib/python3/dist-packages/scipy/__init__.py
and one would like the user installed version (installed e.g. using pip install --user --upgrade scipy) to be prefered, one needs a usercustomize.py file in ~/.local/lib/python3.5/site-packages/ with e.g. this content:
import sys, os
my_site = os.path.join(
os.environ['HOME'], '.local/lib/python%d.%d/site-packages' % (
sys.version_info[0], sys.version_info[1]))
for idx, pth in enumerate(sys.path):
if pth.startswith('/usr'):
sys.path.insert(idx, my_site)
break
else:
raise ValueError("No path starting with /usr in sys.path")
(the for loop selecting index ensures that packages installed in "develop mode" takes precedence) now we get our user specific version of SciPy:
>>> import scipy; print(scipy.__version__); print(scipy.__file__)
0.18.1
/home/user/.local/lib/python3.5/site-packages/scipy/__init__.py
to prefer packages installed to userbase (e.g. pip install --user --upgrade cool_thing )
in ~/.bashrc,~/.profile, or whatever the init file for your shell is, add
export PYTHONUSERBASE="$HOME/python-modules"
in $PYTHONUSERBASE/usercustomize.py
#!/usr/bin/env python
import sys, site
sys.path.insert(0, site.getusersitepackages())

How do I automatically install missing python modules? [duplicate]

This question already has answers here:
How can I Install a Python module within code?
(12 answers)
Closed 6 years ago.
I would like to be able to write:
try:
import foo
except ImportError:
install_the_module("foo")
What is the recommended/idiomatic way to handle this scenario?
I've seen a lot of scripts simply print an error or warning notifying the user about the missing module and (sometimes) providing instructions on how to install. However, if I know the module is available on PyPI, then I could surely take this a step further an initiate the installation process. No?
Risking negative votes, I would like to suggest a quick hack. Please note that I'm completely on board with accepted answer that dependencies should be managed externally.
But for situations where you absolutely need to hack something that acts like self contained, you can try something like below:
import os
try:
import requests
except ImportError:
print "Trying to Install required module: requests\n"
os.system('python -m pip install requests')
# -- above lines try to install requests module if not present
# -- if all went well, import required module again ( for global access)
import requests
Installation issues are not subject of the source code!
You define your dependencies properly inside the setup.py of your package
using the install_requires configuration.
That's the way to go...installing something as a result of an ImportError
is kind of weird and scary. Don't do it.
try:
import foo
except ImportError:
sys.exit("""You need foo!
install it from http://pypi.python.org/pypi/foo
or run pip install foo.""")
Don't touch user's installation.
Here's the solution I put together which I call pyInstall.py. It actually checks whether the module is installed rather than relying on ImportError (it just looks cleaner, in my opinion, to handle this with an if rather than a try/except).
I've used it under version 2.6 and 2.7... it would probably work in older versions if I didn't want to handle print as a function... and I think it'll work in version 3.0+ but I've never tried it.
Also, as I note in the comments of my getPip function, I don't think that particular function will work under OS X.
from __future__ import print_function
from subprocess import call
def installPip(log=print):
"""
Pip is the standard package manager for Python. Starting with Python 3.4
it's included in the default installation, but older versions may need to
download and install it. This code should pretty cleanly do just that.
"""
log("Installing pip, the standard Python Package Manager, first")
from os import remove
from urllib import urlretrieve
urlretrieve("https://bootstrap.pypa.io/get-pip.py", "get-pip.py")
call(["python", "get-pip.py"])
# Clean up now...
remove("get-pip.py")
def getPip(log=print):
"""
Pip is the standard package manager for Python.
This returns the path to the pip executable, installing it if necessary.
"""
from os.path import isfile, join
from sys import prefix
# Generate the path to where pip is or will be installed... this has been
# tested and works on Windows, but will likely need tweaking for other OS's.
# On OS X, I seem to have pip at /usr/local/bin/pip?
pipPath = join(prefix, 'Scripts', 'pip.exe')
# Check if pip is installed, and install it if it isn't.
if not isfile(pipPath):
installPip(log)
if not isfile(pipPath):
raise("Failed to find or install pip!")
return pipPath
def installIfNeeded(moduleName, nameOnPip=None, notes="", log=print):
""" Installs a Python library using pip, if it isn't already installed. """
from pkgutil import iter_modules
# Check if the module is installed
if moduleName not in [tuple_[1] for tuple_ in iter_modules()]:
log("Installing " + moduleName + notes + " Library for Python")
call([getPip(log), "install", nameOnPip if nameOnPip else moduleName])
Here are some usage examples:
from datetime import datetime
from pyInstall import installIfNeeded
# I like to have my messages timestamped so I can get an idea of how long they take.
def log(message):
print(datetime.now().strftime("%a %b %d %H:%M:%S") + " - " + str(message))
# The name fabric doesn't really convey to the end user why the module is needed,
# so I include a very quick note that it's used for SSH.
installIfNeeded("fabric", notes = " (ssh)", log = log)
# SoftLayer is actually named softlayer on pip.
installIfNeeded("SoftLayer", "softlayer", log = log)
Edit: A more cross-platform way of getting pipPath is:
from subprocess import Popen, PIPE
finder = Popen(['where' if isWindows() else 'which', 'pip'], stdout = PIPE, stderr = PIPE)
pipPath = finder.communicate()[0].strip()
This makes the assumption that pip is/will be installed on the system path. It tends to be pretty reliable on non-Windows platforms, but on Windows it may be better to use the code in my original answer.

Check if Python Package is installed

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?

Categories