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.

[BUG] Path parameters not set in starlette Request object

See original GitHub issue

Describe the bug

I am trying to access the path_params for a request from the middleware using request.path_params but it shows an empty {}.

However, it works if I access the Request object from within the endpoint code.

To Reproduce

Steps to reproduce the behavior with a minimum self-contained file.

from fastapi import FastAPI

app = FastAPI()
from starlette.requests import Request

@app.get('/fib-feed/{hello}/hellos')
async def test(path: str, query1: str, query2: str, request: Request):
    print(request.path_params)     # Is correctly populated


@app.middleware("http")
async def middleware(request: Request, call_next):
    print(request.path_params)     # Empty here

Expected behavior

The path_params should be accessible in middleware too.

Environment

  • OS: macOS

  • FastAPI Version : 0.20.0 [e.g. 0.3.0], get it with:

  • Python version, get it with: 3.6.7

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Comments:5 (2 by maintainers)

github_iconTop GitHub Comments

4reactions
nsidnevcommented, Jan 15, 2020

@shalseban Hi! I’m not sure if this should be a FastAPI issue. FastAPI does nothing with the middleware system provided by Starlette, so I think that this issue should be opened in their repository. The main problem here is that path_params in Request object are filled when the route is checked for matching with the request, and this happens after the middleware called call_next callable. This way you can get path_params in middleware, but only after your route has returned the response.

As a workaround you can manualy iterate over your application routes and get path_params, as the Router class from Starlette does when matching request:

from typing import Callable

from fastapi import FastAPI
from starlette.requests import Request
from starlette.responses import Response
from starlette.routing import Match

app = FastAPI()


@app.middleware("http")
async def my_middleware(request: Request, call_next: Callable) -> Response:
    routes = request.app.router.routes
    for route in routes:
        match, scope = route.matches(request)
        if match == Match.FULL:
            print(scope["path_params"])

    return await call_next(request)


@app.get("/{param}")
def my_route(param: str) -> dict:
    return {"param": param}
0reactions
tiangolocommented, Oct 14, 2022

Thanks for the help here @nsidnev! 🙇

And thanks for coming back to close the issue @shalseban. 🍪

This is indeed not really related to FastAPI. And I think it wouldn’t be easily doable in Starlette, maybe it wouldn’t make sense fully, because the middleware has no idea about the routes that would handle the request, to extract the parameters. 🤔

Read more comments on GitHub >

github_iconTop Results From Across the Web

Requests - Starlette
Path Parameters. Router path parameters are exposed as a dictionary interface. For example: request.path_params['username']. Client Address. The ...
Read more >
Access fastapi.Request object without router method
I have a FastAPI app and on app-startup, I create a State for it like this: app.state.player["id"] = Player(). And now I want...
Read more >
FastAPI
Validation even for deeply nested JSON objects. Conversion of input data: coming from the network to Python data and types. Reading from: JSON....
Read more >
Using FastAPI to Build Python Web APIs - Real Python
First Steps. Create a First API; Run the First API App With Uvicorn ; Path Parameters: Get an Item by ID. Path Parameters...
Read more >
starlette Changelog - pyup.io
Implement `__repr__` for route classes [1864](https://github.com/encode/starlette/pull/1864). Fixed * Fix bug on which `BackgroundTasks` were cancelled when ...
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