1

I'm using the following schemas for my FastAPI Get request:

class JWTClaims(BaseModel):
    iat: int
    exp: int
    aud: Optional[Union[str, List[str]]]
    iss: str
    sub: str
    azp: str


class AccessClaims(JWTClaims):
    scope: str


@router.get("/client")
async def get_user_client(claims:AccessClaims = Depends()):
    pass

FastAPI is trying to convert the aud field as part of a request body- how can I eliminate this so that it becomes a valid GET request?

enter image description here

  • try: `aud: Optional[Union[str, List[str]]] = None` – vaizki Sep 07 '22 at 14:04
  • That doesn't get rid of the request body. I can delete the contents of the request body and it works however this `aud` field will be populated at various points so I can't use this as a solution – equatorial_daydreamer Sep 07 '22 at 14:08
  • one more idea.. `aud: Optional[Union[str, List[str]]] = Query(default=None)`, of course you need `from fastapi import Query` – vaizki Sep 07 '22 at 14:17
  • I still get`TypeError: Failed to execute 'fetch' on 'Window': Request with GET/HEAD method cannot have body.` when I try both these ways – equatorial_daydreamer Sep 07 '22 at 14:30
  • 1
    As noted in Chris link this isn't currently possible - [the limitation is documented in the reference guide](https://fastapi.tiangolo.com/tutorial/query-params-str-validations/#query-parameter-list-multiple-values): "To declare a query parameter with a type of list, like in the example above, you need to explicitly use Query, otherwise it would be interpreted as a request body." – MatsLindh Sep 07 '22 at 20:29
  • 1
    thanks @Chris, that does clarify things a lot – equatorial_daydreamer Sep 08 '22 at 08:18

1 Answers1

0

Here a workaround, you can add the aud as argument of the route like this:

class JWTClaims(BaseModel):
    iat: int
    exp: int
    iss: str
    sub: str
    azp: str


class AccessClaims(JWTClaims):
    scope: str


app = FastAPI()


# as argument it works
@app.get("/client")
async def get_user_client(aud: Optional[List[str]] = Query(None), claims:AccessClaims = Depends()):
    return

And you have the aud in the swagger. It will be a list but, users can supply only one if they want.

The swagger with aud

For reason I don't understand, doing this in the class doesn't work:

class JWTClaims(BaseModel):
    iat: int
    exp: int
    aud: Optional[List[str]] = Query(None)
    iss: str
    sub: str
    azp: str

If you're really want the Optional[str, List[str]], you will need to have it as a body request:

@app.get("/client")
async def get_user_client(aud: Optional[Union[str, List[str]]] = Query(None), claims:AccessClaims = Depends()):
    return

leads to this error when loading the app:

    async def get_user_client(aud: Optional[Union[str, List[str]]] = Query(None), claims:AccessClaims = Depends()):
  File "/home/stackoverflow/lib/python3.10/site-packages/fastapi/routing.py", line 626, in decorator
    self.add_api_route(
  File "/home/stackoverflow/lib/python3.10/site-packages/fastapi/routing.py", line 565, in add_api_route
    route = route_class(
  File "/home/stackoverflow/lib/python3.10/site-packages/fastapi/routing.py", line 434, in __init__
    self.dependant = get_dependant(path=self.path_format, call=self.endpoint)
  File "/home/stackoverflow/lib/python3.10/site-packages/fastapi/dependencies/utils.py", line 322, in get_dependant
    assert isinstance(
AssertionError: Param: aud can only be a request body, using Body()

ndclt
  • 2,590
  • 2
  • 12
  • 26