tiangolo/fastapi

Is there a bug in the single body pass parameter?

Closed this issue · 5 comments

Privileged issue

  • I'm @tiangolo or he asked me directly to create an issue here.

Issue Content

server

from fastapi import FastAPI
import uvicorn
from pydantic import BaseModel

app = FastAPI()

class InputParams(BaseModel):
    name:str

@app.post("/")
async def index(params:InputParams):
    return f"hello {params.name}"


uvicorn.run(app)

client

import requests
import json

host = "http://localhost:8000"
uri = "/"
url = host + uri


body = {"name": "aaa"}

response = requests.post(url, json=body)
print(response.status_code)
print(response.json())

It's OK.
server

from fastapi import FastAPI, Body
import uvicorn

app = FastAPI()

@app.post("/")
async def index(name:str=Body(), age:int=Body()):
    return f"hello {name}, {age}"


uvicorn.run(app)

client

import requests
import json

host = "http://localhost:8000"
uri = "/"
url = host + uri


body = {"name": "aaa", "age":18}

response = requests.post(url, json=body)
print(response.status_code)
print(response.json())

OK again.

server

from fastapi import FastAPI, Body
import uvicorn
from pydantic import BaseModel

app = FastAPI()

class InputParams(BaseModel):
    name:str
    age:int

@app.post("/")
async def index(params:InputParams):
    return f"hello {params.name, params.age}, "


uvicorn.run(app)

client

import requests
import json

host = "http://localhost:8000"
uri = "/"
url = host + uri


body = {"name": "aaa", "age":18}

response = requests.post(url, json=body)
print(response.status_code)
print(response.json())

ok. No problem.

But!!!!
server

from fastapi import FastAPI, Body
import uvicorn

app = FastAPI()

@app.post("/")
async def index(name:str=Body()):
    return f"hello {name}"


uvicorn.run(app)

client

import requests
import json

host = "http://localhost:8000"
uri = "/"
url = host + uri


body = {"name": "aaa"}

response = requests.post(url, json=body)
print(response.status_code)
print(response.json())

It's failed. why??? very confuse!!!

How should I call it, or where can I get knowledge about it. will the next version of fastapi be able to support this call?
help me thank you very much!

422
{'detail': [{'type': 'string_type', 'loc': ['body'], 'msg': 'Input should be a valid string', 'input': {'name': 'aaa'}}]}

import requests
import json

host = "http://localhost:8000"
uri = "/"
url = host + uri

body = {"name": "aaa"}

response = requests.post(url, json="aaa")
print(response.status_code)
print(response.json())

this is correct. but why?

In fact, such a modification can be very problematic, as there are inconsistencies in calling the method when there is only one body and multiple bodies

If you want to be able to only take one input parameter, you can do the following:

from fastapi import FastAPI, Body
import uvicorn
from typing import Annotated

app = FastAPI()

@app.post("/")
async def index(name: Annotated[str, Body(embed=True)]):
    return f"hello {name}"


uvicorn.run(app)

For a reference to the Body (in particular the embed) documentation:
https://fastapi.tiangolo.com/reference/parameters/?h=body+embed#fastapi.Body

When embed is True, the parameter will be expected in a JSON body as a key instead of being the JSON body itself.
This happens automatically when more than one Body parameter is declared.

thank you. It work