so no matter what I do I have 422 error on my localhost saying Validation Error, I can add users to the database but I can’t login, the /me function don’t work and I have only 200 responds in my terminal until I try to authenticate.
main.py
from fastapi import FastAPI, HTTPException, Depends
from datetime import timedelta
from contextlib import asynccontextmanager
from auth import create_access_token, get_current_user, ACCESS_TOKEN_EXPIRE_MINUTES
from models import User
from schemas import UserCreate, Token, RegisterResponse, UserValues # Use the correct schemas
from database import SessionLocal
from services import create_database, get_db
from passlib.hash import bcrypt
# Create a context manager for lifespan
@asynccontextmanager
async def lifespan(app: FastAPI):
await create_database() # Create tables at startup
yield
app = FastAPI(lifespan=lifespan)
# User registration endpoint with custom password validation[enter image description here](https://i.sstatic.net/jyAJaKrF.png)
@app.post("/register", response_model=RegisterResponse)
def register_user(user: UserCreate, db=Depends(get_db)):
# Validate the password using the property
if not user.is_valid_password:
raise HTTPException(status_code=422, detail="Password must be at least 8 characters and contain at least one uppercase letter.")
# Check if the email is already registered
if db.query(User).filter(User.Email == user.email).first():
raise HTTPException(status_code=400, detail="Email already registered.")
hashed_password = bcrypt.hash(user.password) # Hash the validated password
new_user = User(Email=user.email, Hashed_Password=hashed_password)
db.add(new_user)
db.commit()
db.refresh(new_user)
return {"message": "User created", "user_id": new_user.ID}
# Endpoint for user login, generating a JWT token
@app.post("/login", response_model=Token) # Expected response model
def login(email: str, password: str, db=Depends(get_db)):
user = db.query(User).filter(User.Email == email).first()
if not user or not bcrypt.verify(password, user.Hashed_Password):
raise HTTPException(status_code=400, detail="Invalid credentials.")
token_data = {
"sub": user.ID, # User ID
}
access_token = create_access_token(
data=token_data,
expires_delta=timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES),
)
return {"access_token": access_token, "token_type": "bearer"}
# Endpoint to get current user information based on JWT
@app.get("/me", response_model=UserValues) # Define expected response
def get_current_user_data(current_user=Depends(get_current_user)):
return {
"user_id": current_user.ID,
"email": current_user.Email,
"date_created": current_user.Date_Created,
}
schemas.py:
from pydantic import BaseModel, EmailStr
from datetime import datetime
# Schema for user registration input
class UserCreate(BaseModel):
email: EmailStr # Valid email address
password: str # Password with custom validation logic
# Enforce custom validation for password
@property
def is_valid_password(self):
if len(self.password) < 8:
return False
if not any(c.isupper() for c in self.password):
return False
return True # Valid password
# Schema for the JWT token response
class Token(BaseModel):
access_token: str # JWT token
token_type: str # Token type (typically 'bearer')
# Schema for user registration response
class RegisterResponse(BaseModel):
message: str # Confirmation message
user_id: int # User ID
# Schema for user information output
class UserValues(BaseModel):
user_id: int # User ID
email: EmailStr # User email
date_created: datetime # Date when user was created
class Config:
from_attributes = True # Enable ORM compatibility
localhost:8000/docs#/default/register
localhost:8000/docs#/default/login
when trying to login with right values
I have tried to use endpoints but had no success, found out I get this error only when asking for parameters in the function for example this function worked:
@app.post(/miao)
async def miao(db=Depands(get_db)):
#anything
and this got the same error:
@app.post(/miao)
async def miao(email: str, db=Depands(get_db)):
#anything
I can see that the error is because the required elements for the functions are different from what it has but I don’t understand why, In schemas and main the column asked are the same…