user.py
1 """User-related schemas.""" 2 from datetime import datetime 3 from typing import Optional 4 5 from pydantic import BaseModel, EmailStr, Field, validator 6 7 8 # Shared properties 9 class UserBase(BaseModel): 10 """Base user schema with common fields.""" 11 email: Optional[EmailStr] = None 12 is_active: Optional[bool] = True 13 full_name: Optional[str] = None 14 is_superuser: bool = False 15 16 17 # Properties to receive via API on creation 18 class UserCreate(UserBase): 19 """Schema for creating a new user.""" 20 email: EmailStr 21 password: str = Field(..., min_length=8, max_length=100) 22 full_name: str = Field(..., min_length=2, max_length=100) 23 24 @validator('password') 25 def password_strength(cls, v): 26 """Validate password strength.""" 27 if len(v) < 8: 28 raise ValueError('Password must be at least 8 characters long') 29 if not any(c.isupper() for c in v): 30 raise ValueError('Password must contain at least one uppercase letter') 31 if not any(c.islower() for c in v): 32 raise ValueError('Password must contain at least one lowercase letter') 33 if not any(c.isdigit() for c in v): 34 raise ValueError('Password must contain at least one number') 35 return v 36 37 38 # Properties to receive via API on update 39 class UserUpdate(UserBase): 40 """Schema for updating a user.""" 41 password: Optional[str] = Field(None, min_length=8, max_length=100) 42 email: Optional[EmailStr] = None 43 44 45 class UserInDBBase(UserBase): 46 """Base schema for user stored in DB.""" 47 id: Optional[int] = None 48 created_at: Optional[datetime] = None 49 updated_at: Optional[datetime] = None 50 51 class Config: 52 """Pydantic config.""" 53 orm_mode = True 54 55 56 # Additional properties to return via API 57 class User(UserInDBBase): 58 """User schema for API responses.""" 59 pass 60 61 62 # Additional properties stored in DB 63 class UserInDB(UserInDBBase): 64 """User schema for data stored in the database.""" 65 hashed_password: str 66 67 68 class UserLogin(BaseModel): 69 """Schema for user login.""" 70 email: EmailStr 71 password: str = Field(..., min_length=8) 72 73 74 class UserRegister(UserCreate): 75 """Schema for user registration.""" 76 password_confirm: str 77 78 @validator('password_confirm') 79 def passwords_match(cls, v, values, **kwargs): 80 """Validate that passwords match.""" 81 if 'password' in values and v != values['password']: 82 raise ValueError('passwords do not match') 83 return v