A guide to setup a development environment using Homebrew, Python 3.9.1 & 3.8.6, Pyenv, Poetry, Tensorflow, Numpy, Pandas and Scipy on new Apple Silicon M1 macs running Big Sur 11.1. Note that while working through this guide, it's best practice to restart your terminal after each installation / major change affecting your .zshrc file.
Install Xcode:
- install xcode from app store v12+
- then install CommandLine Tools
xcode-select --install
- set CommandLine Tools version under Xcode Preferences > Locations
- add SDKROOT Path to .zshrc file
export SDKROOT="/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk"
- restart terminal
Install Homebrew:
cd /opt
sudo mkdir homebrew
sudo chown -R $(whoami) /opt/homebrew
curl -L https://github.com/Homebrew/brew/tarball/master | tar xz --strip 1 -C homebrew
echo "export PATH=/opt/homebrew/bin:$PATH" >> ~/.zshrc
- restart terminal
Install brew dependencies:
brew install libjpeg openblas openssl readline sqlite3 xz zlib
Install Pyenv:
- install Pyenv using Pyenv Installer instead of brew (will allow a working 3.9.1 install)
curl -L https://github.com/pyenv/pyenv-installer/raw/master/bin/pyenv-installer | bash
- add the following to your .zshrc file:
# pyenv
export PATH="$HOME/.pyenv/bin:$PATH"
if command -v pyenv 1>/dev/null 2>&1; then
eval "$(pyenv init -)"
fi
- restart terminal
Install python 3.9.x:
brew install python
- make sure
python3 -Vresults in newly installed version
Install pipx to manage global packages:
python3 -m pip install --user pipx
python3 -m userpath append ~/.local/bin
Install global packages:
python3 -m pipx install flake8
python3 -m pipx install black
- make sure your .zshrc file looks similar to this (replace "YOUR_USER_NAME" with your name):
export PATH="/opt/homebrew/bin:/Users/YOUR_USER_NAME/Library/Python/3.9/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Library/Apple/usr/bin:$PATH"
export SDKROOT="/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk"
# pyenv
export PATH="$HOME/.pyenv/bin:$PATH"
if command -v pyenv 1>/dev/null 2>&1; then
eval "$(pyenv init -)"
fi
# python3 Alias
alias python="python3"
# pipx
export PATH="~/.local/bin:$PATH"
- note the creation of a python3 Alias in the snippet above, this will prevent poetry from defaulting to python 2.
Install Python 3.9.1 in Pyenv:
pyenv install 3.9.1 or update: version 3.9.4 now available, so modify as desired
Install Python 3.8.6 in Pyenv:
CFLAGS="-I$(brew --prefix openssl)/include -I$(brew --prefix bzip2)/include -I$(brew --prefix readline)/include -I$(xcrun --show-sdk-path)/usr/include -I$(brew --prefix xz)/include" LDFLAGS="-L$(brew --prefix openssl)/lib -L$(brew --prefix readline)/lib -L$(brew --prefix zlib)/lib -L$(brew --prefix bzip2)/lib -L$(brew --prefix xz)/lib" pyenv install --patch 3.8.6 <<(curl -sSL https://raw.githubusercontent.com/Homebrew/formula-patches/113aa84/python/3.8.3.patch\?full_index\=1)
Install Python 3.8.9 in Pyenv (submitted by sergeyklay):
CFLAGS="-I$(brew --prefix openssl)/include -I$(brew --prefix bzip2)/include -I$(brew --prefix readline)/include -I$(xcrun --show-sdk-path)/usr/include -I$(brew --prefix xz)/include" LDFLAGS="-L$(brew --prefix openssl)/lib -L$(brew --prefix readline)/lib -L$(brew --prefix zlib)/lib -L$(brew --prefix bzip2)/lib -L$(brew --prefix xz)/lib" pyenv install --patch 3.8.9 <<(curl -sSL https://raw.githubusercontent.com/Homebrew/formula-patches/master/python/3.8.7.patch\?full_index\=1)
Set Pyenv Global for Poetry:
pyenv global 3.9.1
Install Poetry:
curl -sSL https://raw.githubusercontent.com/sdispater/poetry/master/get-poetry.py | python
poetry config virtualenvs.in-project true
Protect Global & Brew Python Packages from Mishaps:
- add following to bottom of .zshrc
### Add these next lines to protect your system python from
### pollution from 3rd-party packages
# pip should only run if there is a virtualenv currently activated
export PIP_REQUIRE_VIRTUALENV=true
# commands to override pip restriction above.
# use `gpip` or `gpip3` to force installation of
# a package in the global python environment
# Never do this! It is just an escape hatch.
gpip(){
PIP_REQUIRE_VIRTUALENV="" pip "$@"
}
gpip3(){
PIP_REQUIRE_VIRTUALENV="" pip3 "$@"
}
Create Poetry Project
poetry new name_of_project
cd name_of_project
pyenv local 3.8.6
- check python version with
python -V - should result in
3.8.6
Manually Install Tensorflow (which will also install Numpy and other dependencies) into Poetry Environment:
- Download Apple's Tensorflow package.
- https://github.com/apple/tensorflow_macos/releases/download/v0.1alpha1/tensorflow_macos-0.1alpha1.tar.gz
- create a
packagesfolder inside your new poetry project - extract then copy all of the
whlfiles from the apple tensorflow release into theyour_new_project/packages/folder - download the Repack of apples tensorflow from the releases section of this repository and copy it into the
your_new_project/packages/folder (the Repack resolves dependency issues and includes a rebuild of pandas, scipy and pillow for M1) - edit the
[tool.poetry.dependencies]section of theproject.tomlfile inside your project folder to look like this:
[tool.poetry.dependencies]
python = "^3.8"
numpy = {path = "packages/numpy-1.18.5-cp38-cp38-macosx_11_0_arm64.whl"}
grpcio = {path = "packages/grpcio-1.33.2-cp38-cp38-macosx_11_0_arm64.whl"}
h5py = {path = "packages/h5py-2.10.0-cp38-cp38-macosx_11_0_arm64.whl"}
tensorflow = {path = "packages/tensorflow-2.4.0rc0-cp38-cp38-macosx_11_0_arm64.whl"}
tensorflow_addons = {path = "packages/tensorflow_addons-0.11.2+mlcompute-cp38-cp38-macosx_11_0_arm64.whl"}
pandas = {path = "packages/pandas-1.2.0-cp38-cp38-macosx_11_1_arm64.whl"}
scipy = {path = "packages/scipy-1.6.0-cp38-cp38-macosx_11_1_arm64.whl"}
pillow = {path = "packages/Pillow-8.1.0-cp38-cp38-macosx_11_1_arm64.whl"}
- also note the python version is set to
^3.8, this is important for apples packages, as they are not compatible with3.9 - the scipy and pillow wheels require
python 3.8.6, they will not work on later versions like3.8.7 - Note: if you want all your poetry projects to default to
3.8instead of3.9, just usepyenv local 3.8.6in the base directory where you create and house your poetry projects. Or you could usepyenv global 3.8.6. Your call. - then install the packages while inside your project folder:
poetry add ./packages/tensorflow-2.4.0rc0-cp38-cp38-macosx_11_0_arm64.whl - after the above packages have been installed, you should be able to proceed with standard poetry installations of matplotlib, etc.
Known Issues:
- seaborn causes segmentation fault in scipy
Download VSCode for MacOS Arm64:
- EDIT: You no longer require the insiders edition of VSCode, the regular version is now a Universal Binary supporting Apple Silicon
- https://code.visualstudio.com/docs/?dv=darwinarm64&build=insiders
- you might have to temporarily disable the pip protections in your .zshrc while setting up some of the python modules in vscode
#export PIP_REQUIRE_VIRTUALENV=true
#gpip(){
# PIP_REQUIRE_VIRTUALENV="" pip "$@"
#}
#gpip3(){
# PIP_REQUIRE_VIRTUALENV="" pip3 "$@"
#}
Sources:
- https://medium.com/@briantorresgil/definitive-guide-to-python-on-mac-osx-65acd8d969d0
- https://gist.githubusercontent.com/nrubin29/bea5aa83e8dfa91370fe83b62dad6dfa/raw/48f48f7fef21abb308e129a80b3214c2538fc611/homebrew_m1.sh
- https://towardsdatascience.com/tensorflow-2-4-on-apple-silicon-m1-installation-under-conda-environment-ba6de962b3b8
- pyenv/pyenv#1767
- python-poetry/poetry#76