Python Azure Function Debugging in Pipenv virtual environment

Creating virtual environment

$ mkdir python_demo
$ cd python_demo
$ pyenv local 3.9.6
$ pipenv --python $(pyenv which python)
$ pipenv --venv
$ pipenv install ptvsd -d

Activating virtual environment

$ pipenv shell

Creating Azure Function Project

$ func init --python -m V2

Creating Azure Function Triggers

$ func new --name HttpExample --template "HTTP trigger" --authlevel "anonymous"
$ func new --name TimerTrigger --template "Timer trigger"
$ func new --name QueueTrigger --template "Queue trigger" --authlevel "anonymous"
$ func new --name BlobTrigger --template "Blob trigger"
$ func new --name CosmosDBTrigger --template "Cosmos DB trigger"
$ func new --name ServiceBusQueueTrigger --template "Service Bus Queue trigger"
$ func new --name ServiceBusTopicTrigger --template "Service Bus Topic trigger"
$ func new --name EventHubTrigger --template "Event Hub trigger"
$ func new --name EventGridTrigger --template "Event Grid trigger"
$ func new --name IoTHubTrigger --template "IoT Hub (Event Hub) trigger"
$ func new --name SignalRTrigger --template "SignalR Service trigger"
$ func new --name DurableOrchestratorTrigger --template "Durable Functions orchestrator trigger"
$ func new --name DurableActivityTrigger --template "Durable Functions activity trigger"
$ func new --name DurableHTTPStarter --template "Durable Functions HTTP starter"
$ func new --name RabbitMQTrigger --template "RabbitMQ trigger"
$ func new --name KafkaTrigger --template "Kafka trigger"

Opening VSCode

$ pipenv shell
$ code .

After opening VSCode, terminal will activate virtual environment as below;

If it doesn't activate it, close vscode and reopen it.

Don't forget to activate virtual environment in terminal before opening vscode, otherwise vscode debugger try to use different python runtime, in this use case, even i create virtual environment for python 3.9 with pipenv, vscode debugger try to use python 3.10 but Azure Function can run with python 3.9.

Vscode config files

We need to update two vscode config files to debug tasks.jsonsettings.json files.

{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Attach to Python Functions",
            "type": "python",
            "request": "attach",
            "port": 9091,
            "preLaunchTask": "func: host start"
        }
    ]
}
{
  "version": "2.0.0",
  "tasks": [
    {
      "label": "func: host start",
      "type": "shell",
      "command": "func host start --language-worker -- '-m ptvsd --host 127.0.0.1 --port 9091'",
      "problemMatcher": "$func-python-watch",
      "isBackground": true,
      "dependsOn": "pip install (functions)"
    },
    {
      "label": "pip install (functions)",
      "type": "shell",
      "osx": {
        "command": "${config:azureFunctions.pythonVenv}/bin/python -m pip install -r requirements.txt"
      },
      "windows": {
        "command": "${config:azureFunctions.pythonVenv}\\Scripts\\python -m pip install -r requirements.txt"
      },
      "linux": {
        "command": "${config:azureFunctions.pythonVenv}/bin/python -m pip install -r requirements.txt"
      },
      "problemMatcher": []
    },
    {
      "label": "Run Azurite",
      "type": "shell",
      "command": "azurite",
      "isBackground": true,
      "problemMatcher": "$tsc"
    }
  ]
}

update value of azureFunctions.pythonVenv to your environment name. Just update python_demo-3.9 to your virtual environment name.

{
    "azureFunctions.deploySubpath": ".",
    "azureFunctions.scmDoBuildDuringDeployment": true,
    "azureFunctions.pythonVenv": "/Users/kenanhancer/.local/share/virtualenvs/python_demo-3.9",
    "azureFunctions.projectLanguage": "Python",
    "azureFunctions.projectRuntime": "~4",
    "debug.internalConsoleOptions": "neverOpen",
    "azureFunctions.projectLanguageModel": 2
}
{
  "recommendations": [
    "ms-azuretools.vscode-azurefunctions",
    "ms-python.python"
  ]
}

Vscode start azurite to start Azure Function

Azurite is local emulator of Azure. Azure function needs azurite so that when we run func host start , azure function app will connect to Azurite storage acount, so click CMD+SHIFT+P in VSCode and type azurite: start and enter.

Debugging Azure Function locally

Click CMD+SHIFT+P and type Debug: Start Debugging as shown in below screenshot or just click F5 shortcut.

VSCode will ask for storage account, so select Use Local Emulator for local development.

This will update line 6 in local.settings.json

{
  "IsEncrypted": false,
  "Values": {
    "FUNCTIONS_WORKER_RUNTIME": "python",
    "AzureWebJobsFeatureFlags": "EnableWorkerIndexing",
    "AzureWebJobsStorage": "UseDevelopmentStorage=true"
  }
}

Testing Azure HTTP and Webhook Triggered Functions Locally

$ curl http://localhost:7071/api/HttpExample\?name=Azure
$ curl -X POST -H "Content-Type: application/json" -d '{ "name": "Azure" }' http://localhost:7071/api/HttpExample

Testing Azure Non-HTTP Triggered Functions Locally

$ curl --request POST -H "Content-Type: application/json" --data '{"input":"sample queue data"}' http://localhost:7071/admin/functions/QueueFunc

Deactivating virtual environment

$ exit