[ADD] data_models.py

This commit is contained in:
Evgeny (Krymmy) Momotov 2025-11-11 11:29:58 +03:00
parent a9f5ba24fd
commit e2f7a9925f

View file

@ -0,0 +1,123 @@
import re
from pydantic import BaseModel, Field, validator
from typing import Optional
class User(BaseModel):
id: Optional[int] = Field(description="Идентификатор (автоматический)", default=None)
username: str = Field(max_length=150, description="Пользовательское имя", example="john_doe")
#password: str = Field(max_length=255, description="Пароль", example="secret123")
email: str = Field(max_length=254, default="", description="Электронная почта", example="john@example.com")
first_name: str = Field(max_length=150, default="", description="Имя", example="John")
last_name: str = Field(max_length=150, default="", description="Фамилия", example="Doe")
#is_staff: bool = Field(default=False, description="Статус администратора")
#is_active: bool = Field(default=False, description="Активен")
#is_superuser: bool = Field(default=False, description="Суперпользователь")
#date_joined: str = Field(description="Дата создания", example="2024-01-01T12:00:00")
#last_login: Optional[str] = Field(null=True, default=None, description="Последний вход")
@validator("email")
def validate_email(cls, v):
if v and "@" not in v or "." not in v:
raise ValueError("Некорректный email")
return v
@validator("username")
def validate_username(cls, v):
if len(v) > 150:
raise ValueError("Имя пользователя слишком длинное (максимум 150 символов)")
return v
@validator("first_name")
def validate_first_name(cls, v):
if v and len(v) > 150:
raise ValueError("Имя слишком длинное (максимум 150 символов)")
return v
@validator("last_name")
def validate_last_name(cls, v):
if v and len(v) > 150:
raise ValueError("Фамилия слишком длинная (максимум 150 символов)")
return v
class Config:
extra = "forbid"
from_attributes = True
class SIPAccount(BaseModel):
"""
SIP-аккаунт.
"""
unique_id: str = Field(description="Уникальный идентификатор", example="00000000-0000-0000-0000-000000000000")
id: Optional[int] = Field(description="Идентификатор (автоматический)", default=None)
created_at: Optional[str] = Field(description="Дата создания", example="2024-01-01T12:00:00")
updated_at: Optional[str] = Field(description="Дата обновления", example="2024-01-01T12:00:00")
owner: Optional[User] = Field(description="Владелец")
name: str = Field(max_length=255, description="Название", example="SIP-аккаунт-1")
is_registered: bool = Field(default=False, description="Зарегистрирован")
username: str = Field(max_length=40, description="Имя SIP клиента", example="user123")
password: Optional[str] = Field(max_length=80, null=True, blank=True, description="Пароль (открытый, временно)")
enc_password: Optional[bytes] = Field(null=True, blank=True, description="Зашифрованный пароль")
server_url: str = Field(
max_length=215,
description="URL сервера",
example="https://192.168.1.100:5060"
)
port: Optional[int] = Field(null=True, blank=True, description="Порт", ge=0, le=65535)
internal_number: Optional[str] = Field(max_length=255, null=True, blank=True, description="Внутренний номер")
endpoint_name: Optional[str] = Field(max_length=255, null=True, blank=True, description="Имя конечной точки")
@validator("server_url")
def validate_server_url(cls, v):
if not v:
return v
# Проверяем, содержит ли строка URL (в формате http:// или https://)
if v.startswith("http://") or v.startswith("https://"):
return v
# Проверяем, является ли это IPv4 (простая проверкаDetails)
parts = v.strip().split(':')
if len(parts) == 1:
ip_part = parts[0]
if re.match(r"^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$", ip_part):
# Проверяем, что каждая часть от 0 до 255
ip_parts = [int(x) for x in ip_part.split('.')]
if all(0 <= part <= 255 for part in ip_parts):
return v
raise ValueError("Invalid server URL format (must be http(s):// or IPv4 address)")
@validator("username")
def validate_username(cls, v):
if len(v) > 40:
raise ValueError("Username too long (max 40 characters)")
return v
@validator("name")
def validate_name(cls, v):
if len(v) > 255:
raise ValueError("Name too long (max 255 characters)")
return v
@validator("internal_number")
def validate_internal_number(cls, v):
if v and len(v) > 255:
raise ValueError("Internal number too long (max 255 characters)")
return v
@validator("endpoint_name")
def validate_endpoint_name(cls, v):
if v and len(v) > 255:
raise ValueError("Endpoint name too long (max 255 characters)")
return v
@validator("port")
def validate_port(cls, v):
if v is not None and not (0 <= v <= 65535):
raise ValueError("Port must be between 0 and 65535")
return v
class Config:
extra = "forbid"
from_attributes = True