Say Goodbye to Virtualenv
10 Mar 2018These days it’s hard to imagine developing in Python without virtualenv. Having isolated environments prevents a whole class of subtle (and not so subtle) bugs, and makes it much easier to manage dependencies.
But virtualenv isn’t without it’s pain points. Having to activate
and deactivate
is a nuisance (virtualenvwrapper helps a bit) that makes jumping into, out of, and between environments harder than it needs to be. Ideally we should be able to pip install django
and ./manage.py runserver
without thinking about anything else.
The solution is pipenv. pipenv is a replacement for both pip and virtualenv, and is going to let us say goodbye to activate
/deactivate
forever.
I’m not going to cover it in detail for this post, but in addition to abstracting away virtual environments, pipenv also gives us a replacement for requirements.txt
that ensures we get deterministic builds. Learn more about what they look like here.
Installing pipenv
For macOS users, the easiest way to get started is with homebrew:
$ brew install pipenv
But you can always use pip
:
$ pip install pipenv
Now that we have pipenv
installed, create a directory for your project:
$ mkdir -p ~/projects/pipenv_test/ && cd ~/projects/pipenv_test/
Using pipenv
Here’s where the magic starts. Let’s install a dependency:
$ pipenv install django
That’s it. Behind the scenes pipenv has created a virtual environment and installed django into it. It has also recorded django as a dependency in Pipfile
and Pipfile.lock
. Again, we won’t go into those files in depth here, but like requirements.txt
they should go into version control.
Continuing with our django example, let’s create a project:
$ pipenv run django-admin.py startproject pipenvtest
So what exactly is happening here? By prefixing our normal django-admin.py
command with pipenv run
, it will be run within the context of the virtual environment that we are no longer thinking about.
Now we can start the dev server:
$ cd pipenvtest
$ pipenv run ./manage.py runserver
Silky smooth. What’s a virtual environment?
Environment Variables
If you’re doing things by the book then you’re probably storing your various secrets/tokens/etc in environment variables. The problem is when you execute pipenv run ...
it’s going to lose those environment variables. Fixing that is as easy as adding a .env
file to the root of your project (aka next to Pipfile
) and populating it with your vars:
$ echo 'DATABASE_PASSWORD=supersecretstuff' >> .env
Now when you pipenv run ...
those environment variables will be in context.
That’s it! Enjoy never thinking about virtualenv again.