6

I am trying to redirect from POST to GET. How to achieve this in FastAPI?

What did you try?

I have tried below with HTTP_302_FOUND, HTTP_303_SEE_OTHER as suggested from Issue#863#FastAPI: But Nothing Works!

It always shows INFO: "GET / HTTP/1.1" 405 Method Not Allowed

from fastapi import FastAPI
from starlette.responses import RedirectResponse
import os
from starlette.status import HTTP_302_FOUND,HTTP_303_SEE_OTHER

app = FastAPI()

@app.post("/")
async def login():
     # HTTP_302_FOUND,HTTP_303_SEE_OTHER : None is working:(
     return RedirectResponse(url="/ressource/1",status_code=HTTP_303_SEE_OTHER)


@app.get("/ressource/{r_id}")
async def get_ressource(r_id:str):
     return {"r_id": r_id}

 # tes is the filename(tes.py) and app is the FastAPI instance
if __name__ == '__main__':
    os.system("uvicorn tes:app --host 0.0.0.0 --port 80")

You can also see this issue here at FastAPI BUGS Issues

mrx
  • 134
  • 1
  • 8

1 Answers1

7

I also ran into this and it was quite unexpected. I guess the RedirectResponse carries over the HTTP POST verb rather than becoming an HTTP GET. The issue covering this over on the FastAPI GitHub repo had a good fix:

POST endpoint

import starlette.status as status

@router.post('/account/register')
async def register_post():
    # Implementation details ...

    return fastapi.responses.RedirectResponse(
        '/account', 
        status_code=status.HTTP_302_FOUND)

Basic redirect GET endpoint

@router.get('/account')
async def account():
    # Implementation details ...

The important and non-obvious aspect here is setting status_code=status.HTTP_302_FOUND.

For more info on the 302 status code, check out https://httpstatuses.com/302 Specifically:

Note: For historical reasons, a user agent MAY change the request method from POST to GET for the subsequent request. If this behavior is undesired, the 307 Temporary Redirect status code can be used instead.

In this case, that verb change is exactly what we want.

Michael Kennedy
  • 2,836
  • 2
  • 22
  • 32