Closed PabloRuizCuevas closed 7 months ago
@PabloRuizCuevas thanks for reporting! i am able to run the async code at module level as shown below:
import azure.functions as func
import logging
import asyncio
app = func.FunctionApp(http_auth_level=func.AuthLevel.ANONYMOUS)
async def test():
"""some async function"""
await asyncio.sleep(1)
logging.info('Asyncio function executed successfully.')
return "test"
@app.route(route="http_trigger")
def http_trigger(req: func.HttpRequest) -> func.HttpResponse:
logging.info('Python HTTP trigger function processed a request.')
name = req.params.get('name')
if not name:
try:
req_body = req.get_json()
except ValueError:
pass
else:
name = req_body.get('name')
asyncio.run(test())
if name:
return func.HttpResponse(f"Hello, {name}. This HTTP triggered function executed successfully.")
else:
return func.HttpResponse(
"This HTTP triggered function executed successfully. Pass a name in the query string or in the request body for a personalized response.",
status_code=200
)
import logging
import asyncio
async def test():
"""some async function"""
await asyncio.sleep(1)
logging.info('Asyncio function executed successfully.')
return "test"
by default asyncio apis shall reuse the current event loop in the function execution context which is the worker loop unless explicitly passing your own loop.
Please refer to this link https://learn.microsoft.com/en-us/azure/azure-functions/python-scale-performance-reference#managing-event-loop if you want to manage worker loop yourself. but we dont have native support for customer managed loops which may generate unexpected behaviors
You are creating a function http_trigger and then calling inside there, but I'm just calling it in the imports as a dependency so it gets executed at module level. Unfortunately i didn't find the way of reusing the event loop, but is what my snipet tries,
by design python function worker manages and run the event loop at runtime. there is a way to add task to worker managed event loop as shown in this example:
import asyncio
import json
import logging
import azure.functions as func
from time import time
from requests import get, Response
async def invoke_get_request(eventloop: asyncio.AbstractEventLoop) -> Response:
# Wrap requests.get function into a coroutine
single_result = await eventloop.run_in_executor(
None, # using the default executor
get, # each task call invoke_get_request
'SAMPLE_URL' # the url to be passed into the requests.get function
)
return single_result
async def main(req: func.HttpRequest) -> func.HttpResponse:
logging.info('Python HTTP trigger function processed a request.')
eventloop = asyncio.get_event_loop()
# Create 10 tasks for requests.get synchronous call
tasks = [
asyncio.create_task(
invoke_get_request(eventloop)
) for _ in range(10)
]
done_tasks, _ = await asyncio.wait(tasks)
status_codes = [d.result().status_code for d in done_tasks]
return func.HttpResponse(body=json.dumps(status_codes),
mimetype='application/json')
customer can put the operations need to be handled by the worker loop into tasks and have them submitted to worker loop. can you give this a try?
however run_until_complete can be called once per loop only.
also python function worker does not manage or execute code execution outside the function natively(ex. code from module A when importing the top level module A in function_app.py are executed by python simply but worker execute functions in its managed way by attaching function context, invocation id, etc) and encourages running the business logic within function.
This issue has been automatically marked as stale because it has been marked as requiring author feedback but has not had any activity for 4 days. It will be closed if no further activity occurs within 3 days of this comment.
Check for a solution in the Azure portal
For issues in production, please check for a solution to common issues in the Azure portal before opening a bug. In the Azure portal, navigate to your function app, select
Diagnose and solve problems
from the left, and view relevant dashboards before opening your issue.Investigative information
Please provide the following:
Repro steps
Notice that test is called at module level, But in an azure function app this simple code it doesn't work.
Expected behavior
It works.
Actual behavior
It doesn't work:
Thi probably means that the function app is already running his own event loop so you can't run it twice.
Known workarounds
None known
many tried like making a run function that gets the loop of the function app
but it doesn't work
Related information
Provide any related information