s3rius / FastAPI-template

Feature rich robust FastAPI template.
MIT License
1.94k stars 171 forks source link

Upgrading FastAPI version breaks the app #149

Closed refl3ct1on closed 2 months ago

refl3ct1on commented 1 year ago

Currently I am trying to use fastapi 0.94.0 and prometheus-fastapi-instrumentator 5.11.1 but I think the way instrumentator is initialised is not supported any more:

INFO:     Will watch for changes in these directories: ['/Users/username/project/backend']
INFO:     Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)
INFO:     Started reloader process [25843] using WatchFiles
2023-03-13 13:30:27.298 | INFO     | logging:callHandlers:1706 - Started server process [25847]
2023-03-13 13:30:27.298 | INFO     | logging:callHandlers:1706 - Waiting for application startup.
2023-03-13 13:30:27.302 | ERROR    | logging:callHandlers:1706 - Traceback (most recent call last):
  File "/Users/username/Library/Caches/pypoetry/virtualenvs/project-6TboK3_T-py3.11/lib/python3.11/site-packages/starlette/routing.py", line 675, in lifespan
    async with self.lifespan_context(app) as maybe_state:
  File "/Users/username/Library/Caches/pypoetry/virtualenvs/project-6TboK3_T-py3.11/lib/python3.11/site-packages/starlette/routing.py", line 566, in __aenter__
    await self._router.startup()
  File "/Users/username/Library/Caches/pypoetry/virtualenvs/project-6TboK3_T-py3.11/lib/python3.11/site-packages/starlette/routing.py", line 652, in startup
    await handler()
  File "/Users/username/project/backend/project/web/lifetime.py", line 60, in _startup
    setup_cors(app)
  File "/Users/username/project/backend/project/web/lifetime.py", line 35, in setup_cors
    app.add_middleware(
  File "/Users/username/Library/Caches/pypoetry/virtualenvs/project-6TboK3_T-py3.11/lib/python3.11/site-packages/starlette/applications.py", line 137, in add_middleware
    raise RuntimeError("Cannot add middleware after an application has started")
RuntimeError: Cannot add middleware after an application has started

https://github.com/trallnag/prometheus-fastapi-instrumentator/issues/214

s3rius commented 1 year ago

I guess we need to rebuild middleware stack by hand.

def startup(app: FastAPI) -> Callable[[], Awaitable[None]]:

    async def _startup() -> None:
        """Startup."""
        app.middleware_stack = None

        # Do all startup stuff
        ...

        app.middleware_stack = app.build_middleware_stack()

    return _startup

But this solution is a bit hacky. Let's leave this issue open for some time. I guess @tiangolo will fix it in new releases if we create an issue in fastapi repo.

jmugan commented 6 months ago

Can you elaborate on how to do this? I'm getting the middleware error, and I set it up like this

@app.on_event("startup")
async def startup_event():
    instrumentator = Instrumentator()
    instrumentator.instrument(app).expose(app)

Nevermind, I find this https://github.com/trallnag/prometheus-fastapi-instrumentator/issues/214#issuecomment-1441706795

s3rius commented 2 months ago

The fastapi was upgraded along with other dependencies.