title: FastAPI User Authentication with verification Email
body: <p>I am creating the User Authentication API route that is able to register the user if it is not already registered in the database and if an email address is in the database it will alert the user with <code>User already exists</code>.</p>
  <p>I'm trying to send the user verification email to verify the JWT token on registration, But for some reasons I couldn't able to save the user in the database whenever I try to make a new user it keeps giving me <code>User already exists</code>.</p>
  <p>Here is the API structure:</p>
  <p><strong>user_data_access_layer.py</strong></p>
  <pre><code>from sqlalchemy.orm import Session
  from sqlalchemy.sql.expression import select
  from sqlalchemy.sql import exists
  
  
  from schemas.users import UserCreate
  from db.models.users import User
  
  
  db_session = Session
  class Users():
      
      def __init__(self, db_session: Session):
          self.db_session = db_session
  
      async def save_user(self, user: UserCreate):
          if self.id == None:
              self.db_session.add(self)
              return await self.db_session.flush()
  
      async def check_user(self, email: str):
          user_exist = await self.db_session.execute(select(exists(User.email==email)))
          user = user_exist.scalar_one_or_none()
          return user
  </code></pre>
  <p><strong>route_user.py</strong></p>
  <pre><code>from fastapi import APIRouter, HTTPException, status
  from fastapi import Depends
  
  from db.models.users import User
  from schemas.users import UserCreate, ShowUser
  from db.repository.users_data_access_layer import Users
  from core.auth import Auth
  from core.hashing import Hasher
  from core.mailer import Mailer
  from core.config import Settings
  from depends import get_user_db
  
  router = APIRouter()
  
  get_settings = Settings()
  
  
  @router.post(&quot;/&quot;,response_model=ShowUser)
  async def create_user(form_data: UserCreate = Depends(), users: Users = Depends(get_user_db)):
      if await users.check_user(email=form_data.email) is not None:
          raise HTTPException(
              status_code=status.HTTP_400_BAD_REQUEST,
              detail=&quot;User already exists&quot;
          )
  
      user = User(email=form_data.email,
                  hashed_password=Hasher.get_password_hash(form_data.password),
                  is_active = False,
                  is_superuser=False)
  
      confirmation = Auth.get_confirmation_token(user.id)
      user.confirmation = confirmation[&quot;jti&quot;]
  
      try:
          Mailer.send_confirmation_message(confirmation[&quot;token&quot;], form_data.email)
      except ConnectionRefusedError:
          raise HTTPException(
              status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
              detail=&quot;Email couldn't be send. Please try again.&quot;
          )
      return await users.save_user(user)
  </code></pre>
  <p><strong>models.py</strong></p>
  <pre><code>import uuid
  from sqlalchemy.dialects.postgresql import UUID
  from sqlalchemy import Column, Integer, String, Boolean, ForeignKey
  from sqlalchemy.orm import relationship
  
  from db.base_class import Base
  
  class User(Base):
      id = Column(Integer, primary_key=True, index=True)
      username = Column(String, unique=True, nullable=False)
      email = Column(String, nullable=False, unique=True, index=True)
      hashed_password = Column(String, nullable=False)
      is_active = Column(Boolean, default=False)
      is_superuser = Column(Boolean, default=False)
      confirmation = Column(UUID(as_uuid=True), nullable=True, default=uuid.uuid4)
      jobs = relationship(&quot;Job&quot;, back_populates=&quot;owner&quot;)
  </code></pre>
  <p><strong>schemas/users.py</strong></p>
  <pre><code>from typing import Optional
  from pydantic import BaseModel, EmailStr
  
  
  class UserCreate(BaseModel):
      username: str
      email: EmailStr
      password: str
  
  class ShowUser(BaseModel):
      username: str
      email: EmailStr
      is_active: bool
  
      class Config():
          orm_mode = True
  </code></pre>