Azure function not executing when called from another function: Time out error

62 views Asked by At

I've got two functions (let's call them A and B) in an Azure function app (environment: Python); both are HTTP triggered function. Function A calls function B to receive a token from an external 3rd party API endpoint. Microsoft authentication is turned on for the function app. So, function A calls B with Microsoft client credentials. The function app is developed in VScode and deployed through the Azure plugin in the cloud. This is where function A gets stuck, waiting for a response from B. But B never executes. I've tried the following:

  • Call B from a local notebook with the same client credentials while B is deployed. Works as intended; B sends out token from the cloud.
  • Execute function A locally, calling B from cloud. Works as intended; B sends out token from the cloud.
  • Trigger function B from browser. works as intended; B sends out a token that I can see from the browser.

Its only when A executes in cloud when it can't get a response from B and times out.

The client credential script I'm using:

# Dedicated Graph Access App
client_secret = 'secret'
client_id = 'client_id'

token_url = 'https://login.microsoftonline.com/<tenant_id>/v2.0/token?'
token_data = {"client_id":client_id,
            "client_secret":client_secret,
            "scope":"<client_id>/.default",
            "grant_type":"client_credentials"
            }
token_r = requests.post(token_url, data=token_data)
token = token_r.json().get('access_token')

headers = {
    'Authorization':"Bearer "+token,
    'ConsistencyLevel':'eventual'
}

Function B is called via:

accessTokenUrl = "https://appname.azurewebsites.net/api/functionName?code=<function_code>"
access_token = requests.get(accessTokenUrl, headers = headers).content.decode()

Which works when I call function B from local notebook. I know function A gets stuck waiting for B to respond because I've checked logs for B, it never executes as if never got triggered by A. And I've put some debugging messages in A which lets me know that A got up to B execution and then it timed out.

I'm at a complete loss of why this happens. Is there a specific way to call one function from another function in Azure apps? Why can't A get response from B when B executes fine by itself?

I've tried the following:

  • Call B from a local notebook with the same client credentials while B is deployed. Works as intended; B sends out token from the cloud.
  • Execute function A locally, calling B from cloud. Works as intended; B sends out token from the cloud.
  • Trigger function B from browser. works as intended; B sends out a token that I can see from the browser.
1

There are 1 answers

1
Ikhtesam Afrin On

I have created two Http triggered python V2 model functions (function_A and function_B). I am using the below code to get the token in function_A by calling function_B.

My folder structure looks like below-

enter image description here

I have the following codes in the below mentioned files.

function_app.py-

import azure.functions as func
import logging
import requests

app = func.FunctionApp(http_auth_level=func.AuthLevel.ANONYMOUS)

@app.route(route="function_A")
def function_A(req: func.HttpRequest) -> func.HttpResponse:
    logging.info('Python HTTP trigger function processed a request.')

    function_b_response = requests.get("https://{functionApp_Name}.azurewebsites.net/api/function_b")
    token = function_b_response.text.strip()
    
    return func.HttpResponse(
        f"Bearer token from function B: {token}",
        status_code=200
    )

@app.route(route="function_B", auth_level=func.AuthLevel.ANONYMOUS)
def function_B(req: func.HttpRequest) -> func.HttpResponse:
    tenant_id = '{tenant_id}'
    client_id = '{client_id}'
    client_secret = '{client_secret}'

    token_url = f'https://login.microsoftonline.com/{tenant_id}/oauth2/v2.0/token'
    token_data = {
            "client_id":client_id,
            "client_secret":client_secret,
            "scope":"{client_id}/.default",
            "grant_type":"client_credentials"
            }
    token_r = requests.post(token_url, data=token_data)
    token = token_r.json().get('access_token') 

    return func.HttpResponse(
        f"{token}",
        status_code=200
    )

requirements.txt-

azure-functions
requests

When I execute the code locally, I am able to get the token as shown below-

enter image description here

enter image description here

I deployed the functions to function app using vs code and got successfully deployed response.

enter image description here

I can see the functions in portal.

enter image description here

I can get the token upon invoking function_A in portal.

enter image description here

enter image description here

Use my code, you will get the output too.