Contents

Create a local Azure Functions project

Environment settings

python-on-rosetta2-m1mac

  • MacOS Monterey 12.3, M1 Apple silicon
  • Rosetta 2
    1
    2
    
    % uname -a
    Darwin xxx 21.4.0 Darwin Kernel Version 21.4.0: Mon Feb 21 20:35:58 PST 2022; root:xnu-8020.101.4~2/RELEASE_ARM64_T6000 x86_64
    
  • pyenv 2.3.18
  • Python 3.9.16
  • Homebrew 4.0.20
  • azure-functions-core-tools@4/4.0.5198

Create Functions project on local environment

Create virtual environment

At your project directory on Rosetta2 (x86_64) emulator environment, create python virtual environment.

1
2
% python -m venv .venv
% source .venv/bin/activate

Create a local Azure Functions Project

Run the bellow commands on the above virtual environment.

1
func init LocalFunctionProj --python -m V2

Move to the project directory.

1
cd LocalFunctionProj

Add below to the end of function_app.py.

1
2
3
4
@app.function_name(name="HttpTrigger1")
@app.route(route="hello")
def test_function(req: func.HttpRequest) -> func.HttpResponse:
    return func.HttpResponse("HttpTrigger1 function processed a request!")

Ref: learn.microsoft.com | Azure Functions HTTP のトリガーとバインド

Launch storage emulator

AzureWebJobStorage setting

At local.settings.json, set AzureWebJobsStorage as UseDevelopmentStorage=true.

Install azurite

I firstly tried VSCode extension. but it does not support command line on azurite. So, I changed the step with npm.

Install nvm on Rosetta2

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.37.2/install.sh | bash

# Add environmental variables
export NVM_DIR="$([ -z "${XDG_CONFIG_HOME-}" ] && printf %s "${HOME}/.nvm" || printf %s "${XDG_CONFIG_HOME}/nvm")"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" 

# To verify you are running in Rosetta run:
arch
-> i386

# Install node
nvm install lts/fermium

# Verify node installation
nvm use lts/fermium
node -e 'console.log(process.arch)'
-> x64

# Add alias for nvm
nvm alias intel lts/fermium

By adding alias, we can switch the npm by nvm use intel and check it by node -e 'console.log(process.arch)'.

Ref:

Install azurite by npm

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
% arch
i386

% npm --version
6.14.18

% npm install -g azurite
...
+ azurite@3.23.0
added 278 packages from 287 contributors in 41.197s

Run azurite

On your Functions project,

1
2
3
4
5
6
7
% azurite
Azurite Blob service is starting at http://127.0.0.1:10000
Azurite Blob service is successfully listening at http://127.0.0.1:10000
Azurite Queue service is starting at http://127.0.0.1:10001
Azurite Queue service is successfully listening at http://127.0.0.1:10001
Azurite Table service is starting at http://127.0.0.1:10002
Azurite Table service is successfully listening at http://127.0.0.1:10002

Run func and call API

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
% func start
Found Python version 3.9.16 (python3).

Azure Functions Core Tools
Core Tools Version:       4.0.5198 Commit hash: N/A  (64-bit)
Function Runtime Version: 4.21.1.20667

[2023-06-03T12:48:27.395Z] Worker process started and initialized.

Functions:

	HttpTrigger1:  http://localhost:7071/api/hello

Then you can call API endpoint from from a browser in your local device.

http://localhost:7071/api/hello

1
HttpTrigger1 function processed a request!

summary of ~/.zshrc

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# rosetta terminal setup
if [ $(arch) = "i386" ]; then
    # alias python="/usr/local/bin/python3"
    alias brew86='/usr/local/bin/brew'
    alias pyenv86="arch -x86_64 pyenv"
    alias func="/usr/local/Cellar/azure-functions-core-tools@4/4.0.5198/func"

    export LDFLAGS="-L/usr/local/opt/zlib/lib"
    export CPPFLAGS="-I/usr/local/opt/zlib/include"
    export CFLAGS="-I$(brew86 --prefix openssl)/include"

    export CFLAGS="-I$(brew86 --prefix openssl)/include -I$(brew86 --prefix bzip2)/include -I$(brew86 --prefix readline)/include -I$(xcrun --show-sdk-path)/usr/include" LDFLAGS="-L$(brew86 --prefix openssl)/lib -L$(brew86 --prefix readline)/lib -L$(brew86 --prefix zlib)/lib -L$(brew86 --prefix bzip2)/lib"

    eval "$(/usr/local/bin/brew shellenv)"
    export PYENV_ROOT="$HOME/.pyenv-x86"
    eval "$(pyenv86 init --path)"
    eval "$(pyenv86 init -)"


    # export PYENV_ROOT="$HOME/.pyenv"
    command -v pyenv86 >/dev/null || export PATH="$PYENV_ROOT/bin:$PATH"
fi


export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"  # This loads nvm
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion"  # This loads nvm bash_completion

References