I'd like to have a python script which in the beginning create a virtual environment, install required modules (e.g. cherrypy) and then continues with the rest of the code.
What I found so far is as follow:
import os, virtualenv
HOME_DIRECTORY = "venv"
virtualenv.create_environment(HOME_DIRECTORY)
execfile(os.path.join(HOME_DIRECTORY, "bin", "activate_this.py"))
import pip
pip.main(["install", "--prefix", HOME_DIRECTORY, "cherrypy"])
import cherrypy
class Root(object):
#cherrypy.expose
def index(self):
return "Hello World!"
if __name__ == '__main__':
cherrypy.quickstart(Root(), '/')
The script creates virtual environment and install cherrypy (based on the log), but still I get ImportError: No module named cherrypy error.
I also tried the following, but got the same error:
import importlib
CHERRYPY = 'cherrypy'
try:
importlib.import_module(CHERRYPY)
except ImportError:
import pip
pip.main(["install", "--prefix", HOME_DIRECTORY, CHERRYPY])
finally:
globals()[CHERRYPY] = importlib.import_module(CHERRYPY)
Apart from the above problem, also, I'd like to know how to specify the python version (e.g. python 3.6) while creating virtual environment. Thanks.
For the record the issue was with the virtual environment activate (the line to execute activate_this.py). For Python 3 the following worked for me:
ACTIVATE_THIS = 'venv/bin/activate_this.py'
exec(Path(ACTIVATE_THIS).read_text(), dict(__file__ = ACTIVATE_THIS))
Related
I get ImportError: no module named Flopy when I try to run the following script from an Anaconda prompt in the folder that the script it stored in, but when I run the script through Spyder it imports Flopy just fine and the rest of the code (not shown) which uses Flopy also works.
# import the required libraries
try:
import flopy
except:
fpth = os.path.abspath(os.path.join('..', '..'))
sys.path.append(fpth)
import flopy
The Spyder ran version never runs the code under than 'except' section since it managed to import Flopy at first try. I tried checking the path created by os.path.abspath(os.path.join('..', '..')) and even copied the Flopy directory to that location and running the script from the Anaconda prompt started in that folder...which did make some difference, but the import failed with error: ImportError: cannot import name getfullargspec.
Any ideas why imports work one way but not the other?
Fixed it with help from #Jainal Patel! I just had to tidy up all my environment paths. There was an installed version of Python in C:\Python3, but Spyder was using the one in C:ProgramData\Anaconda.
Now when I open the command prompt, or an Anaconda prompt, or use Spyder, it uses the same Python environment and recognizes all my installed packages.
!pip install flopy
try:
import flopy
except:
fpth = os.path.abspath(os.path.join('..', '..'))
sys.path.append(fpth)
import flopy
you need to install it first either using pip or conda
I added the src/sample/run.py below to the sampleproject. It runs locally (prints "add_one(2) = 3"), but deployed pip version fails:
virtualenv venv
source venv/bin/activate
pip install -i https://test.pypi.org/simple/ sampleproject-valhuber
sample-run
ModuleNotFoundError: No module named 'simple'
Here is src/sample/run.py:
import simple # FAILS in PyPi: ModuleNotFoundError...
def main():
print("add_one(2) = " + str(simple.add_one(2)))
if __name__ == '__main__':
main()
The complete code, along with packaging procedure is on this GitHub project.
Your simple.py is inside sample package. You have to import it from the package:
import sample.simple
or
from sample import simple
I tried the following simple code,
from flask import Flask
app = Flask(__name__)
#app.route("/")
def hello():
return "Hello World!"
if __name__ == "__main__":
app.run()
it is running fine with,
python hello.py
but it gives an error when i try with python3
ImportError: cannot import name 'Flask'
A package is installed against a specific Python version/location. Installing Flask for Python 2 (which is probably what the python and pip commands are aliased to), doesn't install it for Python 3.
You should really just use virtualenv to control exactly what versions and packages you are using.
This creates a Python 3 environment and installs Flask:
virtualenv -p /usr/bin/python3 my_py3_env
source my_py3_env/bin/activate
pip install flask
When you open a new terminal, just source the activate script again to keep using the environment.
I'm working through a flask tutorial and am trying to run a script that creates a database instead of doing it through the command line. It uses the SQLAlchemy-migrate package, but when I try to run the script, it gives an ImportError.
This is the terminal output:
Sean:app seanpatterson$ python ./db_create.py
Traceback (most recent call last):
File "./db_create.py", line 2, in <module>
from migrate.versioning import api
ImportError: No module named migrate.versioning
This is the db_create.py script:
#!flask/bin/python
from migrate.versioning import api
from config import SQLALCHEMY_DATABASE_URI
from config import SQLALCHEMY_MIGRATE_REPO
from app import db
import os.path
db.create_all()
if not os.path.exists(SQLALCHEMY_MIGRATE_REPO):
api.create(SQLALCHEMY_MIGRATE_REPO, 'database repository')
api.version_control(SQLALCHEMY_DATABASE_URI, SQLALCHEMY_MIGRATE_REPO)
else:
api.version_control(SQLALCHEMY_DATABASE_URI, SQLALCHEMY_MIGRATE_REPO, api.version(SQLALCHEMY_MIGRATE_REPO))
This is the config file it references:
#!/usr/bin/env python
import os
basedir = os.path.abspath(os.path.dirname(__file__))
SQLALCHEMY_DATABASE_URI = 'sqlite:///' + os.path.join(basedir, 'app.db')
SQLALCHEMY_MIGRATE_REPO = os.path.join(basedir, 'db_repository')
This application is being run with a virtual environment. This are the module that relates to it that I have installed in the environment:
sqlalchemy_migrate-0.7.2-py2.7.egg-info
Any help appreciated
pip install sqlalchemy==0.7.9
and
pip install sqlalchemy-migrate==0.7.2
and
optionally this flask-whooshalchemy==0.55a should solve the problem
ImportError: No module named migrate.versioning probably means the module is not installed. Make sure it has been installed in the correct virtual environment, it is activated (you ran the activate script in that environment) and the selected Python binary is actually making use of that environment (i.e. you are using Python2 and not Python3).
As said by #BoppreH earlier
ImportError: No module named migrate.versioning
means that the module named 'migrate' is not installed in your virtual environment or your system. First make sure that you are using the proper environment and that it is activated using the activate script.
I had the same problem and had the correct environment set up. But still the error was not solved.
What worked for me was installing the sqlalchemy-migrate package from pip. After activating my environment, I ran the following code to install it :
pip install sqlalchemy-migrate
flask/bin/pip install flask-sqlalchemy without defining the version worked fine for me.
run :
easy_install Flask-SQLAlchemy
to install Flask-SQLAlchemy
sudo pip install flask-migrate
to install flask-migrate
I think this error might pop up for several obscure reasons, I would like to add another which I experienced:
I had the same exact error while having sqlalchemy-migrate correctly installed, and guess what, it didn't work just because I had named the migration script file as migrate.py, this created some conflict with the migrate package.
In fact PyCharm warned me with this message:
"Import resolves to its containing file... This inspection detects names that should resolve but don't."
I renamed the migration script as db_migrate.py and everything started working fine.
I could understand what was the issue cause I had another project with an identical set-up but with migrate-sqlalchemy working perfectly and the only difference was indeed that file name...
Hope this might help someone one day...
I had the same problem - "No module named migrate.versioning", and everything is much easier than we are talking about, you need to perform the commands "run"
file: db_create.py or file: db_migrate.py if you using PyCharm (not from the terminal). And you will have the expected output: "New migration saved as D:...there is my path...\microblog\db_repositort/versions/001_migration.py
Current database version: 1"
I want to write a script to automatically setup a brand new ubuntu installation and install a django-based app. Since the script will be run on a new server, the Python script needs to automatically install some required modules.
Here is the script.
#!/usr/bin/env python
import subprocess
import os
import sys
def pip_install(mod):
print subprocess.check_output("pip install %s" % mod, shell=True)
if __name__ == "__main__":
if os.getuid() != 0:
print "Sorry, you need to run the script as root."
sys.exit()
try:
import pexpect
except:
pip_install('pexpect')
import pexpect
# More code here...
The installation of pexpect is success, however the next line import pexpect is failed. I think its because at runtime the code doesn't aware about the newly installed pexpect.
How to install and import Python modules at runtime? I'm open to another approaches.
You can import pip instead of using subprocess:
import pip
def install(package):
pip.main(['install', package])
# Example
if __name__ == '__main__':
try:
import pexpect
except ImportError:
install('pexpect')
import pexpect
Another take:
import pip
def import_with_auto_install(package):
try:
return __import__(package)
except ImportError:
pip.main(['install', package])
return __import__(package)
# Example
if __name__ == '__main__':
pexpect = import_with_auto_install('pexpect')
print(pexpect)
[edit]
You should consider using a requirements.txt along with pip. Seems like you are trying to automate deployments (and this is good!), in my tool belt I have also virtualenvwrapper, vagrant and ansible.
This is the output for me:
(test)root#vagrant:~/test# pip uninstall pexpect
Uninstalling pexpect:
/usr/lib/python-environments/test/lib/python2.6/site-packages/ANSI.py
/usr/lib/python-environments/test/lib/python2.6/site-packages/ANSI.pyc
/usr/lib/python-environments/test/lib/python2.6/site-packages/FSM.py
/usr/lib/python-environments/test/lib/python2.6/site-packages/FSM.pyc
/usr/lib/python-environments/test/lib/python2.6/site-packages/fdpexpect.py
/usr/lib/python-environments/test/lib/python2.6/site-packages/fdpexpect.pyc
/usr/lib/python-environments/test/lib/python2.6/site-packages/pexpect-2.4-py2.6.egg-info
/usr/lib/python-environments/test/lib/python2.6/site-packages/pexpect.py
/usr/lib/python-environments/test/lib/python2.6/site-packages/pexpect.pyc
/usr/lib/python-environments/test/lib/python2.6/site-packages/pxssh.py
/usr/lib/python-environments/test/lib/python2.6/site-packages/pxssh.pyc
/usr/lib/python-environments/test/lib/python2.6/site-packages/screen.py
/usr/lib/python-environments/test/lib/python2.6/site-packages/screen.pyc
Proceed (y/n)? y
Successfully uninstalled pexpect
(test)root#vagrant:~/test# python test.py
Downloading/unpacking pexpect
Downloading pexpect-2.4.tar.gz (113Kb): 113Kb downloaded
Running setup.py egg_info for package pexpect
Installing collected packages: pexpect
Running setup.py install for pexpect
Successfully installed pexpect
Cleaning up...
<module 'pexpect' from '/usr/lib/python-environments/test/lib/python2.6/site-packages/pexpect.pyc'>
(test)root#vagrant:~/test#
For those who are using pip version greater than 10.x, there is no main function for pip so the alternative approach is using import pip._internal as pip instead of import pip like :
Updated answer of Paulo
import pip._internal as pip
def install(package):
pip.main(['install', package])
if __name__ == '__main__':
try:
import pexpect
except ImportError:
install('pexpect')
import pexpect
I actually made a module for this exact purpose (impstall)
It's really easy to use:
import impstall
impstall.now('pexpect')
impstall.now('wx', pipName='wxPython')
Github link for issues/contributions
I solved my problem using the imp module.
#!/usr/bin/env python
import pip
import imp
def install_and_load(package):
pip.main(['install', package])
path = '/usr/local/lib/python2.7/dist-packages'
if path not in sys.path:
sys.path.append(path)
f, fname, desc = imp.find_module(package)
return imp.load(package, f, fname, desc)
if __name__ == "__main__":
try:
import pexpect
except:
pexpect = install_and_load('pexpect')
# More code...
Actually the code is less than ideal, since I need to hardcode the Python module directory. But since the script is intended for a known target system, I think that is ok.
I had the same issue but none of Google's searches helped. After hours debugging, I found that it may be because the sys.path is not reloaded with new installation directory.
In my case on my Ubuntu Docker, I want to import dns.resolver at runtime for Python3.8 (pre-installed). I also created ubuntu user and run all things with this user (including my Python script).
Before installing, sys.path doesn't have /home/ubuntu/.local/lib/python3.8/site-packages since I didn't install anything.
While installing with subprocess or pip.main like above, it creates /home/ubuntu/.local/lib/python3.8/site-packages (as user installation).
After installing , the sys.path should be refreshed to include this new location.
Since the sys.path is managed by site module, we should reload it (ref HERE):
import site
from importlib import reload
reload(site)
The full block for anyone that needs:
import subprocess
import sys
try:
import dns.resolver
except ImportError:
subprocess.check_call([sys.executable, "-m", "pip", "install", "dnspython"])
import site
from importlib import reload
reload(site)
import dns.resolver
I'm not Python developer so these code can be simplify more. This may help in cases such as fresh CI/CD environment for DevOps engineers like me.