Skip to content

Allow access to the path operation's Response from within Dependencies using yield #3500

@adriangb

Description

@adriangb

Checks

  • I added a very descriptive title to this issue.
  • I used the GitHub search to find a similar issue and didn't find it.
  • I searched the FastAPI documentation, with the integrated search.
  • I already searched in Google "How to X in FastAPI" and didn't find any information.
  • I already read and followed all the tutorial in the docs and didn't find an answer.
  • I already checked if it is not related to FastAPI but to Pydantic.
  • I already checked if it is not related to FastAPI but to Swagger UI.
  • I already checked if it is not related to FastAPI but to ReDoc.
  • After submitting this, I commit to:
    • Read open issues with questions until I find 2 issues where I can help someone and add a comment to help there.
    • Or, I already hit the "watch" button in this repository to receive notifications and I commit to help at least 2 people that ask questions in the future.
    • Implement a Pull Request for a confirmed bug.

Problem

FastAPI's dependency injection system supports generators as dependencies (docs).

But there is currently no way to access a response generated by the path function in dependencies.
Well, you can access a response object, but it doesn't get merged with the response from the path operation.
Here's a minimal example:

from fastapi import Depends, FastAPI, Response
from fastapi.testclient import TestClient


def dependency(response: Response):
    yield
    assert response.status_code is None  # so not the same response object!


app = FastAPI(dependencies=[Depends(dependency)])

@app.get("/")
def root():
    return Response(status_code=400)


client = TestClient(app)
res = client.get("/")

If your path operation accepts a Response object and modifies and returns the same object,
then you can access data from the path operation (like status code) in the dependency.
Otherwise, you cannot.

Use case

The main use case I have for accessing this data is logging, but I imagine there may be others.

Proposed solution

I think that access to the final Response object could be enable via the generator's send functionality:

def dependency():
    response = yield
    assert response.status_code == 400

I think the main complication with this will be how FastAPI is using these generators internally.
I believe they are being wrapped in context managers, which means the ability to use .send() is lost.

Alternatives

Changing how responses are merged

I know somewhere within FastAPI Response objects get merged together.
I'm not sure if it's possible, but an alternative might be to merge into the dependency's response object instead of creating a new object or merging into the path operation's response (I am not sure which is the current behavior).
This may or may not be a breaking change, I'm not sure.

Middleware

For the particular use case of logging, it is possible to use a middleware.
But middleware's are in some ways not as flexible as dependencies.
For example, you can't apply a middleware to just some paths (for example, to avoid logging data on a path that might handle sensitive information) unless you resort to "give me a list of path regexes as a constructor parameter" in your middleware.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions