title: FastAPI TypeError: Object of type 'ModelMetaclass' is not JSON serializable
body: <p>I'm getting this error, the models migrate successfully when i run <code>uvicorn main:app --reload</code> but when i tried to go to 127.0.0.1:8000/docs i got this error. I'm using  Postgresql for the database</p>
  <pre><code>TypeError: Object of type 'ModelMetaclass' is not JSON serializable
  </code></pre>
  <p>This is my file structure</p>
  <pre><code>backend/main.py
  backend/pydantic_models.py
  backend/requirements.txt
  backend/sql
  backend/sql/crud.py
  backend/sql/database.py
  backend/sql/sql_models.py
  backend/sql/__init__.py
  </code></pre>
  <p>I followed the tutorial on <a href="https://fastapi.tiangolo.com/tutorial/sql-databases/" rel="noreferrer">https://fastapi.tiangolo.com/tutorial/sql-databases/</a>
  Here is the code.
  <strong>main.py</strong></p>
  <pre><code>from typing import List
  
  from fastapi import FastAPI, Depends, HTTPException, status
  from sqlalchemy.orm import Session
  
  from sql import crud, database, sql_models
  from pydantic_models import User, Todo, UserCreation, TodoCreation
  
  
  sql_models.Base.metadata.create_all(bind=database.engine)
  
  app = FastAPI()
  
  def get_db():
      db = database.SessionLocal()
      try:
          yield db
      finally:
          db.close()
  
  
  @app.post(&quot;/users/&quot;, response_model=User)
  def create_user(user=User, db: Session = Depends(get_db)):
      db_user_email = crud.get_user_by_email(db, email=user.email)
      db_user_name = crud.get_user
      if db_user:
          raise HTTPException(status_code=status.HTTP_400_BAD,
                              detail=&quot;Email already taken&quot;)
      return crud.create_user(db=db, user=user)
  
  
  @app.get(&quot;/users/&quot;, response_model=List[User])
  def read_all_users(skip: int = 0, limit: int = 100, db: Session = Depends(get_db)):
      users = crud.get_all_users(db, skip=skip, limit=limit)
      return users
  
  
  @app.get(&quot;/users/{user_id}&quot;, response_model=User)
  def read_user(user_id: int, db: Session = Depends(get_db)):
      db_user = crud.get_user(db, user_id=user_id)
      if db_user is None:
          raise HTTPException(
              status_code=status.HTTP_404_NOT_FOUND, detail=&quot;User not found&quot;)
      return db_user
  
  
  @app.post(&quot;/users/{user_id}/todo/&quot;, response_model=Todo)
  def create_todo_list(user_id: int, todo: TodoCreation, db: Session = Depends(get_db)):
      return crud.create_todo(db=db, todo=todo, user_id=user_id)
  
  
  @app.get(&quot;/items/&quot;, response_model=List[Todo])
  def read_todo(skip: int = 0, limit: int = 100, db: Session = Depends(get_db)):
      todos = crud.get_todo(db, skip=skip, limit=limit)
      return todos
  </code></pre>
  <p><strong>pydantic_models.py</strong></p>
  <pre><code>from typing import List, Optional
  from pydantic import BaseModel
  
  
  # Todo model
  class TodoBase(BaseModel):
      title: str
      description: Optional[str] = None
  
  class TodoCreation(TodoBase):
      pass
  
  
  class Todo(TodoBase):
      id: int
      owner_id: int
  
      class Config:
          orm_mode = True
          
  # User model
  class UserBase(BaseModel):
      username: str
      email: str
  
  class UserCreation(UserBase):
      password: str
  
  class User(UserBase):
      id: int
      is_active: bool
      todo: List[Todo] = []
  
      class Config:
          orm_mode = True
  </code></pre>
  <p>sql.<strong>crud.py</strong></p>
  <pre><code>from sqlalchemy.orm import Session
  
  from . import sql_models
  import pydantic_models
  
  # Get single user
  def get_user(db: Session, user_id: int):
      return db.query(sql_models.User).filter(models.User.id == user_id).first()
  
  def get_user_by_name(db: Session, username: str):
      return db.query(sql_models.User).filter(models.User.username == username).first()
  
  # Get user by email
  def get_user_by_email(db: Session, email: str):
      return db.query(sql_models.User).filter(models.User.email == email).first()
  
  # Get all users
  def get_all_users(db: Session, skip: int = 0, limit: int = 100):
      return db.query(sql_models.User).offset(skip).limit(limit).all()
  
  # Create a user
  def create_user(db: Session, user: pydantic_models.UserCreation):
      fake_hashed_password = user.password + &quot;fakehash&quot; # Hashed user's password
      db_user = sql_models.User(username=user.username, email=user.email, password=fake_hashed_password)
      db.add(db_user)
      db.commit()
      db.refresh(db_user)
      return db_user
  
  
  def get_todo(db: Session, skip: int = 0, limit: int = 100):
      return db.query(sql_models.Todo).offset(skip).limit(limit).all()
  
  
  def create_todo(db: Session, todo: pydantic_models.TodoCreation, user_id: int):
      db_item = models.Item(**item.dict(), owner_id=user_id)
      db.add(db_item)
      db.commit()
      db.refresh(db_item)
      return db_item
  </code></pre>
  <p>sql.<strong>database.py</strong></p>
  <pre><code>import os
  
  from sqlalchemy import create_engine
  from sqlalchemy.ext.declarative import declarative_base
  from sqlalchemy.orm import sessionmaker
  
  SQLALCHEMY_DATABASE_URL = os.environ[&quot;POSTGRES_LINK&quot;]
  engine = create_engine(SQLALCHEMY_DATABASE_URL)
  SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
  
  Base = declarative_base()
  </code></pre>
  <p>sql.<strong>sql_models.py</strong></p>
  <pre><code>from sql.database import Base
  
  from sqlalchemy import Boolean, Column, ForeignKey, Integer, String
  from sqlalchemy.orm import relationship
  
  class User(Base):
      __tablename__  = &quot;users&quot;
  
      id = Column(Integer, primary_key=True, index=True)
      username = Column(String, unique=True, index=True)
      email = Column(String, unique=True, index=True)
      password = Column(String)
      is_active = Column(Boolean, default=True)
  
      todo = relationship(&quot;Todo&quot;, back_populates=&quot;owner&quot;)
  
  class Todo(Base):
      __tablename__ = &quot;todo&quot;
  
      id = Column(Integer, primary_key=True, index=True)
      title = Column(String, index=True)
      description = Column(String, index=True)
      owner_id = Column(Integer, ForeignKey(&quot;users.id&quot;))
  
      owner = relationship(&quot;User&quot;, back_populates=&quot;todo&quot;)
  </code></pre>
  <p>here is the full error</p>
  <pre><code>INFO:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
  INFO:     Started reloader process [6844] using statreload
  INFO:     Started server process [2484]
  INFO:     Waiting for application startup.
  INFO:     Application startup complete.
  INFO:     127.0.0.1:51303 - &quot;GET /docs HTTP/1.1&quot; 200 OK
  INFO:     127.0.0.1:51303 - &quot;GET /openapi.json HTTP/1.1&quot; 500 Internal Server ErrorERROR:    Exception in ASGI application
  Traceback (most recent call last):
    File &quot;c:\users\bryan\source\repos\todoapp\backend\env\lib\site-packages\uvicorn\protocols\http\h11_impl.py&quot;, line 388, in run_asgi
      result = await app(self.scope, self.receive, self.send)
    File &quot;c:\users\bryan\source\repos\todoapp\backend\env\lib\site-packages\uvicorn\middleware\proxy_headers.py&quot;, line 45, in __call__
      return await self.app(scope, receive, send)
    File &quot;c:\users\bryan\source\repos\todoapp\backend\env\lib\site-packages\fastapi\applications.py&quot;, line 179, in __call__
      await super().__call__(scope, receive, send)
    File &quot;c:\users\bryan\source\repos\todoapp\backend\env\lib\site-packages\starlette\applications.py&quot;, line 111, in __call__
      await self.middleware_stack(scope, receive, send)
    File &quot;c:\users\bryan\source\repos\todoapp\backend\env\lib\site-packages\starlette\middleware\errors.py&quot;, line 181, in __call__
      raise exc from None
    File &quot;c:\users\bryan\source\repos\todoapp\backend\env\lib\site-packages\starlette\middleware\errors.py&quot;, line 159, in __call__
      await self.app(scope, receive, _send)
    File &quot;c:\users\bryan\source\repos\todoapp\backend\env\lib\site-packages\starlette\exceptions.py&quot;, line 82, in __call__
      raise exc from None
    File &quot;c:\users\bryan\source\repos\todoapp\backend\env\lib\site-packages\starlette\exceptions.py&quot;, line 71, in __call__
      await self.app(scope, receive, sender)
    File &quot;c:\users\bryan\source\repos\todoapp\backend\env\lib\site-packages\starlette\routing.py&quot;, line 566, in __call__
      await route.handle(scope, receive, send)
    File &quot;c:\users\bryan\source\repos\todoapp\backend\env\lib\site-packages\starlette\routing.py&quot;, line 227, in handle
      await self.app(scope, receive, send)
    File &quot;c:\users\bryan\source\repos\todoapp\backend\env\lib\site-packages\starlette\routing.py&quot;, line 41, in app
      response = await func(request)
    File &quot;c:\users\bryan\source\repos\todoapp\backend\env\lib\site-packages\fastapi\applications.py&quot;, line 128, in openapi
      return JSONResponse(self.openapi())
    File &quot;c:\users\bryan\source\repos\todoapp\backend\env\lib\site-packages\fastapi\applications.py&quot;, line 106, in openapi
      self.openapi_schema = get_openapi(
    File &quot;c:\users\bryan\source\repos\todoapp\backend\env\lib\site-packages\fastapi\openapi\utils.py&quot;, line 348, in get_openapi
      result = get_openapi_path(route=route, model_name_map=model_name_map)
    File &quot;c:\users\bryan\source\repos\todoapp\backend\env\lib\site-packages\fastapi\openapi\utils.py&quot;, line 177, in get_openapi_path
      operation_parameters = get_openapi_operation_parameters(
    File &quot;c:\users\bryan\source\repos\todoapp\backend\env\lib\site-packages\fastapi\openapi\utils.py&quot;, line 95, in get_openapi_operation_parameters
      &quot;schema&quot;: field_schema(
    File &quot;pydantic\schema.py&quot;, line 184, in pydantic.schema.field_schema
    File &quot;pydantic\schema.py&quot;, line 767, in pydantic.schema.encode_default
    File &quot;pydantic\json.py&quot;, line 62, in pydantic.json.pydantic_encoder
  TypeError: Object of type 'ModelMetaclass' is not JSON serializable
  </code></pre>