Reputation: 135
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 User already exists
.
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 User already exists
.
Here is the API structure:
user_data_access_layer.py
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
route_user.py
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("/",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="User already exists"
)
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["jti"]
try:
Mailer.send_confirmation_message(confirmation["token"], form_data.email)
except ConnectionRefusedError:
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail="Email couldn't be send. Please try again."
)
return await users.save_user(user)
models.py
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("Job", back_populates="owner")
schemas/users.py
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
Upvotes: 0
Views: 7331
Reputation: 1
if you are using SQLAlchemy 1.4+ try this instead:
user_exist = await self.db_session.scalar(select(User).where(User.email==email))
Upvotes: 0