66 lines
1.8 KiB
Python
66 lines
1.8 KiB
Python
"""Authentication models for user management with SQLModel support"""
|
|
import uuid
|
|
from pydantic import BaseModel, EmailStr, Field as PydanticField
|
|
from typing import Optional, List
|
|
from datetime import datetime
|
|
from sqlmodel import SQLModel, Field, Relationship
|
|
|
|
|
|
class UserBase(SQLModel):
|
|
"""Base schema for user data"""
|
|
username: str = Field(index=True, unique=True, min_length=3, max_length=50)
|
|
email: Optional[str] = Field(default=None, index=True)
|
|
full_name: Optional[str] = None
|
|
is_active: bool = Field(default=True)
|
|
|
|
|
|
class UserTable(UserBase, table=True):
|
|
"""Database table for users"""
|
|
__tablename__ = "users"
|
|
|
|
id: str = Field(
|
|
default_factory=lambda: str(uuid.uuid4()),
|
|
primary_key=True,
|
|
index=True,
|
|
nullable=False
|
|
)
|
|
hashed_password: str
|
|
created_at: datetime = Field(default_factory=datetime.now)
|
|
last_login: Optional[datetime] = None
|
|
|
|
# Relationships - Using string reference to avoid circular import errors
|
|
watchlist_items: List["WatchlistItemTable"] = Relationship(back_populates="user")
|
|
|
|
|
|
class UserCreate(UserBase):
|
|
"""Schema for user registration"""
|
|
password: str = PydanticField(..., min_length=6)
|
|
email: Optional[EmailStr] = None
|
|
|
|
|
|
class UserLogin(BaseModel):
|
|
"""Schema for user login"""
|
|
username: str
|
|
password: str
|
|
|
|
|
|
class User(UserBase):
|
|
"""Schema for user data (API Response)"""
|
|
id: str
|
|
created_at: datetime
|
|
last_login: Optional[datetime] = None
|
|
|
|
|
|
class Token(BaseModel):
|
|
"""Schema for authentication token"""
|
|
access_token: str
|
|
token_type: str = "bearer"
|
|
|
|
|
|
class UserInDB(User):
|
|
"""Schema for user stored in database (with hashed password)"""
|
|
hashed_password: str
|
|
|
|
# Import WatchlistItemTable here to resolve SQLModel Relationship mappings
|
|
from .watchlist import WatchlistItemTable
|