What I want to do is store a reference to the project location (my source files) in my venv.
The purpose for this is so I can automatically switch to that directory when I activate my venv.
I already have a script that managers my venvs. e.g. workonvenv xyz will activate the venv named xyz.
Why not add this logic to the script that manages the venvs?
A venv is not tightly coupled with a project, meaning venvs can be used for several projects and a project doesn't necessarily need a venv to work. Therefore there's no reference of a project in the venv.
What I recommend is to define a convention for project and venv names such as - project: "project-x" and venv: "project-x-venv" and then use your script to activate the venv and then cd into the project folder according to this convention.
Related
To be honest, up until recently I was hoping to avoid everything related to vurtualenvs. Yep, very naïve.
All of the code I write using python is to be deployed using containers, where "one container - one app" is totally true for now. And also number of CLIs being distributed also to my coworkers as wheels.
What I came up with is two "global" environments living in my homedir:
"default" virtual env with python 3.10 and some general packages installed. Using this venv I develop current versions of my applications and do my regular job. It is sourced automatically in .bashrc.
Virtual env with python 3.9. This is used to support legacy versions of/not yet updated applications in case if something should be done to them.
And also for some of the projects there are dedicated virtual envs living in a project folder needed only for this particular project, python version there may vary from 3.7 to 3.10.
As a consequence, I have to change current environment by manually sourcing the right activate script several times a day, and this isn't funny.
After some research on the topic, I found things like virtualenvwrapper, Pipenv and Poetry, but none of them seem to meet all my needs: "global" env to use across multiple projects and outside projects (because of CLIs); ability to create env with given python version; easy switch between virtual envs.
Is there any solution for this?
UPD: Some illustrations
Next virtual environments were created inside ~/pyenv/:
$ virtualenv -p /usr/local/bin/python3.9 default3.9
$ virtualenv -p /usr/local/bin/python3.10 default3.10
Next, .bashrc was updated to do source ~/pyenv/default3.10/bin/activate.
Now, for the vast majority of tasks it is enough: everything needed for day-to-day job is installed in default3.10 venv.
In case I need to switch to python3.9 the following is required:
$ deactivate
$ source ~/pyenv/default3.9/bin/activate
And if then I need to work on some project with its own venv, inside project folder I have to do:
$ deactivate
$ source env/bin/activate
Too many manual inputs. At minimal, I'd like to do something like $ workon default3.9 no matter of the current directory I'm in, and it should activate default3.9 venv correctly if no venv is active right now or if any venv if already active.
The same should work inside project folder: $ workon <local_venv_name> to switch to the venv living in current project folder.
And something like venv create <enterpreter path/py version> to create new "global" or "local" (in current folder only) venv, and venv list to get the list of available "global" and "local" environments.
to use the global environment inside the project's local virtual environment.
set
include-system-site-packages = true
in pyvenv.cfg file located in .venv (virtual environment installation directory) directory of each project.
I'm a huge beginner so I'm not very informed about how packages really work. I know that you should create a virtualenv in your project folder to avoid version conflicts etc, and you're not supposed to put your actual project files in the virtual env. So if your project files are in your project directory on the same level as the virtualenv, can your project files "access" the things installed in the virtualenv? Can files outside of your directory access packages in your virtual env?
Yes, it all depends on the context. Your virtualenv can exist anywhere, be it in your project directory, or somewhere else.
When you want to use the virtualenv, you just have to call source command on it. Then whatever python command you execute on whichever file, will have access to the virtualenv. For example, if you store your virtualenv in /home/user/project/virtualenv, then you would do
source /home/user/project/virtualenv/bin/activate
Then whatever you with the python, it would be the version installed in virtualenv.
You can double check if you're using the global python or the virtualenv python by doing which python. It will either point to the global python path which is usually under /usr/bin/python or /home/user/project/virtualenv/bin/python.
So normally, you first do the source command, then you can do pip install on whatever packages you need already. It will be installed in the virtualenv and it will not conflict with other projects.
I keep all my projects in a folder called 'Projects' and have a venv in each project. I have the venv path setting in VS Code set to my Projects folder path, and when I use the Select Python Interpreter it recognizes the venv in my folder and says it is selected, however the venv is not being recognized because it won't recognize the packages I have imported.
enter image description here
So how I solved it was deleting the venv I created inside the project folder and creating a folder inside the project folder called venv where I installed the virtual environment. From there, the default paths in vscode were able to detect my venv and it was able to run. I'm not sure why it made a difference but it's working now!
Should I create a directory in my virtualenv and save the source code for that specific project there?
Thanks in advance
You're not required to have them related in any way. As long as your env is activated, it doesn't matter where it is.
But what's usually easiest is:
Create an empty directory for your project.
Create the virtualenv under that project directory.
Put the source in a src directory under that project directory (or, for really simple projects, just drop it in the project directory).
That way you can check the env settings into version control alongside your code, and if you use an auto-venv tool it'll activate the env every time you cd into the project directory, and so on.
As a side note, if you're just learning this stuff today, you might want to consider learning pipenv instead of using raw virtual environments.
You can save your project anywhere. But you should activate the virtual environment before working on that project.
You can activate the virtual environment using the following command.
source path-to-virtualenvironment/bin/activate
After activating the virtual environment move to your project location.
I've just installed virtualenv and virtualenvwrapper on my computer. Now I want to use it to work with Django. When I run mkvirtualenv django, from ~, the interpreter stays there. Does that mean I can create my django files there? Or is the environment not that virtual? Should I create my own folder instead where I work on the project? I thought mkvirtualenv would create one for me automatically and take me there upon running workon, otherwise, what's the point of even using virtualenvwrapper?
EDIT: These few lines from my .bash_profile might help you:
export WORKON_HOME=$HOME/.virtualenvs
export PROJECT_HOME=$HOME/Devel
source /usr/local/bin/virtualenvwrapper.sh
virtualenwrapper will create the virtualenv in your ~$WORKON_HOME/ directory. This is the venv only and is distinct from any associated "project" directory you might (or not...) want to use and which virtualenvwrapper will indeed not create.
IOW, at this point you are exactly in the same directory as when you ran the mkvirtualenv command.
If you want to associate this venv to a project directory, you have to create this directory (if it does not exist yet), and then - with your venv activated - run setvirtualenvproject /path/to/your/projectdir (or cd /path/to/your/projectdir and here run setvirtualenvproject without argument).
Once done with this, next time you activate your venv with workon myenv, you will be automagically cd'ed to your project directory too, and the cdproject command will bring you back there if you cd elsewhere.
As for other reasons to use (or not) virtualenwrapper, you can read the doc and find out by yourself what other features it adds to the raw virtualenv and whether you want those features or not.
FWIW the behaviour you expected (creating both the venv AND the project dir) is given by the mkproject command
The main advantage of virtualenvwrapper is the separation of your environment from a specific working directory. Just activate your environment with:
workon django
The prompt should change to:
(django)
Now you are free to work from any directory you want.