from datetime import date, timedelta, datetime, time from typing import Annotated from pydantic_core import PydanticCustomError from pydantic import BaseModel, EmailStr, field_validator, HttpUrl, StringConstraints from fastapi import Query class SUserLogin(BaseModel): email_or_username: EmailStr | str password: str class SUserRegister(BaseModel): email: EmailStr username: str = Query(None, min_length=2, max_length=30) password: str = Query(None, min_length=8) password2: str = Query(None, min_length=8) date_of_birth: date @field_validator("date_of_birth") # noqa @classmethod def validate_date_of_birth(cls, v): if date.today() - v < timedelta(days=365 * 16): date_of_birth = date.today() - timedelta(days=365 * 16) raise PydanticCustomError( "date_input_error", "date of birth might be earlier than {date_of_birth}", {"date_of_birth": date_of_birth} ) elif datetime.combine(v, time.min).timestamp() < datetime(year=1924, month=1, day=1).timestamp(): date_of_birth = date(1924, 1, 1) raise PydanticCustomError( "date_input_error", "date of birth might be later than {date_of_birth}", {"date_of_birth": date_of_birth} ) return v class SUserResponse(BaseModel): id: int username: str email: EmailStr black_phoenix: bool avatar_image: HttpUrl date_of_birth: date date_of_registration: date class SUsers(BaseModel): users: list[SUserResponse] | None class SUser(BaseModel): id: int email: str username: str hashed_password: str role: int black_phoenix: bool avatar_image: HttpUrl date_of_birth: date date_of_registration: date class SUserSendConfirmationCode(BaseModel): email: EmailStr class SUserChangeData(BaseModel): verification_code: str email: EmailStr username: str = Query(None, min_length=2, max_length=30) new_password: str | None = Query(None, min_length=8) avatar_url: HttpUrl | None class STokenLogin(BaseModel): authorization: str class SUserCode(BaseModel): user_code: str class SCreateInvitationLink(BaseModel): invitation_link: HttpUrl class SUserAvatarUrl(BaseModel): avatar_url: HttpUrl class SUserAvatars(BaseModel): user_avatars: list[SUserAvatarUrl] | None class SUserFilter(BaseModel): username: Annotated[str, StringConstraints(min_length=2, max_length=30)] | None = None email: EmailStr | None = None class SUserPassword(BaseModel): user_password: str = Query(None, min_length=8) class SConfirmationData(BaseModel): user_id: int username: str email_to: EmailStr confirmation_code: str class SInvitationData(BaseModel): chat_id: int class SGetUsersFilter(BaseModel): username: str | None = None @field_validator("username") # noqa @classmethod def validate_username(cls, v): if not v: return "%" else: return f"%{v}%"