'FastAPI - Postman error 422 Unprocessable Entity

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.

enter image description here

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



Solution 1:[1]

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
}

If you needed to pass the Item model parameters as Query parameters, you should then use Depends(), as described in this answer (Method 2).

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1