There is nothing built into the FastAPI to achieve that, but we can write it!
We need function that parse parameter:
import re
def parse_param(param, value):
regex = r"(?P<op>.*)\[(?P<col>.*)\]"
if m := re.search(r, param):
return {"op": m.group("op"), "col": m.group("col"), "val": value}
return {param: value}
Now it's time to use it, the simplest way would be use underlying Starlete request and parse url
from fastapi import Request
@app.get("/sheetName")
def endpoint(r: Request):
k, v = next(iter(r.query_params.items())) # Assuming there is only one parameter
print(parse_param(k, v))
If you would like to some FastAPI magic, you have another two options
- The middleware
@app.middleware("http")
async def preprocess(request: Request, call_next):
k, v = next(iter(request.query_params.items()))
request._query_params = QueryParams(parse_param(k, v))
request.scope["query_string"] = str(request._query_params).encode("ascii")
response = await call_next(request)
return response
- Custom request
from fastapi.routing import APIRoute
from starlette.datastructures import QueryParams
class BracketRequest(Request):
@property
def query_params(self):
k, v = next(iter(super().query_params.items()))
return QueryParams(parse_param(k, v))
class BracketRoute(APIRoute):
def get_route_handler(self):
original_route_handler = super().get_route_handler()
async def custom_route_handler(request: Request):
request = BracketRequest(request.scope, request.receive)
return await original_route_handler(request)
return custom_route_handler
app.router.route_class = BracketRoute
Second solution allows you to assign such logic only for specific routers.
In both cases you can use your endpoint with help of FastAPI validation now:
@app.get("/sheetName")
def endpoint(op: str, col: str, val: Any):
print(op, col, val)
This approach has limitations (like what if there can be more parameters? Or more parameters with brackets?) and exact solutions depends on specific needs, but they should give you enough insight how to solve them.