azure-functions-python-worker
azure-functions-python-worker copied to clipboard
[BUG] Starlette app throws 'State' object has no attribute 'dbpool' when deployed as an az func but runs normally with uvicorn
Investigative information
Please provide the following:
- Timestamp: 2023-06-28 08:58:35.849
- Function App name: https://raster.azurewebsites.net
- Function name(s) (as appropriate): http_app_func
- Core Tools version: 4.0.5095
- Invocation id: 9afa1aa8-76ae-4d3f-87ee-90c58bd0d927 (taken from the function logs)
- Region: West Europe
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