Azure Functions Core Tools with Python on Mac M1/M2 + @azure/static-web-apps-cli
If you’ve been trying to use Azure Functions with Python and have run into issues because the Azure Functions core tools do not support Python on Arm64, there is a workaround available.
- Install the Azure Functions Core Tools
https://learn.microsoft.com/en-us/azure/azure-functions/functions-run-local?tabs=v4%2Cwindows%2Ccsharp%2Cportal%2Cbash#install-the-azure-functions-core-tools
Please note that while Azure Functions Core Tools can now be installed via npm, for this particular case, we have chosen to use Homebrew as recommended by the documentation.
Open a terminal and use the following command to install Azure Functions Core Tools (version 4)
# brew install azure functions core tools
brew tap azure/functions
brew install azure-functions-core-tools@4
2. Install python (or make sure you have installed python)
To check your current python version
# check current Python version
python -V
You should see an output like: python 3.9.16
If you have not yet installed python, there are two ways to install python: via brew or via pyenv.
- Using Homebrew (python 3.9 is used in this case; however you can choose any versions you like)
# Install Python
brew install python@3.9
- Using pyenv
# install pyenv
brew install pyenv
After successfully installing pyenv, run the following command to install the specific version of python
# install python
pyenv install 3.9
use global
command to switch between different python versions
# switch python version
pyenv global 3.9
If you have any difficulties in installing python using pyenv, have a look at this article:
https://medium.com/@lizhuohang.selina/install-pyenv-on-mac-818098603cb2
Although you have both Azure Function Core Tools and Python ready, running func start
under your target directory may still lead to encountering the following errors:
[2023-05-08T21:29:33.030Z] Failed to initialize worker provider for: /opt/homebrew/Cellar/azure-functions-core-tools@4/4.0.5198/workers/python
[2023-05-08T21:29:33.030Z] Microsoft.Azure.WebJobs.Script: Architecture Arm64 is not supported for language python.
[2023-05-08T21:29:33.409Z] Failed to initialize worker provider for: /opt/homebrew/Cellar/azure-functions-core-tools@4/4.0.5198/workers/python
[2023-05-08T21:29:33.409Z] Microsoft.Azure.WebJobs.Script: Architecture Arm64 is not supported for language python.
To avoid encountering this error, you can refer to the official documentation, which provides instructions on how to enable the Rosetta emulator:
However, being a nonconformist, I prefer to explore uncharted territories and embrace the risks of the unknown, even if it means succumbing to the tumultuous waves of the deep blue sea. (powered by ChatGPT)
The essence of this workaround involves the following steps:
- install
grpcio
inside your python viapip
- replace the file cygrpc.cpython-39-darwin.so in azure-functions-core-tools@4 with the one in your python
The detailed commands are shown below:
# Install grpcio inside python3.9
pip3.9 install grpcio
Or if you are already under python 3.9 ( check your version using python -V )
# install grpcio inside python
pip install grpcio
Check if grpcio
is successfully installed
#check if grpcio is installed
pip freeze
You should see an output like:
grpcio==1.54.2
Keep in mind that pip
functions similarly to npm
. When using pyenv
in conjunction with pip
, the packages will be installed within the specified Python version of your preference. If you cannot locate the packages, it is likely that you are operating under the incorrect Python version. To resolve this, utilize pyenv global {version}
to switch to the appropriate version.
After the installation of grpico, the modified file of cygrpc.cpython-39-darwin.so should be ready under the following paths:
- If you are using
pyenv
for python version management
/Users/{username}/.pyenv/versions/3.9.16/lib/python3.9/site-packages/grpc/_cython/cygrpc.cpython-39-darwin.so
In the above example, Python 3.9.16 is used as a reference. Please modify the Python version accordingly to match your environment if necessary.
- If you are using
Homebrew
/opt/homebrew/lib/python3.9/site-packages/grpc/_cython/cygrpc.cpython-39-darwin.so
The file that needs to be replaced in Azure Functions Core Tools@4 can typically be found at the following path:
/opt/homebrew/Cellar/azure-functions-core-tools@4/4.0.5198/workers/python/3.9/OSX/X64/grpc/_cython/cygrpc.cpython-39-darwin.so
This path only works for Azure Functions Core Tools that is installed via Homebrew
To replace the files, you have two options: manually navigating to the respective folder locations and performing copy-paste (my recommendation), or using the following command.
- For
pyenv
# replace the file in Azure Functions Core Tools with the one from Python
cp /Users/{username}/.pyenv/versions/3.9.16/lib/python3.9/site-packages/grpc/_cython/cygrpc.cpython-39-darwin.so /opt/homebrew/Cellar/azure-functions-core-tools@4/4.0.5198/workers/python/3.9/OSX/X64/grpc/_cython/cygrpc.cpython-39-darwin.so
- For
Homebrew
installed python
# replace the file in Azure Functions Core Tools with the one from Python
cp /opt/homebrew/lib/python3.9/site-packages/grpc/_cython/cygrpc.cpython-39-darwin.so /opt/homebrew/Cellar/azure-functions-core-tools@4/4.0.5198/workers/python/3.9/OSX/X64/grpc/_cython/cygrpc.cpython-39-darwin.so
Congratulations on completing the previous steps! Now, to proceed further, you will need to
- Create a symlink for the Arm64 architecture that points to the exact same folder as the x64 architecture. (This will ensure that all the modifications made in the x64 folder are correctly applied to the Arm64 architecture as well.)
# symlink X64 to Arm64
cd /opt/homebrew/Cellar/azure-functions-core-tools@4/4.0.5198/workers/python/3.9/OSX/
ln -s X64 Arm64
- Update supportedArchitectures in the
work.config.json
.
To update the supportedArchitectures
in the work.config.json
file, follow these steps:
- Locate the
work.config.json
file in your project. - Open the
work.config.json
file in a text editor. - Add the
ARM64
architecture to thesupportedArchitectures
section. For example:
"supportedArchitectures": ["x64", "X86", "ARM64"]
4. Save the work.config.json
file.
By adding ARM64
to the supportedArchitectures
array, you are specifying that the Arm64 architecture is now supported. This ensures that the modifications made for the Arm64 architecture in the respective folder (Arm64 symlink) will be recognized and utilized accordingly.
Please note that the specific location of the work.config.json
file may vary depending on your project structure. Make sure to navigate to the correct directory or path mentioned in your particular project context.
The config file can be typically found here:
# work.config.json file path
/opt/homebrew/Cellar/azure-functions-core-tools@4/4.0.5198/workers/python
Now if you run func start
, no errors occur.
In summary:
# Install Python
brew install python@3.9
# install latest azure-function-core-tools from brew
brew install azure-functions-core-tools@4
# Install grpcio inside python3.9
pip3.9 install grpcio
# copy the lib
cp /opt/homebrew/lib/python3.9/site-packages/grpc/_cython/cygrpc.cpython-39-darwin.so /opt/homebrew/Cellar/azure-functions-core-tools@4/4.0.5198/workers/python/3.9/OSX/X64/grpc/_cython/cygrpc.cpython-39-darwin.so
# symlink X64 to Arm64
cd /opt/homebrew/Cellar/azure-functions-core-tools@4/4.0.5198/workers/python/3.9/OSX/
ln -s X64 Arm64
#edit the worker config to reference arm64
cd /opt/homebrew/Cellar/azure-functions-core-tools@4/4.0.5198/workers/python
#use your text editor of choice e.g. nano
nano worker.config.json
# update supportedArchitectures like so
"supportedArchitectures":["X64", "X86","ARM64"],
# save and exit
# in your function directory setup a python 3.9 venv (may not be necessary)
cd <path to azure functions code>
python3.9 -m venv .venv
source .venv/bin/activate
# start func
func start
Another interesting topic regarding the use of Azure Static Web App simulator:
Assuming you have the following project folder structure:
The config file staticwebapp.database.config.json
for database connection of Azure Static Web Apps has been correctly set.
And you would like to run the following command to start simulator
swa start --data-api-location swa-db-connectionsb
It is possible that you would encounter this error:
The error message explicitly states that dataApiBuilder/0.7.6
is not executing correctly, which might be puzzling as you might not have sufficient information to understand the underlying issue.
The following is the path of the folder:
/Users/{username}/.swa/dataApiBuilder/0.7.6
The solution to the issue is straightforward, yet the underlying cause remains unidentified:
- Go to the
0.7.6
folder, and look for the followingzip
file. - Unzip this file and use the extracted content to replace EVERYTHING under
0.7.6
Now, you should be able to start the emulator seamlessly.
If you still have strange errors, for example:
The solutions from the Internet would suggest you to download dotnet
, however, simply run
sudo swa start --data-api-location swa-db-connections