2
votes

I have created one HttpTrigger Azure functions using python. But I want to create another one HttpTrigger Azure Functions using python in the same project. In this application I want to execute first HttpTrigger Azure functions after that second HttpTrigger Azure functions execute. How can I implement that?

Because in Python Azure Functions there is no Durable Functions. That's why I am not able to understood how can I execute one after another azure function executes.

1
Just call the public URL (https://<functionapp>.azurewebsites.net/api/<function>) of the second function from your first function. You could convert the 2nd function to trigger on a queue and output a queue message from your first HttpTrigger function.. but that's just gratuitous complexity unless you absolutely need it. - evilSnobu
@evilSnobu Thanks for the reply. I will check and update you - Akshay Godase

1 Answers

0
votes

Assumed there are two HttpTrigger functions HttpTriggerA and HttpTriggerB, a direct solution in my mind is to request the public url of HttpTriggerA from HttpTriggerB function via a HTTP client request using requests, as the code below in my first version of HttpTriggerB code.

import logging

import azure.functions as func
import requests
from urllib.parse import urlparse

def main(req: func.HttpRequest) -> func.HttpResponse:
    logging.info('Python HTTP trigger function processed a request.')

    name = req.params.get('name') or 'Peter Pan'
    codeA = req.params.get('codeA') or ''
    o = urlparse(req.url)
    if not name:
        try:
            req_body = req.get_json()
        except ValueError:
            pass
        else:
            name = req_body.get('name')

    if name:
        print("B be invoked.")
        resp = requests.get(f"{o.scheme}://{o.netloc}/api/HttpTriggerA?name={name}&code={codeA}")
        return func.HttpResponse(f"Hello {name}! from B {resp.status_code == 200 and resp.text or ''}")
    else:
        return func.HttpResponse(
             "Please pass a name on the query string or in the request body",
             status_code=400
        )

However, it will not work after I test the code above on local or on Azure. It will hang at the code line resp = requests.get(f"{o.scheme}://{o.netloc}/api/HttpTriggerA?name={name}&code={codeA}"), when I access the url http(s)://<the host of local or Azure>:<7071 or 80>/api/HttpTriggerB?name=Peter%20Pan&code=<code for HttpTriggerB>&codeA=<code for HttpTriggerA>. The reason for the hang issue seems to be caused by functions running in singleton or in single thread.

So I switched to the other solution to use Ajax request from the html content of HttpTriggerB. It works as I wish as the figure below.

enter image description here

Here is my code for HttpTriggerB function, the HttpTriggerA function is simply generated by func new.

import logging

import azure.functions as func
#import requests
from urllib.parse import urlparse

def main(req: func.HttpRequest) -> func.HttpResponse:
    logging.info('Python HTTP trigger function processed a request.')

    name = req.params.get('name') or 'Peter Pan'
    codeA = req.params.get('codeA') or ''
    o = urlparse(req.url)
    if not name:
        try:
            req_body = req.get_json()
        except ValueError:
            pass
        else:
            name = req_body.get('name')

    if name:
        print("B be invoked.")
        #resp = requests.get(f"{o.scheme}://{o.netloc}/api/httptriggera?name={name}&code={req.params.get('codeA')}")
        html = """
<script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>

Hello """+name+"""! from B<br/>
<span id="A"></span>

<script>
$.when( 
  $.get('"""+o.scheme+'://'+o.netloc+'/api/HttpTriggerA?name='+name+'&code='+codeA+"""'),
  $.ready
).done(function( data ) {
  $( "#A" ).html( data[0] );
});
</script>
"""
        return func.HttpResponse(html, mimetype="text/html")
    else:
        return func.HttpResponse(
             "Please pass a name on the query string or in the request body",
             status_code=400
        )

Hope it helps.