← baseline_full_v2

fastapi_14873

failed NO_PATCH NO_PATCH UNSUBMITTED empty_patch(None) · None tool calls · 0 s · fastapi/fastapi

Task input

🐛 Fix `on_startup` and `on_shutdown` parameters of `APIRouter`

This fixes the issue reported in this comment: https://github.com/fastapi/fastapi/pull/14851#issuecomment-3863896385

```py
from fastapi import FastAPI


def s_start():
    print("SYNC START", flush=True)


app = FastAPI(on_startup=[s_start])


@app.get("/health")
async def health():
    return {"ok": True}
```

Startup event is not called because `APIRouter.on_startup` is set in `APIRouter.__init__` before calling `super().__init__` and  is overridden by `router.__init__` (https://github.com/Kludex/starlette/blob/e5b8a5d200504a2608bed11fe6f66b1d20b9ae2c/starlette/routing.py#L597-L598)

Tool calls (0)

#ToolArgumentsResult
No trace captured.

Test output

show
.........F
=================================== FAILURES ===================================
_________________ test_startup_shutdown_handlers_as_parameters _________________

state = State(app_startup=False, app_shutdown=False, router_startup=False, router_shutdown=False, sub_router_startup=False, sub_router_shutdown=False)

    def test_startup_shutdown_handlers_as_parameters(state: State) -> None:
        """Test that startup/shutdown handlers passed as parameters to FastAPI are called correctly."""
    
        def app_startup() -> None:
            state.app_startup = True
    
        def app_shutdown() -> None:
            state.app_shutdown = True
    
        app = FastAPI(on_startup=[app_startup], on_shutdown=[app_shutdown])
    
        @app.get("/")
        def main() -> dict[str, str]:
            return {"message": "Hello World"}
    
        def router_startup() -> None:
            state.router_startup = True
    
        def router_shutdown() -> None:
            state.router_shutdown = True
    
        router = APIRouter(on_startup=[router_startup], on_shutdown=[router_shutdown])
    
        def sub_router_startup() -> None:
            state.sub_router_startup = True
    
        def sub_router_shutdown() -> None:
            state.sub_router_shutdown = True
    
        sub_router = APIRouter(
            on_startup=[sub_router_startup], on_shutdown=[sub_router_shutdown]
        )
    
        router.include_router(sub_router)
        app.include_router(router)
    
        assert state.app_startup is False
        assert state.router_startup is False
        assert state.sub_router_startup is False
        assert state.app_shutdown is False
        assert state.router_shutdown is False
        assert state.sub_router_shutdown is False
        with TestClient(app) as client:
>           assert state.app_startup is True
E           assert False is True
E            +  where False = State(app_startup=False, app_shutdown=False, router_startup=False, router_shutdown=False, sub_router_startup=False, sub_router_shutdown=False).app_startup

tests/test_router_events.py:365: AssertionError
=============================== warnings summary ===============================
../../../../../../../Users/jp/repos/kaggle-gemini-coding-agent-post-training/.envs/overlays/starlette-0.52.1-py3-none-any/starlette/testclient.py:45
  /Users/jp/repos/kaggle-gemini-coding-agent-post-training/.envs/overlays/starlette-0.52.1-py3-none-any/starlette/testclient.py:45: DeprecationWarning: The anyio.abc.BlockingPortal alias is deprecated, use anyio.from_thread.BlockingPortal instead.
    _PortalFactoryType = Callable[[], AbstractContextManager[anyio.abc.BlockingPortal]]

-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html
!!!!!!!!!!!!!!!!!!!!!!!!!! stopping after 1 failures !!!!!!!!!!!!!!!!!!!!!!!!!!!
1 failed, 9 passed, 1 warning in 0.76s