pipenv: how to activate virtual environment by specifying name or path? - python

pipenv has a design centered around projects having their own venvs. What if I have a generic venv that I want to use for scripting or to be shared with other projects and therefore I would like it to be activate while the current directory is pointing anywhere in the system. How can I achieve this? I looked up the docs and I couldn't see a way to do it.
In conda, one can simply activate an environment by specifying its name, no matter whats the current directory is. Even virtualenv can do the same but you have to specify the path.

At the directory where Pipfile resides, find the path to the environment:
pipenv --venv
Copy that path, for example /Users/yourname/.local/share/virtualenvs/yourproject-7qj8f3ed. Then in any other folder you can activate the venv with source, e.g.:
source /Users/yourname/.local/share/virtualenvs/yourproject-7qj8f3ed/bin/activate
You could also put an alias in bash.rc, etc to make a shortcut to that command.

Related

pipenv deleted libraries from my virtual environment?

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.

Make Pipenv create the virtualenv in the same folder

I want Pipenv to make virtual environment in the same folder with my project (Django).
I searched and found the PIPENV_VENV_IN_PROJECT option but I don't know where and how to use this.
PIPENV_VENV_IN_PROJECT is an environment variable, just set it (the value doesn't matter, but must not be empty). Make sure to export it so child processes of the shell can see it:
export PIPENV_VENV_IN_PROJECT=1
This causes the virtualenv to be created in the .venv directory next to the Pipfile file. Use unset PIPENV_VENV_IN_PROJECT to remove the option again.
You may want to see if the direnv project can be useful here. It'll set environment variables for you, automatically, when you enter your project directory, provided you created a .envrc file in the project directory and enabled the directory with direnv allow. You then can add any such export commands to that file.
This maybe helps someone else. I found another easy way to solve this!
Just make an empty folder inside your project and name it .venv and pipenv will use this folder.
Try
PIPENV_VENV_IN_PROJECT=1 pipenv sync -d
For the fish shell, use:
set -Ux PIPENV_VENV_IN_PROJECT 1
For posterity's sake, if you find pipenv is not creating a virtual environment in the proper location, you may have an erroneous Pipfile somewhere, confusing the pipenv shell call - in which case I would delete it form path locations that are not explicitly linked to a repository.
In Three simple steps:
export the variable as
export PIPENV_VENV_IN_PROJECT=1
Create a empty folder and file Pipfile
mkdir .venv
touch Pipfile
Then execute
pipenv shell
This trick worked for me:
create an empty folder named .venv
create an empty file named Pipfile
Run pipenv shell there.

pipenv : how to force virtualenv directory?

Actually, pipenv will install the virtualenv with a path like this :
$WORKON_HOME/<base_dir>-<hash>
Is it possible to have exactly the path I want, that is without the base_dir and the hash, for exemple :
/home/user/myapp_venv
Apart from using a custom location, you can also install the virtualenv in your project's directory. Just add the following line in your .bashrc/.zshrc file:
export PIPENV_VENV_IN_PROJECT=1
Just wanted to let others know that there is another approach available too.
Should you keep the virtualenv inside or outside the project's directory is an opinionated question afterall.
There is an undocumented feature of pipenv, it could locate virtualenv path from VIRTUAL_ENV environment variable, but you need to create virtualenv manually:
virtualenv /home/user/myapp_venv
VIRTUAL_ENV=/home/user/myapp_venv pipenv install
There's an undocumented feature in pipenv: if you create a file named .venv in the project root with a path in it, pipenv will use that instead of an autogenerated path.
This, however, is more fit for cases when you already have an established set of environments that you wish to reuse. Otherwise, placing environments in arbitrary places is prone to create a mess eventually. pipenv relieves you from this task specifically to keep them all in one predictable place and eliminate accidental collisions from human error.
In windows, Pycharm user by
make .venv fold in project
Settings->Project->Project interpreter->pipenv Environment
it works for me
Creating a directory .venv in the project then try to initiate with pipenv install <some package> did not work for me at the first in my mac, it was always creating virtual environment somewhere else. Though later I figure it out the reason. The hack is, first cd to the project folder cd /Home/.../MyProject then create a empty Pipfile touch Pipfile the create a directory mkdir .venv should work. Now you can run pipenv install and .venv folder will be used.
Now the elaboration is given form the source code. When the pipenv try to create create a virtual env it looks to the directory dot_venv = os.path.join(self.project_directory, ".venv") (taken from source code) and thats how the self.project_directory looks like:
#property
def project_directory(self):
# type: () -> str
return os.path.abspath(os.path.join(self.pipfile_location, os.pardir))
So that function looks for the pipfile location to create the path it will create the virtual environment. So if you create the empty Pipfile before hand it is confirmed that it will find that file and then find the .venv directory and create the path all together.

Virtual Environments with Python

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.

Why do you need to set the WORKON_HOME environment variable?

I haven't used my python/virtual environments in a while, but I do have virtualenvironment wrapper installed also.
My question is, in the doc page it says to do this:
export WORKON_HOME=~/Envs
$ mkdir -p $WORKON_HOME
$ source /usr/local/bin/virtualenvwrapper.sh
$ mkvirtualenv env1
I simply did this at my prompt:
source /usr/local/bin/virutalenvwrapper.sh
And now I can list and select an environment by doing:
>workon
>workon envtest1
My question is, since this works for me, I'm confused why I should be creating an environmental variable WORKON_HOME and point it to the ~/Envs folder? What does that do and how come mine works fine w/o it? I don't have that /Envs folder either (I know the script creates it).
Reference: http://virtualenvwrapper.readthedocs.org/en/latest/
If WORKON_HOME is not set, your default virtualenv folder will be set to ~/.virtualenvs
(see virtualenvwrapper.sh l.118)
You will also use WORKON_HOME to specify to pip which folder to use (export PIP_VIRTUALENV_BASE=$WORKON_HOME)
source : virtualenvwrapper.readthedocs.org : Tying to pip’s virtualenv support
I'm confused why I should be creating an environmental variable
WORKON_HOME and point it to the ~/Envs folder?
It's optional. You're confused (like I was) because the documentation is confusing.
What does that do and how come mine works fine w/o it?
It tells virtualenvwrapper which folder to search for Python environments. The command workon searches the path WORKON_HOME if it's defined, or ~/.virtualenvs if it's not, which is why it works by default.
A use case for defining a different WORKON_HOME directory would be if you have different environments you want to available to virtualenvwrapper. For example, if you save virtual env backups to a different folder or have multiple users who want to maintain their own environments.

Categories

Resources