question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Behavior of `include_router` method

See original GitHub issue

Hi, I would like to prepare a tool responsible for logging the requests & responses. I have found out, that the best way to do it is to prepare a custom APIRoute class. My case is that I have got one main APIRouter to which I’m pinning a lot of smaller ones, in the code, it looks like:

router_1 = APIRouter()
router_2 = APIRouter()
router_3 = APIRouter()

api_router = APIRouter(route_class=MyLoggingClass)

api_router.include_router(router_1)
api_router.include_router(router_2)
api_router.include_router(router_3)

The problem is that the pinned small routers are not overwriting their own route_class from the main one, because of what MyLoggingClass has never been called and I can’t capture my logs. When I am calling api_router.routes all objects are still APIRoute instances instead of MyLoggingClass. Is it a proper behavior of the include_router method? Shouldn’t it interfere with the object which is being added and change his route_class to the one to which is he being added?

If yes, do you folks know any way how to achieve my goal without any workarounds?

Thanks in advance for your comments & help! 😃

EDIT: Added full copy & paste code snippet which describes the whole situation include actual output and expected output inside docstring:

from typing import Callable

from fastapi import APIRouter, FastAPI, Request, Response
from fastapi.routing import APIRoute


class TestRoute(APIRoute):
    def get_route_handler(self) -> Callable:
        original_route_handler = super().get_route_handler()

        async def custom_route_handler(request: Request) -> Response:
            response = await original_route_handler(request)
            print("Example print... -.^")
            return response

        return custom_route_handler


app = FastAPI()
api_router = APIRouter(route_class=TestRoute)
router_1 = APIRouter()
router_2 = APIRouter()
router_3 = APIRouter(route_class=TestRoute)


@router_1.get("/router_1")
async def r_1():
    return {"I am router": 1}


@router_2.get("/router_2")
async def r_2():
    return {"I am router": 2}


@router_3.get("/router_3")
async def r_3():
    return {"I am router": 3}

api_router.include_router(router_1)
api_router.include_router(router_2)
api_router.include_router(router_3)


@app.get("/")
async def api_r():
    return {"Routes": str(api_router.routes)}


app.include_router(api_router)


"""
Actual output:
{
    "Routes":"
        [
            <fastapi.routing.APIRoute object at 0x7fa1d7dd8e50>, 
            <fastapi.routing.APIRoute object at 0x7fa1d7de41f0>, 
            <fastapi.routing.TestRoute object at 0x7fa1d7de4f70>, 
        ]"
}

Expected output:
{
    "Routes":"
        [
            <fastapi.routing.TestRoute object at 0x7fa1d7dd8e50>, 
            <fastapi.routing.TestRoute object at 0x7fa1d7de41f0>, 
            <fastapi.routing.TestRoute object at 0x7fa1d7de4f70>, 
        ]"
}

"""

Issue Analytics

  • State:open
  • Created 3 years ago
  • Reactions:1
  • Comments:5

github_iconTop GitHub Comments

1reaction
Kskowcommented, Feb 21, 2021

@aalifadv thanks for the answer!

My first thought and implementation were Middleware, but then I hit the wall while I was trying to get the request and response body.

According to the topics I found it is impossible to fetch the request body via Middleware - it’s coming from Starlette implementation as I understand.

https://github.com/tiangolo/fastapi/issues/394 https://github.com/tiangolo/fastapi/issues/1123

I can pin the logger to each view and at the begging create a log from request and at the end from response or prepare Dependency pinned to the router which will create a log from request and in the middleware log the response, but my goal is to prepare one functionality which will make both that is why I put my eyes into APIRoute which according to the comments inside above topics, should be helpful 😃

0reactions
prakhar5augcommented, Jun 21, 2022

same issue with me does any one have a workaround

Read more comments on GitHub >

github_iconTop Results From Across the Web

Routers - Django REST framework
REST framework adds support for automatic URL routing to Django, and provides you with a simple, quick and consistent way of wiring your...
Read more >
A Complete Beginner's Guide to React Router (Including ...
But, with the push method they can. However, you can use props.history.replace('/) to mimic the Redirect behavior.
Read more >
Common Routing Tasks - Angular
This topic describes how to implement many of the common tasks associated with adding the Angular router to your application.
Read more >
Troubleshooting Duplicate Router IDs with OSPF - Cisco
The default behavior of the selection of the highest IP address on a ... In this example, the router ID for the OSPF...
Read more >
Django REST Framework Views - ViewSets - TestDriven.io
This ViewSet provides the GET HTTP method, mapped to a list action ... view behavior along with the get_object and get_queryset methods.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found