I have, for example, this function
I deployed it with VS Code using the following F1
option in VS Code
Nonetheless, when I go to the function app portal, it shows nothing under the functions submenu:
I don't know why I am not being able to see my functions in my function app, what am I missing?
Here is the dummy code of the function:
import azure.functions as func
import logging
import os
from azure.identity import DefaultAzureCredential
from azure.keyvault.secrets import SecretClient
from azure.communication.email import EmailClient
from datetime import timezone, timedelta, datetime
import jwt
import bcrypt
import pymssql
import json
from azure.identity import DefaultAzureCredential
from azure.keyvault.secrets import SecretClient
app = func.FunctionApp(http_auth_level=func.AuthLevel.ANONYMOUS)
@app.route(route="actualizar_contrasena", auth_level=func.AuthLevel.ANONYMOUS)
def actualizar_contrasena(req: func.HttpRequest) -> func.HttpResponse:
import json
try:
req_body = req.get_json()
username_to_check = req_body.get("username")
password_to_check = str(req_body.get("password"))
# do things
return func.HttpResponse(
json.dumps(
{"access_token": 1, "refresh_token": 1}
),
status_code=200,
)
except Exception as e:
return func.HttpResponse(str(e), status_code=500)
UPDATE
After following @RithwikBoj instructions, I'm in the same situation. I have observed that locally I can't see the functions neither:
This is my host.json
:
{
"version": "2.0",
"logging": {
"applicationInsights": {
"samplingSettings": {
"isEnabled": true,
"excludedTypes": "Request"
}
}
},
"extensionBundle": {
"id": "Microsoft.Azure.Functions.ExtensionBundle",
"version": "[4.*, 5.0.0)"
}
}
And this is my structure:
root
|_.venv
|_.funcignore
|_host.json
|_function_app.py
|_ local.settings.json
This is my requirements.txt
azure-common==1.1.28
azure-communication-email==1.0.0
azure-core==1.32.0
azure-functions==1.21.3
azure-identity==1.19.0
azure-keyvault-secrets==4.9.0
azure-mgmt-core==1.5.0
bcrypt==4.2.1
certifi==2024.12.14
cffi==1.17.1
charset-normalizer==3.4.1
cryptography==44.0.0
idna==3.10
isodate==0.7.2
jwt==1.3.1
msal==1.31.1
msal-extensions==1.2.0
msrest==0.7.1
oauthlib==3.2.2
portalocker==2.10.1
pycparser==2.22
PyJWT==2.10.1
pymssql==2.3.2
requests==2.32.3
requests-oauthlib==2.0.0
six==1.17.0
typing_extensions==4.12.2
urllib3==2.3.0
I tried to deploy using my github repo. This is the yaml:
# Docs for the Azure Web Apps Deploy action: https://github.com/azure/functions-action
# More GitHub Actions for Azure: https://github.com/Azure/actions
# More info on Python, GitHub Actions, and Azure Functions: https://aka.ms/python-webapps-actions
name: Build and deploy Azure Function App - fnc-app-d
on:
push:
branches:
- develop
workflow_dispatch:
env:
AZURE_FUNCTIONAPP_PACKAGE_PATH: '.' # set this to the path to your web app project, defaults to the repository root
PYTHON_VERSION: '3.11' # set this to the python version to use (supports 3.6, 3.7, 3.8)
jobs:
build:
runs-on: ubuntu-latest
permissions:
contents: read #This is required for actions/checkout
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup Python version
uses: actions/setup-python@v5
with:
python-version: ${{ env.PYTHON_VERSION }}
- name: Create and start virtual environment
run: |
python -m venv venv
source venv/bin/activate
- name: Install dependencies
run: pip install -r requirements.txt
# Optional: Add step to run tests here
- name: Zip artifact for deployment
run: zip -r release.zip function_app.py host.json -x "*.txt venv/*" ".git/*" ".github/* *.md .gitignore local.*"
- name: Upload artifact for deployment job
uses: actions/upload-artifact@v4
with:
name: python-app
path: |
.
!venv/
deploy:
runs-on: ubuntu-latest
needs: build
permissions:
id-token: write #This is required for requesting the JWT
contents: read #This is required for actions/checkout
steps:
- name: Download artifact from build job
uses: actions/download-artifact@v4
with:
name: python-app
path: .
- name: Unzip artifact for deployment
run: unzip -o release.zip
- name: Login to Azure
uses: azure/login@v2
with:
client-id: ${{ secrets.AZUREAPPSERVICE_CLIENTID_06 }}
tenant-id: ${{ secrets.AZUREAPPSERVICE_TENANTID_88510E }}
subscription-id: ${{ secrets.AZUREAPPSERVICE_SUBSCRIPTIONID_38D5 }}
- name: 'Deploy to Azure Functions'
uses: Azure/functions-action@v1
id: deploy-to-function
with:
app-name: 'fnc-app-d'
package: ${{ env.AZURE_FUNCTIONAPP_PACKAGE_PATH }}
I realised that the requirements.txt has something wrong with it in the Function App
And the folder structure has not been updated, because I removed the Readme.md a while ago:
UPDATE I have edited the yaml, now it uploads the requirements.txt file correctly
UPDATE 2
I have deleted all imports except os, logging and azure.functions. After that, I can deploy correctly my function. Butm when I for example add import jwt
to the python script, it disappears again. I need to add libraries to the script, that is my main issue
UPDATE 3 Adding the import inside the definition of each function seems to work:
@app.route(route="log_in_user", auth_level=func.AuthLevel.ANONYMOUS)
def log_in_user(req: func.HttpRequest) -> func.HttpResponse:
import json
import jwt # ADDED HERE THE LIBRARY
try:
req_body = req.get_json()
username_to_check = req_body.get("username")
password_to_check = str(req_body.get("password"))
p = jwt.encode({"pass": password_to_check}, "assaasassa", algorithm="HS256")
return func.HttpResponse(
json.dumps(
{"access_token": 1, "refresh_token": 1, "p": p}
),
status_code=200,
)
except Exception as e:
return func.HttpResponse(str(e), status_code=500)
It is now deployed. But when I try to execute it in Azure:
Result: Failure Exception: ModuleNotFoundError: No module named 'jwt'
The error message is clear that jwt
package is not installed.
You already have jwt
in the requirements.txt, the issue is in the github yaml pipeline. The build step activats virtual env and installs packages into the virtual env. However, your zip step excludes these venv\*
. This is the reason the python packages do not exist on function app when you invoke the http trigger.
- name: Create and start virtual environment
run: |
python -m venv venv
source venv/bin/activate
- name: Install dependencies
run: pip install -r requirements.txt
# Optional: Add step to run tests here
- name: Zip artifact for deployment
run: zip -r release.zip function_app.py host.json -x "*.txt venv/*" ".git/*" ".github/* *.md .gitignore local.*"
To validate if jwt
is really installed or not on FA, you can browse files using vs code
The reason moving import jwt
into log_in_user
worked is that this function is not invoked until a http trigger is executed. when you put import jwt
on the top of the file, this line is executed during function startup.
There are a few ways to deploy a python function, let's try this method first to test it out. This method gives you most visibility of what is happening under the hood.
func azure functionapp publish <function app name>
in git bash
or any terminal window. i.e. func azure functionapp publish test3339
deployment
tab under function app to see the final status of deployment to be sure:This is a great guide to read through. the cmd deployment is under Deploy the function project to Azure
section.
If confirmed working in above method, you can refer to this guide to setup github action to deploy via pipeline. It is important to add venv
to .gitignore
so that these files are excluded from repo (also pipeline build)
when you run the func start
locally with virtual env, the python packages are installed to system folder.
You have the option to create virtual env and active it to keep local python env clean. this is the purpose of .venv folder. I think VS Code by default creates one for your project.
py -m venv env
.\env\Scripts\activate
But when deploying to Azure, the build process will install all the packages for you and it does not use the virtual env inside .venv folder.