As a simple example consider a tree represented as a dict
tree = {
"a": { "b": "c" },
"d": "g"
}
I would like to define a FastAPI application which allows "browsing" of this tree, using the following
GET /tree/{item1}/{item2}/...
should either return tree[item1][item2]... .keys()
if it is a dict otherwise simply the value.
My initial solution was:
from fastapi import FastAPI
app = FastAPI()
@app.get("/tree/{path:path}")
async def tree_lookup( path ):
return path # "return" for easier demonstration reasons, in actuality it is a lookup
Which when directly working with the API works as expected. Even GET /tree/
results in an empty path, which should in this case correspond with tree.keys()
however when going to /docs
to view the documentation, I cannot test the request of /tree/
because the parameter is required.
The 'solutions' I found where:
1
from fastapi import FastAPI
app = FastAPI()
@app.get("/tree/")
async def tree_lookup( path ):
return "" # "return" for easier demonstration reasons, in actuality it is a lookup
@app.get("/tree/{path:path}")
async def tree_lookup( path ):
return path # "return" for easier demonstration reasons, in actuality it is a lookup
2
from fastapi import FastAPI
app = FastAPI()
@app.get("/tree{path:path}")
async def tree_lookup( path ):
#add an extra check that path needs to start with /
return path # "return" for easier demonstration reasons, in actuality it is a lookup
Neither of which I like as 1 has duplicate code and documentation and 2 looks confusion when not aware of the reasoning behind it.
Question
Is there a better way to implement this, such that
- FastAPI can handle the empty path case
- The documentation treats this as a single access point not 2
- The documentation allows for testing of an empty path
My initial solution satisfies 1 and 2, solution 1 satisfies 1 and 3, and solution 2 technically satisfies all three but it would require extra documentation to say that /treeewew
is not a valid access point
EDIT
There is a workaround for my initial solution by accessing
tree//
which can be supplied in the swagger UI try out input.
Which would be trivial to have mapped to /tree/
but my question still remains is there a better way to do this