Reputation: 2629
I have a FastAPI app in which routes are dynamically generated based on an DB config.
However, once the routes are defined and the app running, if the config changes, there seems to be no way to reload the config so that the routes could reflect the config. The only solution I have for now is manually restart the asgi app by restarting uvicorn.
Is there any way to fully regenerate routes without stopping the app, that could ideally be called from an URL ?
Upvotes: 10
Views: 5492
Reputation: 8199
It is possible to modify routes at runtime.
FastAPI
apps have the method add_api_route
which allows you to dynamically define new endpoints. To remove an endpoint you will need to fiddle directly with the routes of the underlying Router
.
The following code shows how to dynamically add and remove routes.
import fastapi
app = fastapi.FastAPI()
@app.get("/add")
async def add(name: str):
async def dynamic_controller():
return f"dynamic: {name}"
app.add_api_route(f"/dyn/{name}", dynamic_controller, methods=["GET"])
return "ok"
def route_matches(route, name):
return route.path_format == f"/dyn/{name}"
@app.get("/remove")
async def remove(name: str):
for i, r in enumerate(app.router.routes):
if route_matches(r, name):
del app.router.routes[i]
return "ok"
return "not found"
And below is shown how to use it
$ curl 127.0.0.1:8000/dyn/test
{"detail":"Not Found"}
$ curl 127.0.0.1:8000/add?name=test
"ok"
$ curl 127.0.0.1:8000/dyn/test
"dynamic: test"
$ curl 127.0.0.1:8000/add?name=test2
"ok"
$ curl 127.0.0.1:8000/dyn/test2
"dynamic: test2"
$ curl 127.0.0.1:8000/remove?name=test
"ok"
$ curl 127.0.0.1:8000/dyn/test
{"detail":"Not Found"}
$ curl 127.0.0.1:8000/dyn/test2
"dynamic: test2"
Note though, that if you change the routes dynamically you will need to invalidate the cache of the OpenAPI endpoint.
Upvotes: 8