from fastapi import FastAPI
app = FastAPI()
@app.get("/items")
def read_items():
return {"items": []}
@app.get("/other_items")
def read_other_items():
return {"other_items": []}
@app.get("/") # how to make this route_path to catch anything else other than "/items/" or "other_items"
def read_generic_response():
return {"Hello": "World"}
As shown in the example above I would like to set a route_path that to catch anything else other than "/items/" or "other_items"
I tried to force route.path_regex to be something more generic, but that overrode the other route_paths
for route in app.router.routes:
if isinstance(route, Route) and route.path_regex.pattern == r'^/$':
route.path_regex = re.compile('^/([\w+]?/?)+$')
Any help would be great
You can add a 404 handler, if the endpoint is not defined this will redirect the url that you specified.
from fastapi.responses import RedirectResponse
from starlette.exceptions import HTTPException as StarletteHTTPException
@app.exception_handler(StarletteHTTPException)
async def custom_http_exception_handler(request, exc):
return RedirectResponse("/")
Log:
INFO: 127.0.0.1:48258 - "GET /items HTTP/1.1" 200 OK
INFO: 127.0.0.1:48260 - "GET /not_defined_endpoint HTTP/1.1" 307 Temporary Redirect
INFO: 127.0.0.1:48260 - "GET / HTTP/1.1" 200 OK
That works @ycd, nice and clean.
Cheers
@ycd...
Although it works, the RedirectResponse modifies the url, which does not let my react app to know the initial route.
Is there another way to work this around?
Cheers
I'm not that familiar with frontend :disappointed:, but can you give this a try?
from fastapi import Request
@app.exception_handler(StarletteHTTPException)
async def custom_http_exception_handler(request, exc):
print(request.url)
url = app.url_path_for("read_generic_response")
response = RedirectResponse(url=url)
return response
I don't exactly know how you use that initial url from React but, request.url contains url that your app accepted
Out: http://127.0.0.1:8000/not_defined_endpoint
INFO: 127.0.0.1:37764 - "GET /not_defined_endpoint HTTP/1.1" 307 Temporary Redirect
INFO: 127.0.0.1:37764 - "GET / HTTP/1.1" 200 OK
Hi @ycd,
Thanks for the replies, but that was not working for me. The key point to find the solution was your hint to handle the 404 Exception. As fastAPI extends starlette it is possible to define custom HTTP exception handlers as in the code below.
# async function defined to handle the 404 Exception
async def not_found(request, exc):
response = await hello_world(request)
return response
# List of custom exception handlers
exception_handlers = {
404: not_found,
}
# Add the custom exception handlers to the fastAPI instance
app = FastAPI(exception_handlers=exception_handlers)
@app.get("/")
def hello_world():
return {"Hello": "World"}
The same way someone could use your exceptions handling suggestions but without the redirect.
```python
@app.exception_handler(StarletteHTTPException)
async def custom_http_exception_handler(request, exc):
response = await hello_world()
return response
````
Thanks for your help @ycd !!
@mrcl
I get the error
TypeError: hello_world() takes 0 positional arguments but 1 was given when the not_found handle is called.
Does this work for you?
Ops my bad,
That is not my code, just an example to explain what I did so I have not ran that code.
response = await hello_world(request) should be response = await hello_world()
With that fix it should work.
Cheers
Also updated the comment in case someone bumps on it again.
Thanks for the help here everyone! :clap: :bow:
Thanks for reporting back and closing the issue :+1:
Just for completeness, you can declare path parameters that include paths: https://fastapi.tiangolo.com/tutorial/path-params/?h=+path#path-parameters-containing-paths
This is especially useful (and almost exclusively useful) for these cases.
For example:
from fastapi import FastAPI
app = FastAPI()
@app.get("/items")
def read_items():
return {"items": []}
@app.get("/other_items")
def read_other_items():
return {"other_items": []}
@app.get("/{any_path:path}")
def read_generic_response(any_path: str):
# You could check if it's a static file and return it, or just return something else
return {"any_path": any_path}
Most helpful comment
Hi @ycd,
Thanks for the replies, but that was not working for me. The key point to find the solution was your hint to handle the 404 Exception. As fastAPI extends starlette it is possible to define custom HTTP exception handlers as in the code below.
The same way someone could use your exceptions handling suggestions but without the redirect.
```python
@app.exception_handler(StarletteHTTPException)
async def custom_http_exception_handler(request, exc):
response = await hello_world()
return response
````
Thanks for your help @ycd !!