Issue 1:
First check

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.

Description

Is it possible to somehow globally filter response that is returned from a route method? What I have in mind if there is any proper way to additionally filter response based on some context, or FastAPI dependencies (Dependency, Security etc.).

My use case is:

I have some authorization mechanism with different roles (let's say admin and user for simplicity).

Data is typical CRUD model stored in the database, and all records have boolean active column to handle "soft" delete and not remove records entirely from the database. If record was "soft" deleted the flag would be set to false.

As user with admin role I can access all records, even if they were "soft" deleted, and user role can only access the ones that have been not "soft" deleted.

Record from database is represented by pydantic model:

class MyModel(BaseModel):
id: str
name: str
active: bool = True

I have some route defined which fetches a model from database and returns it:

async def get_model(
id: str = Path(...),
current_user: User = Depends(get_current_user)
) -> MyModel:
# The `current_user` will be a model representing currently authorized user.
# In case of admin user inactive record might also be returned here.
return await fetch_model_from_db(id, user.is_admin())

The output model will have the attribute active present in any case, but I want to only preserve it for admin user and hide it from regular user role (it can access only records with active flag as true anyway). In short I would like to additionally parse response based on current_user role.

What I found

First thing I thought about was excluding certain attributes as per docummentation https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter but this only allows excluding attributes explicitly without any additional context.

Then I thought about making custom middleware, which serves the purpose of processing response object before it is returned to the client, but I couldn't find a clear way to pass down the context as current_user, so I could use that to process response and exclude unwanted attributes from response body. This however would add additional overhead as the response body is already serialized at this stage and would need to be deserialized -> filtered -> serialized again.

Additional context

I could add additional function like this and call it as the last thing in every route, but it's way too verbose and I'd rather handle it more generic way:

def filter_admin_attributes(input: Dict, is_admin: bool, attributes: Set[str]) -> Dict:
return {k: v for k, v in input.items() if not is_admin and k in attributes}

async def get_model(
id: str = Path(...),
current_user: User = Depends(get_current_user)
) -> Dict:
# The `current_user` will be a model representing currently authorized user.
# In case of admin user inactive record might also be returned here.
result = await fetch_model_from_db(id, user.is_admin())
return filter_admin_attributes(result.dict(), user.is_admin(), {'active',})

Issue 2:
from fastapi import FastAPI, Query

app = FastAPI()

@app.get('/sprints/')
async def get_sprints(userID: int, numOfSprints: int = Query(..., ge=1, lt=100)):
[...]
return answer

is applied, if numOfSprints is more than 99, response is: 422 Unprocessable Entity

but in swagger documentation isnt clear about limit:

python 3.8

latest fastapi