from datetime import datetime from typing import Optional from pydantic import BaseModel, EmailStr, Field, validator class UserBase(BaseModel): email: Optional[EmailStr] = None username: Optional[str] = None is_active: Optional[bool] = True is_superuser: Optional[bool] = False class UserCreate(UserBase): email: EmailStr = Field(..., description="User email") username: str = Field(..., min_length=3, max_length=50, description="Username") password: str = Field(..., min_length=8, description="Password") @validator("username") def username_valid(cls, v): # Additional validation for username if not v.isalnum(): raise ValueError("Username must be alphanumeric") return v class UserUpdate(UserBase): password: Optional[str] = Field(None, min_length=8, description="Password") class UserInDBBase(UserBase): id: int created_at: datetime updated_at: datetime model_config = {"from_attributes": True} class User(UserInDBBase): """Return user information without sensitive data""" pass class UserInDB(UserInDBBase): """User model stored in DB, with hashed password""" hashed_password: str class Token(BaseModel): """OAuth2 compatible token""" access_token: str token_type: str class TokenPayload(BaseModel): """JWT token payload""" sub: Optional[int] = None