{"id":255,"date":"2021-03-15T21:21:48","date_gmt":"2021-03-15T21:21:48","guid":{"rendered":"https:\/\/andrejacobs.org\/?p=255"},"modified":"2022-04-11T20:24:23","modified_gmt":"2022-04-11T20:24:23","slug":"100-days-of-learning-day-7-setting-up-python-using-pyenv-and-virtual-environments","status":"publish","type":"post","link":"https:\/\/andrejacobs.org\/100-days-challenge\/100-days-of-learning-day-7-setting-up-python-using-pyenv-and-virtual-environments\/","title":{"rendered":"100 Days of Learning: Day 7 \u2013 Setting up Python using pyenv and virtual environments"},"content":{"rendered":"\n
Here is my Log book<\/a><\/p>\n I recently clean installed my Mac to use Big Sur and with that I have not yet had a chance to install Python 3 and using virtual environments.<\/p>\n Python 2.x is no longer being maintained, however macOS Big Sur still ships 2.7.x.<\/p>\n I like to use Homebrew<\/a> as my package manager on macOS. See their website on the one line command to run to install Ensure brew is up to date<\/p>\n One of the things you learn as a developer on the job is that it does not take long for your development machine to become cluttered with programming languages and tools and at some point you will hit a snag where different projects will require different version of tool chains and dependencies.<\/p>\n Always use a version manager if you can.<\/strong> For example for Node.js I use For Python I like to use pyenv<\/a><\/p>\n Install <\/p>\n Add (I will be adding mine to ~\/.ajzsh\/extras\/zshrc.ajzsh because I am using my own ajzsh<\/a>)<\/p>\n To get the latest version number of Python, visit the downloads<\/a> page. At the time writing the latest version is 3.9.2 however pyenv is at 3.9.1<\/p>\n To get the list of available Pythons that can be installed from Set the default global version of Python to the latest version<\/p>\n Upgrade pip (pip is THE package installer for python, at least for now 😝)<\/p>\n Verify<\/p>\n Along with being able to have multiple versions of toolchains installed it is also important<\/strong> not to litter your development machine with dependencies directly. Meaning if you install 3rd party packages directly to your machine then sooner or later you will run into different projects depending on different versions of the packages.<\/p>\n The solution is to use Virtual Environments<\/a>.<\/p>\n I prefer to use the python build in Activate the virtual environment<\/strong><\/p>\n You will need to do this every time you start a new terminal session.<\/p>\n I like to use click<\/a> when developing Python CLI apps. So in this example I will be installing click into the virtual environment.<\/p>\n Notice the warning about the pip version. Earlier we updated the global pip to the latest version but the virtual environment is out of date. This shows the power behind using virtual environments.<\/p>\n What happens in the virtual environment stays in the virtual environment<\/strong> 🤫<\/p>\n To see the list of installed packages<\/p>\n requirements.txt<\/strong><\/p>\n The common convention is to "freeze" the list of packages that your project depends on into a file called requirements.txt that will then make it easier for anybody else (or yourself on a different machine or the CI\/CD) to install all of the dependencies.<\/p>\n To freeze the required packages<\/p>\n To install the required packages you would run<\/p>\n OpenFaaS and Python template<\/strong><\/p>\n You will notice that when you used the Python template to create a new OpenFaaS function that it created an empty requirements.txt file. If my theory is correct then there will be some kind of command run during deployment \/ building that will do a similar install of requirements.txt as we did above.<\/p>\n I am going to explore this theory a bit.<\/p>\n Right ok so the OpenFaaS template will indeed install any packages we use as long as we follow the convention of adding them to requirements.txt.<\/p>\nSetting up Python 3 on macOS<\/h2>\n
$ python --version\nPython 2.7.16\n<\/code><\/pre>\n
Homebrew<\/h3>\n
brew<\/code>.<\/p>\n
$ brew doctor\n$ brew update\n$ brew upgrade\n<\/code><\/pre>\n
Manage multiple versions of Python with pyenv<\/h3>\n
nvm<\/code> (for more details see this blog post<\/a>)<\/p>\n
pyenv<\/code>.<\/p>\n
$ brew install pyenv\n<\/code><\/pre>\n
pyenv<\/code> to your ~\/.zshrc<\/p>\n
$ echo -e 'if command -v pyenv 1>\/dev\/null 2>&1; then\\n eval "$(pyenv init -)"\\nfi' >> ~\/.zshrc\n<\/code><\/pre>\n
Install the latest version of Python 3<\/h3>\n
pyenv<\/code>.<\/p>\n
$ pyenv install --list\n<\/code><\/pre>\n
$ pyenv install 3.9.2\n...\npython-build: definition not found: 3.9.2\n# Bummer! pyenv haven't added 3.9.2 yet. You could try\n# brew update && brew upgrade pyenv\n# but the latest pyenv has is 3.9.1\n\n$ pyenv install 3.9.1\n...\nInstalled Python-3.9.1 to \/Users\/andre\/.pyenv\/versions\/3.9.1\n\n$ pyenv version\nsystem (set by \/Users\/andre\/.pyenv\/version)\n<\/code><\/pre>\n
$ pyenv global 3.9.1\n$ pyenv version\n3.9.1 (set by \/Users\/andre\/.pyenv\/version)\n\n# You might have to relaunch the terminal session\n$ python --version\nPython 3.9.1\n<\/code><\/pre>\n
$ pip install --upgrade pip\n...\nSuccessfully installed pip-21.0.1\n<\/code><\/pre>\n
$ which python\n\/Users\/andre\/.pyenv\/shims\/python\n\n$ python --version\nPython 3.9.1\n\n$ pip --version\npip 21.0.1 from \/Users\/andre\/.pyenv\/versions\/3.9.1\/lib\/python3.9\/site-packages\/pip (python 3.9)\n<\/code><\/pre>\n
Create a new Python based project<\/h2>\n
venv<\/code>.<\/p>\n
# Create a new project\n$ mkdir my-new-project\n$ cd my-new-project\n\n# Install a virtual environment\n$ python3 -m venv .\/venv\n<\/code><\/pre>\n
$ source venv\/bin\/activate\n(venv) ~\/...\/my-new-project\n<\/code><\/pre>\n
Installing 3rd party packages<\/h3>\n
(venv)$ pip install click\n...\nSuccessfully installed click-7.1.2\nWARNING: You are using pip version 20.2.3; however, version 21.0.1 is available.\nYou should consider upgrading via the '\/Users\/andre\/temp\/my-new-project\/venv\/bin\/python3 -m pip install --upgrade pip' command.\n<\/code><\/pre>\n
# Upgrade virtual environment pip\n(venv)$ python3 -m pip install --upgrade pip\nSuccessfully installed pip-21.0.1\n<\/code><\/pre>\n
(venv)$ pip list\nPackage Version\n---------- -------\nclick 7.1.2\npip 21.0.1\nsetuptools 49.2.1\n<\/code><\/pre>\n
(venv)$ pip freeze > requirements.txt\n(venv)$ cat requirements.txt\nclick==7.1.2\n<\/code><\/pre>\n
(venv)$ python -m pip install -r requirements.txt\n<\/code><\/pre>\n
\u256d ~\/Learning\/faasd\/helloworld\/helloworld\n\u2570 $ ls\n__init__.py handler.py requirements.txt\n\n$ cd ..\/\n$ grep -R 'requirements.txt' .\/\n...\n.\/\/template\/python3\/Dockerfile:COPY requirements.txt .\n.\/\/template\/python3\/Dockerfile:RUN pip install -r requirements.txt --target=\/home\/app\/python\n<\/code><\/pre>\n