mirror of
https://github.com/fastapi/fastapi.git
synced 2025-12-27 08:10:57 -05:00
Compare commits
9 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1c7e2540c2 | ||
|
|
9e5439959a | ||
|
|
282f372eda | ||
|
|
972a967d5d | ||
|
|
4170f621a5 | ||
|
|
67c8dfaf0f | ||
|
|
34db1e2e2c | ||
|
|
b787103226 | ||
|
|
289b4aa2fa |
@@ -14,7 +14,7 @@ repos:
|
||||
- id: end-of-file-fixer
|
||||
- id: trailing-whitespace
|
||||
- repo: https://github.com/astral-sh/ruff-pre-commit
|
||||
rev: v0.14.2
|
||||
rev: v0.14.3
|
||||
hooks:
|
||||
- id: ruff
|
||||
args:
|
||||
|
||||
@@ -70,12 +70,22 @@ If you understood all this, you already know how those utility tools for securit
|
||||
|
||||
You most probably don't need these technical details.
|
||||
|
||||
These details are useful mainly if you had a FastAPI application older than 0.118.0 and you are facing issues with dependencies with `yield`.
|
||||
These details are useful mainly if you had a FastAPI application older than 0.121.0 and you are facing issues with dependencies with `yield`.
|
||||
|
||||
///
|
||||
|
||||
Dependencies with `yield` have evolved over time to account for the different use cases and to fix some issues, here's a summary of what has changed.
|
||||
|
||||
### Dependencies with `yield` and `scope` { #dependencies-with-yield-and-scope }
|
||||
|
||||
In version 0.121.0, FastAPI added support for `Depends(scope="function")` for dependencies with `yield`.
|
||||
|
||||
Using `Depends(scope="function")`, the exit code after `yield` is executed right after the *path operation function* is finished, before the response is sent back to the client.
|
||||
|
||||
And when using `Depends(scope="request")` (the default), the exit code after `yield` is executed after the response is sent.
|
||||
|
||||
You can read more about it in the docs for [Dependencies with `yield` - Early exit and `scope`](../tutorial/dependencies/dependencies-with-yield.md#early-exit-and-scope).
|
||||
|
||||
### Dependencies with `yield` and `StreamingResponse`, Technical Details { #dependencies-with-yield-and-streamingresponse-technical-details }
|
||||
|
||||
Before FastAPI 0.118.0, if you used a dependency with `yield`, it would run the exit code after the *path operation function* returned but right before sending the response.
|
||||
|
||||
@@ -7,6 +7,21 @@ hide:
|
||||
|
||||
## Latest Changes
|
||||
|
||||
## 0.121.1
|
||||
|
||||
### Fixes
|
||||
|
||||
* 🐛 Fix `Depends(func, scope='function')` for top level (parameterless) dependencies. PR [#14301](https://github.com/fastapi/fastapi/pull/14301) by [@luzzodev](https://github.com/luzzodev).
|
||||
|
||||
### Docs
|
||||
|
||||
* 📝 Upate docs for advanced dependencies with `yield`, noting the changes in 0.121.0, adding `scope`. PR [#14287](https://github.com/fastapi/fastapi/pull/14287) by [@tiangolo](https://github.com/tiangolo).
|
||||
|
||||
### Internal
|
||||
|
||||
* ⬆ Bump ruff from 0.13.2 to 0.14.3. PR [#14276](https://github.com/fastapi/fastapi/pull/14276) by [@dependabot[bot]](https://github.com/apps/dependabot).
|
||||
* ⬆ [pre-commit.ci] pre-commit autoupdate. PR [#14289](https://github.com/fastapi/fastapi/pull/14289) by [@pre-commit-ci[bot]](https://github.com/apps/pre-commit-ci).
|
||||
|
||||
## 0.121.0
|
||||
|
||||
### Features
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"""FastAPI framework, high performance, easy to learn, fast to code, ready for production"""
|
||||
|
||||
__version__ = "0.121.0"
|
||||
__version__ = "0.121.1"
|
||||
|
||||
from starlette import status as status
|
||||
|
||||
|
||||
@@ -129,7 +129,10 @@ def get_parameterless_sub_dependant(*, depends: params.Depends, path: str) -> De
|
||||
if isinstance(depends, params.Security) and depends.scopes:
|
||||
use_security_scopes.extend(depends.scopes)
|
||||
return get_dependant(
|
||||
path=path, call=depends.dependency, security_scopes=use_security_scopes
|
||||
path=path,
|
||||
call=depends.dependency,
|
||||
scope=depends.scope,
|
||||
security_scopes=use_security_scopes,
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# For mkdocstrings and tests
|
||||
httpx >=0.23.0,<1.0.0
|
||||
# For linting and generating docs versions
|
||||
ruff ==0.13.2
|
||||
ruff ==0.14.3
|
||||
|
||||
@@ -2,7 +2,7 @@ import json
|
||||
from typing import Any, Tuple
|
||||
|
||||
import pytest
|
||||
from fastapi import Depends, FastAPI
|
||||
from fastapi import APIRouter, Depends, FastAPI, HTTPException
|
||||
from fastapi.exceptions import FastAPIError
|
||||
from fastapi.responses import StreamingResponse
|
||||
from fastapi.testclient import TestClient
|
||||
@@ -20,6 +20,11 @@ def dep_session() -> Any:
|
||||
s.open = False
|
||||
|
||||
|
||||
def raise_after_yield() -> Any:
|
||||
yield
|
||||
raise HTTPException(status_code=503, detail="Exception after yield")
|
||||
|
||||
|
||||
SessionFuncDep = Annotated[Session, Depends(dep_session, scope="function")]
|
||||
SessionRequestDep = Annotated[Session, Depends(dep_session, scope="request")]
|
||||
SessionDefaultDep = Annotated[Session, Depends(dep_session)]
|
||||
@@ -64,6 +69,12 @@ RegularSessionsDep = Annotated[
|
||||
]
|
||||
|
||||
app = FastAPI()
|
||||
router = APIRouter()
|
||||
|
||||
|
||||
@router.get("/")
|
||||
def get_index():
|
||||
return {"status": "ok"}
|
||||
|
||||
|
||||
@app.get("/function-scope")
|
||||
@@ -124,6 +135,18 @@ def get_regular_function_scope(sessions: RegularSessionsDep) -> Any:
|
||||
return StreamingResponse(iter_data())
|
||||
|
||||
|
||||
app.include_router(
|
||||
prefix="/router-scope-function",
|
||||
router=router,
|
||||
dependencies=[Depends(raise_after_yield, scope="function")],
|
||||
)
|
||||
|
||||
app.include_router(
|
||||
prefix="/router-scope-request",
|
||||
router=router,
|
||||
dependencies=[Depends(raise_after_yield, scope="request")],
|
||||
)
|
||||
|
||||
client = TestClient(app)
|
||||
|
||||
|
||||
@@ -182,3 +205,42 @@ def test_regular_function_scope() -> None:
|
||||
data = response.json()
|
||||
assert data["named_session_open"] is True
|
||||
assert data["session_open"] is False
|
||||
|
||||
|
||||
def test_router_level_dep_scope_function() -> None:
|
||||
response = client.get("/router-scope-function/")
|
||||
assert response.status_code == 503
|
||||
assert response.json() == {"detail": "Exception after yield"}
|
||||
|
||||
|
||||
def test_router_level_dep_scope_request() -> None:
|
||||
with TestClient(app, raise_server_exceptions=False) as client:
|
||||
response = client.get("/router-scope-request/")
|
||||
assert response.status_code == 200
|
||||
assert response.json() == {"status": "ok"}
|
||||
|
||||
|
||||
def test_app_level_dep_scope_function() -> None:
|
||||
app = FastAPI(dependencies=[Depends(raise_after_yield, scope="function")])
|
||||
|
||||
@app.get("/app-scope-function")
|
||||
def get_app_scope_function():
|
||||
return {"status": "ok"}
|
||||
|
||||
with TestClient(app) as client:
|
||||
response = client.get("/app-scope-function")
|
||||
assert response.status_code == 503
|
||||
assert response.json() == {"detail": "Exception after yield"}
|
||||
|
||||
|
||||
def test_app_level_dep_scope_request() -> None:
|
||||
app = FastAPI(dependencies=[Depends(raise_after_yield, scope="request")])
|
||||
|
||||
@app.get("/app-scope-request")
|
||||
def get_app_scope_request():
|
||||
return {"status": "ok"}
|
||||
|
||||
with TestClient(app, raise_server_exceptions=False) as client:
|
||||
response = client.get("/app-scope-request")
|
||||
assert response.status_code == 200
|
||||
assert response.json() == {"status": "ok"}
|
||||
|
||||
Reference in New Issue
Block a user