pythonazureazure-functions

Can't add libraries to function_app.py in azure Function


I have, for example, this function

enter image description here

I deployed it with VS Code using the following F1 option in VS Code enter image description here

Nonetheless, when I go to the function app portal, it shows nothing under the functions submenu: enter image description here

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:

enter image description here

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

enter image description here

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 enter image description here

And the folder structure has not been updated, because I removed the Readme.md a while ago: enter image description here

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'

Solution

  • I have used below code and it got deployed for me and followed below process:

    function_app.py:

    import azure.functions as func
    import logging as ri_lg
    import pymssql as chop
    from azure.identity import DefaultAzureCredential
    from azure.keyvault.secrets import SecretClient
    
    rith = func.FunctionApp(http_auth_level=func.AuthLevel.ANONYMOUS)
    
    @rith.route(
        route="rith_func", methods=["POST"], auth_level=func.AuthLevel.ANONYMOUS
    )
    def rith_func(req: func.HttpRequest) -> func.HttpResponse:
        try:
            rith_rq_bdy = req.get_json()
            eml = rith_rq_bdy.get("email")
            pwd = rith_rq_bdy.get("password")
            ri_con = chop.connect(server="rithwik.database.windows.net",user="rithwik",password="RTestpass@2",database="test1")
            cho_cur = ri_con.cursor()
            cho_cur.execute("UPDATE users SET password = %s WHERE email = %s",(pwd, eml))
            ri_con.commit()
    
            return func.HttpResponse("Hello Rithwik, the Password has been updated",status_code=200)
    
        except Exception as f:
            ri_lg.error(f"Error: {f}")
            return func.HttpResponse(f"Hello Rithwik, there is an error: {f}",status_code=500)
        finally:
            if "ri_con" in locals() and ri_con:
                ri_con.close()
    

    local.settings.json:

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

    requirements.txt:

    azure-functions
    pymssql
    azure-identity
    azure-keyvault-secrets
    

    host.json:

    {
      "version": "2.0",
      "logging": {
        "applicationInsights": {
          "samplingSettings": {
            "isEnabled": true,
            "excludedTypes": "Request"
          }
        }
      },
      "extensionBundle": {
        "id": "Microsoft.Azure.Functions.ExtensionBundle",
        "version": "[4.*, 5.0.0)"
      }
    }
    

    Structure:

    RithAppFolder
    ├── __ pycache __
    ├── .venv
    ├── .vscode
    ├── .funcignore
    ├── .gitignore
    ├── function_app.py
    ├── host.json
    ├── local.settings.json
    └── requirements.txt
    

    Output:

    Deployed from VS Code:

    enter image description here

    After Deployment:

    enter image description here

    Then tested with wrong data to get 500 error:

    enter image description here

    Make sure to add all the packages.