Reputation: 517
I am using FastAPI to make get/post/put/del
requests, which all work perfectly fine in the browser. I wanted to use Postman to do the exact same thing; however, I am running into an issue trying to do anything other than GET
. Below is the error I am getting:
{
"detail": [
{
"loc": [
"body"
],
"msg": "field required",
"type": "value_error.missing"
}
]
}
422 Unprocessable Entity
is the exact error.
Below is the code I am using:
from lib2to3.pytree import Base
from fastapi import FastAPI, Path, Query, HTTPException, status, File, Form
from typing import Optional, Dict, Type
from pydantic import BaseModel
import inspect
app = FastAPI()
class Item(BaseModel):
name: str
price: float
brand: Optional[str] = None
class UpdateItem(BaseModel):
name: Optional[str] = None
price: Optional[float] = None
brand: Optional[str] = None
inventory = {}
@app.get("/get-item/{item_id}")
def get_item(item_id: int = Path(None, description = "The ID of the item")):
if item_id not in inventory:
raise HTTPException(status_code = 404, detail = "Item ID not found")
return inventory[item_id]
@app.get("/get-by-name/")
def get_item(name: str = Query(None, title = "Name", description = "Test")):
for item_id in inventory:
if inventory[item_id].name == name:
return inventory[item_id]
# return {"Data": "Not found"}
raise HTTPException(status_code = 404, detail = "Item ID not found")
@app.post("/create-item/{item_id}")
def create_item(item_id: int, item: Item):
if item_id in inventory:
raise HTTPException(status_code = 400, detail = "Item ID already exists")
inventory[item_id] = item
print(type(item))
return inventory[item_id]
@app.put("/update-item/{item_id}")
def update_item(item_id: int, item: UpdateItem):
if item_id not in inventory:
# return {"Error": "Item does not exist"}
raise HTTPException(status_code = 404, detail = "Item ID not found")
if item.name != None:
inventory[item_id].name = item.name
if item.brand != None:
inventory[item_id].brand = item.brand
if item.price != None:
inventory[item_id].price = item.price
return inventory[item_id]
@app.delete("/delete-item/{item_id}")
def delete_item(item_id: int = Query(..., description="ID of item you want to delete", ge=0)):
if item_id not in inventory:
# return {"Error": "ID does not exist"}
raise HTTPException(status_code = 404, detail = "Item ID not found")
del inventory[item_id]
return {"Success": "Item deleted"}
I tried this possible solution with no luck: https://github.com/tiangolo/fastapi/issues/2387
Upvotes: 1
Views: 10579
Reputation: 626870
In my case, since I was passing a parameter as fastapi.Form()
, all I needed was to send it via Body
> form-data
.
When you POST, you should not use explicit params after ?
in the URL. So, you need to define your method like
from fastapi import Form
# ...
@app.post("/create-item") # NOTE {item_id} is REMOVED!
def create_item(item_id: int = Form(), item: Item): # NOTE: item_id: int = Form()
if item_id in inventory:
raise HTTPException(status_code = 400, detail = "Item ID already exists")
inventory[item_id] = item
print(type(item))
return inventory[item_id]
And then
Upvotes: 0
Reputation: 154
On postman you need to change headers, by default, the value of Content-Type
is plain/text
, change it to application/json
.
View answer at
POST request response 422 error {'detail': [{'loc': ['body'], 'msg': 'value is not a valid dict', 'type': 'type_error.dict'}]}
Upvotes: 1
Reputation: 34199
Your endpoint expects Item
as JSON
(body
) data, but the screenshot you provided shows that you are sending the required fields as Query
parameters (using the Params
tab in Postman); hence, the error that the body
is missing. You should instead add your data to the body
of your POST
request in Postman. To do that, you should go to Body
> raw
, and select JSON
from the dropdown list to indicate the format of your data. Your payload should look something like this:
{
"name": "foo",
"price": 1.50
}
See related answers here and here as well. In case you needed to pass the parameters of Item
model as Query
parameters, you should then use Depends()
, as described in this answer (Method 2).
Upvotes: 1