Geek Culture
Published in

Geek Culture

Setting up python environment in macOS using Homebrew, Pyenv, and Pipenv

Pyenv and Pipenv are necessary tools if you are working on different projects that need to be deployed to production and maintain a clean codebase.

A high-level overview of how Pyenv and Pipenv are different and solve the bigger problem.

We often have a problem when working on different projects in the local system

  1. we might need different python versions for different projects (less common) or
  2. we might need python packages compatible with particular versions (more likely).
  3. Virtual environments for different projects for easy deployments

After stumbling with this problem, I found a perfect solution using two awesome libraries — Pyenv and Pipenv.

Pyenv is to manage Python versions, and Pipenv is to create virtual environments required for each project and manage python packages and their dependencies for each project.

This is a great way of working on different projects locally without any hassles.

We will use Homebrew to install Pyenv and Pipenv. If you already have Homebrew, skip the next step.

Installing Homebrew

Homebrew is a package manager for macOS. There are other package managers like MacPorts, but Homebrew is easy and popular. This is my one-stop package manager for installing some of the packages like — java, scala, apache-spark, python…

Simply run the below code to install homebrew from its git repo. Or check their official page — https://brew.sh/ for instructions and troubleshooting

ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

Installing Pyenv

We can install python using Homebrew with brew install python or for a specific version brew install python@3.7, but using Pyenv is a better way of handling different versions.

brew install pyenv

Also add this code to your .zshrc or .bashrc, depending on the shell you are using. Then restart the terminal so that the changes take into effect.

if command -v pyenv 1>/dev/null 2>&1; then
eval "$(pyenv init -)"
fi

To see all pyenv available python versions:

pyenv install --list

To install a specific version:

pyenv install 3.7.0

By default, macOS picks the system python version. To set pyenv version as default:

pyenv global 3.7.0

Check the python version and it should reflect the version set as above:

python --version

If a particular project needs a different python version, then install that version first (if not installed already), navigate to the project folder, and set that version as local to that folder.

pyenv install 3.6.5
cd <path to project folder>
pyenv local 3.6.5

This way, a specific project will use version 3.6.5, and all other projects by default use the 3.7.0 version.

To check all python versions installed using pyenv, enter this command:

pyenv versions

Check their home page for more details — https://github.com/pyenv/pyenv

Installing Pipenv

While pyenv is to have different versions of python and able to switch between them easily. Pipenv is to create virtual environments for different projects where we need different versions of python packages. In general, I recommend using a virtual environment, so that it is easy to replicate in production or share the list of packages required for a project.

To install Pipenv using homebrew:

brew install pipenv

Note: This pipenv creates dependency to the python version that was set as global in pyenv.

Navigate to the project folder and run pipenv install

cd <path to project folder>
pipenv install

This will create a virtual environment within that folder. The name of the virtual environment is the same as the folder name. (Note: my global version is 3.8.1)

Using pipenv to create a virtual environment within the project folder.

If you have an existing project folder with requirements.txt, this will also install packages listed in that file.

It also creates 2 files — Pipfile and Pipfile.lock. Pipfile contains 4 sections — source, packages, dev-packages, and requires.

To install any packages, do pipenv install <list of packages separated by space>. There is no need to activate a virtual environment. Note that it is pipenv and not pip.

Using pipenv to install necessary packages.

Now let’s take a look at Pipfile once.

Contents of Pipfile created by pipenv install.

Another awesome command in Pipenv, to find dependencies between packages and this is stored in Pipfile.lock is

pipenv graph
Results of Pipenv graph command.

If only seaborn is installed, all these packages would also be installed. And this is a nice way of showing dependencies and I absolutely love this method compared to pip list that doesn’t know which package depends on which package or why a certain package is there in that list.

It works the other way as well. When uninstalled pipenv uninstall pandas it will remove dependent packages that are not needed for other packages.

To run a python file, use pipenv run python <file.py> . There is no need to activate the virtual environment and run python from it. A single line will do all of it and it’s easy.

Pipenv has a lot more than what I mentioned in this article. Hence, I recommend going through their documentation for more details and customizations — https://docs.pipenv.org/

Pro Tip: Create aliases for all commands in your .zshrc or .bashrc. Here is my list for reference.

alias py="python $1"
alias prp="pipenv run python $1"
alias ps="pipenv shell"
alias pi="pipenv install $1"
alias pu="pipenv uninstall $1"
alias pg="pipenv graph"
alias pr="pipenv --rm"

Conclusion

When working on different projects that require different python versions or different python packages or for easy deployability, pyenv+pipenv is an awesome combination. It takes a little bit of time and effort to set it up, but that is well paid off in the long run.

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Avinash Kanumuru

Avinash Kanumuru

24 Followers

Data Scientist | Machine Learning Engineer | Data & Analytics Manager