fastapi body behaving differently between two functions

Viewed 401

I have two functions and I'm using similar parameters but for one they work as expected and for the other, they do not:

from fastapi import FastAPI, Header, HTTPException, Body

@app.post("/portfolio/analytics/carbon-footprint", dependencies=[Depends(api_counter)])
async def getPortfolioCarbonFootprint(
    tickers: list = Body(...),
    func: str = Body(...),
    http_client: aiohttp.ClientSession = fastapi.Depends(http_client)
):
  
    print(tickers)
    return res

#historical prices
@app.post("/portfolio/analytics/historicalprices", dependencies=[Depends(api_counter)])
async def getPortfolioHistoricalPrices(
    tickers: list = Body(...),
    http_client: aiohttp.ClientSession = fastapi.Depends(http_client)
):
  
    print(tickers)
    jsonResults = await getHistoricalPrices(tickers)
    return jsonResults

For both I send it this json:

{"tickers" : [ "IBM.US", "MSFT.US"]}

the first function works perfectly. The second returns this error:

{
    "detail": [
        {
            "loc": [
                "body"
            ],
            "msg": "value is not a valid list",
            "type": "type_error.list"
        }
    ]
}

Here's where it gets weird. If I send this:

[ "IBM.US", "MSFT.US"]

then it works as expected.

So function 1, works fine. Function 2 is copied from function 1 and it doesn't accept tickers as input but sending it a raw list works.

1 Answers

The difference between the two functions is the number of parameters to be filled in by the user. In the first function you have tickers and func, and in the second one you only have tickers.

From the FastAPI documentation:

But if you have only a single item body parameter from a Pydantic model Item.

By default, FastAPI will then expect its body directly.

But if you want it to expect a JSON with a key item and inside of it the model contents, you can use the special Body parameter embed

So in the second function, if you want to have a key, you must write:

tickers: list = Body(..., embed=True)
Related