← baseline_full_v2

fastapi_14262

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

Task input

✨ Add support for dependencies with scopes, support `scope="request"` for dependencies with `yield` that exit before the response is sent

✨ Add support for dependencies with scopes, support `scope="request"` for dependencies with `yield` that exit before the response is sent

This adds support for

* `Depends(func, scope="request")`, the default.
* `Depends(func, scope="function")`, early exit, after the function, but before sending the response back.

---

I'm considering an alternative name for the `scope` parameter of `mode`, to avoid any confusion with OAuth scopes, e.g. `Security(scopes=["blah"])`, which is a completely different idea.

Or a potential future `Depends(oauth_scopes=["blah"])` to replace `Security(scopes=["blah"])`.

That's the only reason to consider `mode` over `scope`.

---

I'm also considering the values, currently they are:

* `"function"`: start before the *path operation function*, exit after the function returns but **before** the response is sent.
* `"request"`: start before the *path operation function* (same as above), exit **after** the response is sent back.

I'm considering an alternative name for `"request"` of `"response"`, with the same behavior.

The rationale for using `"request"` as the value is that the dependency runs around (start and end) of the *request* cycle.

The rationale for using `"response"` as the value is that the main difference with `"function"` is when the exit code is run, in `"function"` it is run *after* the function is done, in this second form (`"request"` or `"response"`) it is run *after* the *response* is sent back.

---

I'm using this interface design because I also plan on (potentially, possibly) add a new `scope="lifespan"` that would allow using dependencies (or equivalent) functions that are run only once per app, and closed when the app ends. This way the same functionality for dependencies could be used for the app lifespan (ASGI `startup` and `shutdown` events). It should be more intuitive for users to work with. But these are future plans.

---

### 2025-10-03 Edit

After asking in several places, I concluded to keep the parameter name as `scope`.

I'll also keep the current values of `"function"`, similar to pytest, and `"request"`, to avoid confusing users who could think that the dependency will start running when the response is being sent, but it starts when the request starts.

Tool calls (0)

#ToolArgumentsResult
No trace captured.

Test output

show
==================================== ERRORS ====================================
____________ ERROR collecting tests/test_dependency_yield_scope.py _____________
tests/test_dependency_yield_scope.py:23: in <module>
    SessionFuncDep = Annotated[Session, Depends(dep_session, scope="function")]
                                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
E   TypeError: Depends() got an unexpected keyword argument 'scope'
=============================== warnings summary ===============================
../../../../../../../Users/jp/repos/kaggle-gemini-coding-agent-post-training/.envs/overlays/starlette-0.49.3-py3-none-any/starlette/testclient.py:51
  /Users/jp/repos/kaggle-gemini-coding-agent-post-training/.envs/overlays/starlette-0.49.3-py3-none-any/starlette/testclient.py:51: 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 warning, 1 error in 0.53s