Skip to content

Commit 282f372

Browse files
authored
🐛 Fix Depends(func, scope='function') for top level (parameterless) dependencies (#14301)
1 parent 972a967 commit 282f372

File tree

2 files changed

+67
-2
lines changed

2 files changed

+67
-2
lines changed

fastapi/dependencies/utils.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,10 @@ def get_parameterless_sub_dependant(*, depends: params.Depends, path: str) -> De
129129
if isinstance(depends, params.Security) and depends.scopes:
130130
use_security_scopes.extend(depends.scopes)
131131
return get_dependant(
132-
path=path, call=depends.dependency, security_scopes=use_security_scopes
132+
path=path,
133+
call=depends.dependency,
134+
scope=depends.scope,
135+
security_scopes=use_security_scopes,
133136
)
134137

135138

tests/test_dependency_yield_scope.py

Lines changed: 63 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
from typing import Any, Tuple
33

44
import pytest
5-
from fastapi import Depends, FastAPI
5+
from fastapi import APIRouter, Depends, FastAPI, HTTPException
66
from fastapi.exceptions import FastAPIError
77
from fastapi.responses import StreamingResponse
88
from fastapi.testclient import TestClient
@@ -20,6 +20,11 @@ def dep_session() -> Any:
2020
s.open = False
2121

2222

23+
def raise_after_yield() -> Any:
24+
yield
25+
raise HTTPException(status_code=503, detail="Exception after yield")
26+
27+
2328
SessionFuncDep = Annotated[Session, Depends(dep_session, scope="function")]
2429
SessionRequestDep = Annotated[Session, Depends(dep_session, scope="request")]
2530
SessionDefaultDep = Annotated[Session, Depends(dep_session)]
@@ -64,6 +69,12 @@ def get_named_regular_func_session(session: SessionFuncDep) -> Any:
6469
]
6570

6671
app = FastAPI()
72+
router = APIRouter()
73+
74+
75+
@router.get("/")
76+
def get_index():
77+
return {"status": "ok"}
6778

6879

6980
@app.get("/function-scope")
@@ -124,6 +135,18 @@ def iter_data():
124135
return StreamingResponse(iter_data())
125136

126137

138+
app.include_router(
139+
prefix="/router-scope-function",
140+
router=router,
141+
dependencies=[Depends(raise_after_yield, scope="function")],
142+
)
143+
144+
app.include_router(
145+
prefix="/router-scope-request",
146+
router=router,
147+
dependencies=[Depends(raise_after_yield, scope="request")],
148+
)
149+
127150
client = TestClient(app)
128151

129152

@@ -182,3 +205,42 @@ def test_regular_function_scope() -> None:
182205
data = response.json()
183206
assert data["named_session_open"] is True
184207
assert data["session_open"] is False
208+
209+
210+
def test_router_level_dep_scope_function() -> None:
211+
response = client.get("/router-scope-function/")
212+
assert response.status_code == 503
213+
assert response.json() == {"detail": "Exception after yield"}
214+
215+
216+
def test_router_level_dep_scope_request() -> None:
217+
with TestClient(app, raise_server_exceptions=False) as client:
218+
response = client.get("/router-scope-request/")
219+
assert response.status_code == 200
220+
assert response.json() == {"status": "ok"}
221+
222+
223+
def test_app_level_dep_scope_function() -> None:
224+
app = FastAPI(dependencies=[Depends(raise_after_yield, scope="function")])
225+
226+
@app.get("/app-scope-function")
227+
def get_app_scope_function():
228+
return {"status": "ok"}
229+
230+
with TestClient(app) as client:
231+
response = client.get("/app-scope-function")
232+
assert response.status_code == 503
233+
assert response.json() == {"detail": "Exception after yield"}
234+
235+
236+
def test_app_level_dep_scope_request() -> None:
237+
app = FastAPI(dependencies=[Depends(raise_after_yield, scope="request")])
238+
239+
@app.get("/app-scope-request")
240+
def get_app_scope_request():
241+
return {"status": "ok"}
242+
243+
with TestClient(app, raise_server_exceptions=False) as client:
244+
response = client.get("/app-scope-request")
245+
assert response.status_code == 200
246+
assert response.json() == {"status": "ok"}

0 commit comments

Comments
 (0)