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
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() ): ....
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.
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.
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.
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:
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)
@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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With