I use virtualenvwrapper to manage my environments. I create my projects with the -a <path-to-project> argument and PROJECT_HOME is not set, because my projects don't share a common path. VIRTUALENVWRAPPER_WORKON_CD is set to 1 though and a valid .project file exist in the virtual environments.
When I use the workon command, it only changes the working directory to the path of the project sometimes, while at other times, the directory stays the same, despite the environment being activated correctly.
So when and how does the directory change trough workon happens? And are there things I have to do / set for it to work?
I have a small solution albeit kinda hacky
Go to the folder which this variable, $VIRTUALENVWRAPPER_HOOK_DIR is pointing to. You might need to be in a virtual environment to see that variable, but usually it has the same value as $WORKON_HOME
In this folder you should see a script called postactivate
Add this as the last line in the script: cdproject
Now what this does is that every time you type workon <project_name>, this script will run after the virtual environment is activated, and the directory you were working in will switch to the directory for that project.
For more life-cycle hooks, see here!
NOTE
I didn't fully test this to make sure it works no matter how the project was created, but to make sure it works, I recommend creating your virtual environments with mkvirtualenv -a <env_name> or if the environment exists and with the environment activated, go to it's project folder and run setvirtualenvproject. Now the next time you try to do workon ..., the script will kick in and take you to your project folder
Addendum
Since this is a shell script, you can do some fancy tweaks than just that one line. For example you might want to only do something if the activated project has a certain pattern, or part of a certain group of projects. Checkout some of the $VIRTUALENVWRAPPER_* variables to see what other useful information you can get
setvirtualenvproject is now called setprojectdir. To use the current directory write setprojectdir .
Related
I am using Homebrew-installed pipenv to manage my virtual environments for Python projects. I navigate to my Python project's folder and use the pipenv shell command to activate the venv.
It has worked fine, until today when I noticed that I can't run my app.py from within the shell using the python3 app.py command. I get the ModuleNotFoundError: No module named 'flask' right from line 1.
When I run which python3 and which pip3, I see the expected response that specifies that I'm within my venv. When I run pip3 list, I only see pip, setuptools and wheel.
This is odd, because just very recently everything has worked fine (1-2 weeks ago?), and I'm positive that I personally didn't do anything that would mess with the libraries/requirements.
The Pipfile still lists all the requirements as expected. So how come they got deleted from my virtual environment?
I understand that I can just redownload all of the requirements; I'm just curious about why this happened in the first place.
UPDATE: I just realised that I did change the name of the folder which contains the project; I assume this is the cause. Since I've redownloaded the requirements already, does that mean I now have duplicates existing somewhere? If so, where?
If you moved/renamed the folder where you created your virtual env, then the next time you try to activate the virtual env there, Pipenv will create a brand new virtual env. This is because Pipenv creates the actual virtual env folders based on the full path to the project directory. This is noted in the docs:
https://pipenv-fork.readthedocs.io/en/latest/install.html#virtualenv-mapping-caveat
Pipenv automatically maps projects to their specific virtualenvs.
The virtualenv is stored globally with the name of the project’s root directory plus the hash of the full path to the project’s root (e.g., my_project-a3de50).
If you change your project’s path, you break such a default mapping and pipenv will no longer be able to find and to use the project’s virtualenv.
Emphasis on the 3rd bullet. So it didn't delete your packages, it basically created a new one. You should have also seen a notice that it was creating a new one:
demo$ pipenv shell
Launching subshell in virtual environment...
...
(demo) demo$
exit
demo$ cd ..
~$ mv demo demo2
~$ cd demo2
demo2$ pipenv shell
Creating a virtualenv for this project...
...
(demo2) demo2$
That "Creating a virtualenv..." means it's creating a new one.
Now, on to:
does that mean I now have duplicates existing somewhere? If so, where?
It means you still have your previous virtual env folder somewhere, where you previously installed your packages. You can try using the --venv option to get the top-level directory where Pipenv creates all virtual env folders. In your new env:
(demo2) demo2$ pipenv --venv
/Users/gino.mempin/.venvs/demo2-4Y1NLH_X
As mentioned, the virtual env folder here is demo2-4Y1NLH_X, and the top-level folder is (for my case) .venvs. The default is something like /.local/share/ or whatever you set WORKON_HOME to (see Custom Virtual Environment Location). Just run the --venv for yourself.
You can try going there, and it will list all the virtual envs you have created:
(demo2) demo2$ ls /Users/gino.mempin/.venvs
demo-tSf-ZA7f
demo2-4Y1NLH_X
some-other-project-ABJaje5
another-project-8WUmE08m
...
Here, if you are lucky, you can find the name of your old folder, and then simply delete it if you want to cleanup. If you are unlucky, there'll be multiple folders with the same name, and you won't be able to tell which one was your old folder.
(demo2) demo2$ ls /Users/gino.mempin/.venvs
demo-tSf-ZA7f
demo-7I2ki6rH
demo-8WUmE08m
demo2-4Y1NLH_X
There is currently no way to get the full path to the original directly from the virtual env folder-hash itself. (See related: How to remove all pipenv virtualenvs when the directory was deleted?). There is also no way to reuse your old virtual env and copy it to your new one. But you don't need to anyway, creating virtual envs is inexpensive, just recreate it and reinstall all previous packages.
I used this tutorial (rec by GoDaddy because I have a GoDaddy VPS)
https://www.godaddy.com/garage/how-to-install-and-configure-python-on-a-hosted-server/
to install a secondary version of Python (3.6.6) and create a Virtual Environment to run modules with the secondary version of Python. I want to be able to run scripts in the virtual environment but do not want to always use the admin account to do this. I have one other account set up that does not have admin privileges. Is there a way to extend authority to more than the admin account that created it? Do I need to do a virtual environment on every user account that is going to have access to run python?
It says to add a line to the bash_profile script. The script already had this:
# .bash_profile
# Get the aliases and functions
if [ -f ~/.bashrc ]; then
. ~/.bashrc
fi
# User specific environment and startup programs
PATH=$PATH:$HOME/bin
export PATH
This makes sense in that it seems to be defining the location of underlying Python (i.e., 2.6.6). I have modules in a venv that require 3.4+ so I created the virtual environment. I want to be able to call the script from Chrome and run it for some scripts and run it from cronjob for other scripts and the scripts need to always point to the virtualenv to use that installed interpreter. I have no idea how to do this correctly. Here's my system information and the results of some SSH printouts:
$ cd $PATH
-bash: cd: /home/flohosti/.local/bin:/home/flohosti/perl5/bin:/usr/local/cpanel/3rdparty/lib/path-bin:/usr/local/cpanel/3rdparty/lib/path-bin:/usr/local/cpanel/3rdparty/lib/path-bin:/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin:/opt/cpanel/composer/bin: No such file or directory
Before going into the VirtualEnv I run which python and get /usr/bin/python which I expected.
There are multiple ways to do that.
You can simply give read access to the directory where virtual environment is installed and then export its path in /etc/profile so that its automatically added to every users path.
Or you can give access to python binary inside the virtual env folder.
That being said this isn't the right way to go about it, most of the times you would want to have virtual environment inside your projet folder so that it is automatically available the project and who so ever has access to that project.
Edit 1
So the answer to your comment
Yes absolutely you can use the same virtual env to execute script in cron but you have to give absolute path to virtaul environment and your script in cron, like /home/flohosti/projectOne/env/bin/python <script path> or you can just set the PATH in cron and then you can use relative path as well.
I want to use the following directory hierarchy
~/python/project-1
~/python/project-2
~/python/project-3
~/python/virtual-environments/environment-1 (virtual environment base)
~/python/virtual-environments/environment-2 (virtual environment base)
and then use it like this
# project-1 runs inside environment-1
source ~/python/virtual-environments/environment-1/bin/activate
cd ~/python/project-1/
python
.
# project-2 runs inside environment-2
source ~/python/virtual-environments/environment-2/bin/activate
cd ~/python/project-2/
python
.
# project-3 also runs inside environment-1
source ~/python/virtual-environments/environment-1/bin/activate
cd ~/python/project-3/
python
Is this allowed or could this cause some nasty problems?
I ask because it seems that
~/python/virtual-environments/environment-1/ (virtual environment base)
~/python/virtual-environments/environment-1/project-1
~/python/virtual-environments/environment-1/project-3 (not sure if "allowed")
~/python/virtual-environments/environment-2/ (virtual environment base)
~/python/virtual-environments/environment-2/project-2
is the "official" way to do it. I don't want to tie the projects so tightly to the environments and also have multiple projects use the same environment, so it's not really the inside/outside discussion, but a "completely somewhere else" one.
Yes, it's ok. There is even a wrapper for virtualenv called virtualenvwrapper which does similar thing. By default it stores all virtualenvs in ~/.virtualenvs.
Hi I've been reading a lot about virtual environments but I don't seem to get one thing.
So I have my path like this:
../my_app/
../my_app/app.py
..etc
Where should I put the virtual environment?
Inside my_appas /my_app/venv/bin,include,lib?
or at the same level as my_app
/my_app/
/venv/
I don't understand if the location matters or if by using activate it will reference it instead of going to the main environment.
I hope this question makes sense.
Thanks!
I recommend utilizing the root directory which virtualenv creates as the root directory for your source files. Virtual-envirments are designed to be tied to a project, not shared between different projects. Example, lets say I write a lot of code in my ~/school directory. I'd cd to ~/school, do virtualenv ENV. Now I have an ENV directory in which to keep my source files and dependencies for the project. So you can create a ~/school/ENV/source folder in which to keep all your source folders. And all your virtual-environment files are close to your program, easily accessible in the ENV directory.
EDIT:
To address one part of your question: As long as you keep track of your environment, and you source bin/activate before running your python programs and installing dependencies with pip, you can install your virtual environment anywhere.
I don't understand if the location matters or if by using activate it
will reference it instead of going to the main environment.
It doesn't matter, as activate will take care of the paths correctly, but you shouldn't put your virtual environment in your source, as it is not part of your application (and its not portable). Instead, create a file with your requirements and put that under your source control.
You should put it in any directory other than your source code. The activate script will make sure the paths point to the right places.
Here is an example:
$ virtualenv /home/somedir/envs/myenv
... # some output
$ source /home/somedir/envs/myenv/bin/activate
(myenv) $ mkdir /home/somedir/projects
(myenv) $ cd /home/somedir/projects
(myenv) projects $
As you can see, the virtual environment is in the envs directory and is called myenv. Your source is in /home/somedir/projects. Type deactivate to exit your virtual environment.
I'm new to virtualenv and not sure how to set up paths. My paths have been set to something like this:
PYTHONPATH=C:\Python27\
PYTHONSTARTUP=C:\Python27\Scripts\startup.py
PATH=%PYTHONPATH%;...;%PYTHONPATH%\Scripts
Should I remove those paths for virtualenv's activate script to work correctly? If I can keep my paths then how do I call scripts for an env when it has been activated? Do I call scripts by explicitly running them with python.exe instead of simply typing the script name alone?
python myscript.py
Not sure how to handle the paths and I would appreciate a little guidance.
First, you have your paths wrong. PYTHONPATH tells Python in what folders to look for Python modules and normally you don't put Python's installation folder in it. For keeping installation folder of Python there's different environment variable called PYTHONHOME. So instead of PYTHONPATH=C:\Python27\ you should have PYTHONHOME=C:\Python27\. You should change PATH variable to use PYTHONHOME accordingly.
As to how to set environment variables when working with virtualenv; you don't need to do anything because virtualenv stores original values when it's activated, modifies environment variables it needs to modify and then restores original values when it's deactivated.
You can take a look at Using Python on Windows
Think you are fine just get on with virtual-env, (follow docs) but remember you must use cmd shell (NO POINT AND CLICKING!!) Took me a while before I realized that...
Once you have activated And installed what you want to in the virtual env,, you invoke scripts by "python scriptname"