Redirect means sending users from one URL to another, usually after performing some action or checking some condition (such as authentication, payment, etc.). This concise, example-based article will walk you through a couple of different ways to create redirects in FastAPI (a modern Python web framework).
Using RedirectResponse (recommended)
This solution uses the RedirectResponse
class from fastapi.responses
to return a response that redirects the client to a different URL. It takes 2 main parameters: url
and status_code
:
url
: Determines the destination URL that you want the client to go to.status_code
: Set the HTTP status code that indicates the type of redirect. The default value is 307 (Temporary Redirect).
There are different types of redirects, but the most common ones are:
- 301 Moved Permanently: This means that the resource has been permanently moved to a new location, and the browser should always use the new URL in the future.
- 302 Found: This means that the resource has been temporarily moved to a new location, but the browser may use the old URL again in the future.
- 303 See Other: This means that the resource has been successfully processed, and the browser should go to a different URL to get the result.
Code example:
from fastapi import FastAPI
from fastapi.responses import RedirectResponse
import starlette.status as status
app = FastAPI()
@app.get("/")
async def main():
# Redirect to /docs (relative URL)
return RedirectResponse(url="/docs", status_code=status.HTTP_302_FOUND)
@app.get("/sling-academy")
async def sling_academy():
# Redirect to an absolute URL
return RedirectResponse(
url="https://api.slingacademy.com", status_code=status.HTTP_302_FOUND
)
Now get the app up and running by executing this command:
uvicorn main:app --reload
Then go to http://localhost:8000
and http://localhost:8000/sling-academy
to test it out.
This approach is simple and easy to use, and it supports both relative and absolute URLs.
Using Request.scope (advanced)
This solution uses the request.scope
attribute to modify the request path, headers, and parameters before processing it by another path operation function. It does not require sending a redirection response to the client. However, there are some trade-offs you should be aware of:
- This approach requires accessing and modifying the low-level
request.scope
attribute, which may not be documented or stable. - May cause unexpected behavior or errors if not handled carefully.
- The code is longer and more complicated than using
RedirectResponse
.
The steps:
- Import
Request
fromfastapi
. - Define a middleware function that takes a
request
object and acall_next
function as arguments. - In the middleware function, check if the request path matches a certain format or condition.
- If yes, change the
request.scope['path']
value to the target path. - Optionally, you can also modify the
request.scope['headers']
andrequest.scope['query_string']
values to change the request headers and parameters. - Return the result of calling
call_next(request)
. - Register the middleware function with
app.middleware("http")
.
Complete example:
from fastapi import FastAPI, Request
app = FastAPI()
# Define a middleware that will reroute all requests to /old to /new, and change the headers and parameters
@app.middleware("http")
async def reroute_middleware(request: Request, call_next):
if request.url.path.startswith("/old"):
# Change the request path
request.scope["path"] = request.url.path.replace("/old", "/new")
# Change the request headers
headers = dict(request.scope["headers"])
headers[b"x-rerouted"] = b"yes"
request.scope["headers"] = [(k, v) for k, v in headers.items()]
# Change the request parameters
request.scope["query_string"] = b"sling=academy"
response = await call_next(request)
return response
@app.get("/old")
async def old():
return "This is the old endpoint"
@app.get("/new")
async def new(request: Request):
return {
"msg": "This is the new endpoint",
"headers": request.headers,
"params": request.query_params,
}
Conclusion
You’ve learned 2 different techniques to make redirection in FastAPI. In most cases, you’ll only need the first one. However, the second technique is worth knowing. This tutorial ends here. Happy coding & have a nice day!