azure-functions-python-worker icon indicating copy to clipboard operation
azure-functions-python-worker copied to clipboard

[BUG] Azure Function AsgiMiddleware Not Responding

Open yks0000 opened this issue 2 years ago • 3 comments

Investigative information

Please provide the following:
  • Timestamp: Tue 20 Sep 2022 16:43:04 IST
  • Function App name: locally testing in VSCode
  • Core Tools version: 4.0.4736

Repro steps

Provide the steps required to reproduce the problem:
  1. Create a new Function App of type HTTP trigger and the following code in __init__.py:
import azure.functions as func
import time
import nest_asyncio
from fastapi import FastAPI, Request
from fastapi.middleware.cors import CORSMiddleware

nest_asyncio.apply()

app = FastAPI(title="FastAPI on Azure")
app.add_middleware(
    CORSMiddleware,
    allow_origins=['*'],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

@app.middleware("http")
async def add_process_time_header(request: Request, call_next):
    start_time = time.time()
    response = await call_next(request)
    process_time = time.time() - start_time
    response.headers["X-Process-Time"] = str(process_time)
    return response



async def main(req: func.HttpRequest, context: func.Context) -> func.HttpResponse:
    return func.AsgiMiddleware(app).handle(req, context)


@app.get("/")
async def root():
    return {"message": "Hello from Azure Function"}

Complete code including config is available in GitHub repo: https://github.com/yks0000/az-function-fastapi/tree/azure-worker-issue To start function app: func host start --verbose

Expected behavior

Provide a description of the expected behavior.

It should return a response when we access http://0.0.0.0:7071/

Actual behavior

Provide a description of the actual behavior observed.

No response and running forever.

Known workarounds

Provide a description of any known workarounds.

No workaround but If we stop using middleware (as below), it works, but the requirement is to use middleware.

Middleware Doc: https://fastapi.tiangolo.com/tutorial/middleware/

@app.middleware("http")
async def add_process_time_header(request: Request, call_next):
    start_time = time.time()
    response = await call_next(request)
    process_time = time.time() - start_time
    response.headers["X-Process-Time"] = str(process_time)
    return response

Contents of the requirements.txt file:

Provide the requirements.txt file to help us find out module related issues.
azure-common
azure-core
azure-functions
fastapi
nest-asyncio

Related information

Provide any related information
  • Links to source: https://github.com/yks0000/az-function-fastapi/tree/azure-worker-issue
  • Bindings used: All config are available in https://github.com/yks0000/az-function-fastapi/tree/azure-worker-issue

yks0000 avatar Sep 20 '22 11:09 yks0000

@yks0000 We will check this issue with our next level team and update you.

ramya894 avatar Sep 22 '22 10:09 ramya894

@vrdmr Can you please have a look into this issue.

ramya894 avatar Sep 23 '22 03:09 ramya894

@vrdmr @YunchuWang Any update on this please?

yks0000 avatar Oct 03 '22 19:10 yks0000

@YunchuWang Could you please have a look into the above issue

ramya894 avatar Oct 27 '22 07:10 ramya894

@yks0000 I'll clone your repo and isolate the issue.

There is a new API for the sample that removes the need for nest-asyncio and changes the main function to:

async def main(req: func.HttpRequest, context: func.Context) -> func.HttpResponse:
    return await func.AsgiMiddleware(app).handle_async(req, context)

tonybaloney avatar Nov 28 '22 23:11 tonybaloney

@yks0000 I've submitted a PR to your sample with the changes to the sample for v1.12 of the functions library

https://github.com/yks0000/az-function-fastapi/pull/1

This fixes the hanging process problem, but the app returns no response and if the add_process_time_header() function is commented out it works correctly.

I'll continue looking at this to see how the middleware chains calls to other middleware.

tonybaloney avatar Nov 29 '22 01:11 tonybaloney

Looking deeper into the issue with a debugger, when the custom middleware is added, the http.response.body message is never sent to the Azure functions library code for handling ASGI applications. I don't think it's an issue specifically with the middleware, but having 2 items in the FastAPI middleware collection seems to cause some issue

2022-11-29T02:35:00.066Z] Received {'type': 'http.response.start', 'status': 200, 'headers': [(b'content-length', b'39'), (b'content-type', b'application/json')]} from ASGI worker.
[2022-11-29T02:35:00.066Z] Received {'type': 'http.response.body', 'body': b'{"message":"Hello from Azure Function"}'} from ASGI worker.

tonybaloney avatar Nov 29 '22 02:11 tonybaloney

Thanks @tonybaloney for checking this.

yks0000 avatar Nov 29 '22 06:11 yks0000

I've submitted a fix to the related package, it might take a while for this to roll through. https://github.com/Azure/azure-functions-python-library/pull/153

In the meantime only 1 piece of middleware is supported.

tonybaloney avatar Dec 02 '22 03:12 tonybaloney