Azure / azure-functions-python-worker

Python worker for Azure Functions.
http://aka.ms/azurefunctions
MIT License
332 stars 100 forks source link

[BUG] Starlette app throws 'State' object has no attribute 'dbpool' when deployed as an az func but runs normally with uvicorn #1273

Open charalamm opened 1 year ago

charalamm commented 1 year ago

Investigative information

Please provide the following:

Repro steps

export DATABASE_URL="postgresql://<username>:<password>@<domain>:5432/<database>"
import azure.functions as func

from fastapi import Depends, FastAPI, Query
from psycopg import OperationalError
from psycopg_pool import PoolTimeout
from typing import Dict

fapp = FastAPI()

@fapp.get("/healthz", description="Health Check", tags=["Health Check"])
def ping(
    timeout: int = Query(1, description="Timeout getting SQL connection from the pool.")
) -> Dict:
    """Health check."""
    try:
        with fapp.state.dbpool.connection(timeout) as conn:
            with conn.cursor() as cursor:
                cursor.execute("SELECT 1;")
                version = cursor.fetchone()
        return {"database_online": True}
    except (OperationalError, PoolTimeout):
        return {"database_online": False}

app = func.AsgiFunctionApp(app=fapp, http_auth_level=func.AuthLevel.ANONYMOUS)
func start

Expected behavior

I expect to get a response

Actual behavior

There is a 500 response and the error in the function is Exception: AttributeError: 'State' object has no attribute 'dbpool'

Full error:

Result: Failure Exception: AttributeError: 'State' object has no attribute 'dbpool' Stack: File "/azure-functions-host/workers/python/3.10/LINUX/X64/azure_functions_worker/dispatcher.py", line 475, in _handle__invocation_request call_result = await self._run_async_func( File "/azure-functions-host/workers/python/3.10/LINUX/X64/azure_functions_worker/dispatcher.py", line 758, in _run_async_func return await ExtensionManager.get_async_invocation_wrapper( File "/azure-functions-host/workers/python/3.10/LINUX/X64/azure_functions_worker/extension.py", line 147, in get_async_invocation_wrapper result = await function(**args) File "/azure-functions-host/workers/python/3.10/LINUX/X64/azure/functions/decorators/function_app.py", line 2068, in http_app_func return await asgi_middleware.handle_async(req, context) File "/azure-functions-host/workers/python/3.10/LINUX/X64/azure/functions/_http_asgi.py", line 199, in handle_async return await self._handle_async(req, context) File "/azure-functions-host/workers/python/3.10/LINUX/X64/azure/functions/_http_asgi.py", line 204, in _handle_async asgi_response = await AsgiResponse.from_app(self._app, File "/azure-functions-host/workers/python/3.10/LINUX/X64/azure/functions/_http_asgi.py", line 80, in from_app await app(scope, res._receive, res._send) File "/home/site/wwwroot/.python_packages/lib/site-packages/fastapi/applications.py", line 271, in __call__ await super().__call__(scope, receive, send) File "/home/site/wwwroot/.python_packages/lib/site-packages/starlette/applications.py", line 118, in __call__ await self.middleware_stack(scope, receive, send) File "/home/site/wwwroot/.python_packages/lib/site-packages/starlette/middleware/errors.py", line 184, in __call__ raise exc File "/home/site/wwwroot/.python_packages/lib/site-packages/starlette/middleware/errors.py", line 162, in __call__ await self.app(scope, receive, _send) File "/home/site/wwwroot/.python_packages/lib/site-packages/starlette_cramjam/middleware.py", line 112, in __call__ await responder(scope, receive, send) File "/home/site/wwwroot/.python_packages/lib/site-packages/starlette_cramjam/middleware.py", line 142, in __call__ await self.app(scope, receive, self.send_with_compression) File "/home/site/wwwroot/.python_packages/lib/site-packages/titiler/core/middleware.py", line 62, in __call__ await self.app(scope, receive, send_wrapper) File "/home/site/wwwroot/.python_packages/lib/site-packages/starlette/middleware/cors.py", line 84, in __call__ await self.app(scope, receive, send) File "/home/site/wwwroot/.python_packages/lib/site-packages/starlette/middleware/exceptions.py", line 79, in __call__ raise exc File "/home/site/wwwroot/.python_packages/lib/site-packages/starlette/middleware/exceptions.py", line 68, in __call__ await self.app(scope, receive, sender) File "/home/site/wwwroot/.python_packages/lib/site-packages/fastapi/middleware/asyncexitstack.py", line 21, in __call__ raise e File "/home/site/wwwroot/.python_packages/lib/site-packages/fastapi/middleware/asyncexitstack.py", line 18, in __call__ await self.app(scope, receive, send) File "/home/site/wwwroot/.python_packages/lib/site-packages/starlette/routing.py", line 706, in __call__ await route.handle(scope, receive, send) File "/home/site/wwwroot/.python_packages/lib/site-packages/starlette/routing.py", line 276, in handle await self.app(scope, receive, send) File "/home/site/wwwroot/.python_packages/lib/site-packages/starlette/routing.py", line 66, in app response = await func(request) File "/home/site/wwwroot/.python_packages/lib/site-packages/fastapi/routing.py", line 237, in app raw_response = await run_endpoint_function( File "/home/site/wwwroot/.python_packages/lib/site-packages/fastapi/routing.py", line 165, in run_endpoint_function return await run_in_threadpool(dependant.call, **values) File "/home/site/wwwroot/.python_packages/lib/site-packages/starlette/concurrency.py", line 41, in run_in_threadpool return await anyio.to_thread.run_sync(func, *args) File "/home/site/wwwroot/.python_packages/lib/site-packages/anyio/to_thread.py", line 33, in run_sync return await get_asynclib().run_sync_in_worker_thread( File "/home/site/wwwroot/.python_packages/lib/site-packages/anyio/_backends/_asyncio.py", line 877, in run_sync_in_worker_thread return await future File "/home/site/wwwroot/.python_packages/lib/site-packages/anyio/_backends/_asyncio.py", line 807, in run result = context.run(func, *args) File "/home/site/wwwroot/.python_packages/lib/site-packages/titiler/pgstac/factory.py", line 637, in register_search with request.app.state.dbpool.connection() as conn: File "/home/site/wwwroot/.python_packages/lib/site-packages/starlette/datastructures.py", line 705, in __getattr__ raise AttributeError(message.format(self.__class__.__name__, key))

Known workarounds

Contents of the requirements.txt file:

It is a FastAPI app

Related information

bhagyshricompany commented 1 year ago

Thanks for informing . pls provide the func name.invocation id,time ,region etc

charalamm commented 1 year ago

@bhagyshricompany Just updated the issue with the required info

bhagyshricompany commented 1 year ago

As we investigated found psycopg_pool lib not working so working on that will update you once done