Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to do a Post/Redirect/Get (PRG) in FastAPI?

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

like image 752
mrx Avatar asked May 31 '20 16:05

mrx


People also ask

How do I redirect on Fastapi?

as_form) ): event = await service. post( ... ) redirect_url = request. url_for('get_event', **{'pk': event['id']}) return RedirectResponse(redirect_url) @router. get('/{pk}', response_model=EventSingle) async def get_event( request: Request, pk: int, service: EventsService = Depends() ): ....

Is redirect POST or get?

POST: A form is sent to the server with a post-request and an entry in the database is changed. Redirect: After a post request, the correct webpage with the changed data is delivered to the client using the redirect instruction (HTTP 303). GET: The client requests a confirmation page.

Can I redirect a post request?

in response to a POST request. Rather, the RFC simply states that the browser should alert the user and present an option to proceed or to cancel without reposting data to the new location. Unless you write complex server code, you can't force POST redirection and preserve posted data.

How does HTTP POST redirect work?

In HTTP, redirection is triggered by a server sending a special redirect response to a request. Redirect responses have status codes that start with 3 , and a Location header holding the URL to redirect to. When browsers receive a redirect, they immediately load the new URL provided in the Location header.


1 Answers

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.

like image 110
Michael Kennedy Avatar answered Sep 20 '22 01:09

Michael Kennedy