Skip to content
Advertisement

I want to change api response json in fastapi | pydantic

I am new in fastapi and please help me!

I got an validation error when I change the default API response comes when I use response_model in fastAPI.

The default API response is simple json like object from response_model.

user.py

from fastapi import FastAPI, Response, status, HTTPException, Depends
from sqlalchemy.orm.session import Session
import models
import schemas
from database import get_db

app = FastAPI()
@app.post('/', response_model=schemas.UserOut)
def UserCreate(users:schemas.UserBase, db:Session = Depends(get_db)):
    # print(db.query(models.User).filter(models.User.username == users.username).first().username)
    if  db.query(models.User).filter(models.User.email == users.email).first() != None:
        if users.email == db.query(models.User).filter(models.User.email == users.email).first().email:
            raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED,detail="email already exist")
    
    
    hashed_password = hash(users.password)
    users.password =hashed_password
    new_user = models.User(**users.dict())

    db.add(new_user)
    db.commit()
    db.refresh(new_user)
    # return new_user #if i uncomment this code then it will give default response which i don't want
    return {"status":True,"data":new_user, "message":"User Created Successfully"}

schemas.py

from pydantic import BaseModel, validator, ValidationError
from datetime import datetime

from typing import Optional, Text

from pydantic.networks import EmailStr
from pydantic.types import constr, conint

class UserBase(BaseModel):
    name : str
    email : EmailStr
    country: str
    city: str
    state : str
    address: str
    phone: constr(min_length=10, max_length=10)
    password: str

class UserOut(BaseModel):
    name : str
    email : EmailStr
    country: str
    city: str
    state : str
    address: str
    phone: str

    class Config:
        orm_mode = True

Now, when I run this code it gives me errors like below mentioned.

ERROR:    Exception in ASGI application
Traceback (most recent call last):
  File "/home/amit/.local/lib/python3.6/site-packages/uvicorn/protocols/http/httptools_impl.py", line 375, in run_asgi
    result = await app(self.scope, self.receive, self.send)
  File "/home/amit/.local/lib/python3.6/site-packages/uvicorn/middleware/proxy_headers.py", line 75, in __call__
    return await self.app(scope, receive, send)
  File "/home/amit/.local/lib/python3.6/site-packages/fastapi/applications.py", line 208, in __call__
    await super().__call__(scope, receive, send)
  File "/home/amit/.local/lib/python3.6/site-packages/starlette/applications.py", line 112, in __call__
    await self.middleware_stack(scope, receive, send)
  File "/home/amit/.local/lib/python3.6/site-packages/starlette/middleware/errors.py", line 181, in __call__
    raise exc
  File "/home/amit/.local/lib/python3.6/site-packages/starlette/middleware/errors.py", line 159, in __call__
    await self.app(scope, receive, _send)
  File "/home/amit/.local/lib/python3.6/site-packages/starlette/exceptions.py", line 82, in __call__
    raise exc
  File "/home/amit/.local/lib/python3.6/site-packages/starlette/exceptions.py", line 71, in __call__
    await self.app(scope, receive, sender)
  File "/home/amit/.local/lib/python3.6/site-packages/starlette/routing.py", line 656, in __call__
    await route.handle(scope, receive, send)
  File "/home/amit/.local/lib/python3.6/site-packages/starlette/routing.py", line 259, in handle
    await self.app(scope, receive, send)
  File "/home/amit/.local/lib/python3.6/site-packages/starlette/routing.py", line 61, in app
    response = await func(request)
  File "/home/amit/.local/lib/python3.6/site-packages/fastapi/routing.py", line 243, in app
    is_coroutine=is_coroutine,
  File "/home/amit/.local/lib/python3.6/site-packages/fastapi/routing.py", line 137, in serialize_response
    raise ValidationError(errors, field.type_)
pydantic.error_wrappers.ValidationError: 7 validation errors for UserOut
response -> name
  field required (type=value_error.missing)
response -> email
  field required (type=value_error.missing)
response -> country
  field required (type=value_error.missing)
response -> city
  field required (type=value_error.missing)
response -> state
  field required (type=value_error.missing)
response -> address
  field required (type=value_error.missing)
response -> phone
  field required (type=value_error.missing)

Below is the output i want:-

{
  "status": true,
  "data": {
    "name": "raj",
    "email": "rajshah123@gmail.com",
    "country": "India",
    "city": "surat",
    "state": "gujarat",
    "address": "str5654",
    "phone": "6666888899"
  },
  "message": "User Created Successfully"
}

Thank you so much.

Advertisement

Answer

The object you are returning doesn’t match your response_model. You have two options:

  1. The last line should be return new_user instead of return {"status":True,"data":new_user, "message":"User Created Successfully"}

  2. You response_model should be something like:

    class UserOutSchema(BaseModel):
       user: UserOut
       status: str
       message: str
    
    
User contributions licensed under: CC BY-SA
3 People found this is helpful
Advertisement