[Python] How to check the response type in the middleware?

Discussão em 'Python' iniciado por Stack, Maio 1, 2025.

  1. Stack

    Stack Membro Participativo

    I'm trying to create a middleware, the logic of which depends on the response type. Specifically, I need to close the db session after the response has been sent for "immediate" response types (like Response, HTMLResponse, JSONResponse), and don't need to close it for StreamingResponse, because I need to close the connection after the stream has finished (how to do it is another matter, maybe directly inside the generator).

    The problem is that if I print type(response), I always gen 'starlette.middleware.base._StreamingResponse', regardless of the response type that I set in the router.

    The questions are:

    1. Why does the middleware always wrap the response into the _StreamingResponse class?
    2. Is it even possible to check the response type?

    I could mitigate the problem by passing the endpoint paths, for which I don't need to close the session, but it's less scalable and requires adding new paths in case I add new streaming endpoints.

    Here is the code example:

    _engine = create_async_engine(
    f"postgresql+asyncpg://{user}:{password}@{host}:{port}/{database}"
    )
    AsyncSessionFactory = async_sessionmaker(bind=_engine, expire_on_commit=False)


    class DBSessionMiddleware(BaseHTTPMiddleware):
    async def dispatch(self, request: Request, call_next):
    request.state.db_session_factory = AsyncSessionFactory
    request.state.active_session = None

    response = await call_next(request)
    debug_logger.debug(f'response type: {type(response)}') # always prints `StreamingResponse`

    if request.state.active_session and not isinstance(response, StreamingResponse):
    request.state.active_session.close()

    return response


    # get or create the sesson from the factory
    async def get_db_session(request: Request) -> AsyncSession:
    if hasattr(request.state, "active_session") and request.state.active_session:
    session = request.state.active_session
    elif hasattr(request.state, "db_session_factory"):
    request.state.active_session = request.state.db_session_factory()
    session = request.state.active_session
    debug_logger.debug(f'session {id(session)} opened')
    else:
    session = AsyncSessionFactory()
    return cast(AsyncSession, session)

    Continue reading...

Compartilhe esta Página