Compare commits

..

No commits in common. "8889e964b37bb8ddcee1ab14cc5b19ae8268cbc7" and "179cc1fe32a1545c8cb97234111953b7d3e54778" have entirely different histories.

2 changed files with 56 additions and 15 deletions

View file

@ -27,7 +27,6 @@ class CallerManagerClient:
headers = kwargs.get('headers', {}) headers = kwargs.get('headers', {})
if self.token: if self.token:
headers['Authorization'] = f'Bearer {self.token}' headers['Authorization'] = f'Bearer {self.token}'
kwargs['headers'] = headers
async with aiohttp.ClientSession() as session: async with aiohttp.ClientSession() as session:
async with session.request(method, f"{self.base_url}{endpoint}", **kwargs) as response: async with session.request(method, f"{self.base_url}{endpoint}", **kwargs) as response:
if response.status >= 400: if response.status >= 400:

View file

@ -29,17 +29,41 @@ class User(BaseModel):
id: Optional[int] = Field(description="Идентификатор (автоматический)", default=None) id: Optional[int] = Field(description="Идентификатор (автоматический)", default=None)
username: str = Field(max_length=150, description="Пользовательское имя", example="john_doe") username: str = Field(max_length=150, description="Пользовательское имя", example="john_doe")
#password: str = Field(max_length=255, description="Пароль", example="secret123") #password: str = Field(max_length=255, description="Пароль", example="secret123")
email: Optional[str] = Field(max_length=254, default="", description="Электронная почта", example="john@example.com") email: str = Field(max_length=254, default="", description="Электронная почта", example="john@example.com")
first_name: Optional[str] = Field(max_length=150, default="", description="Имя", example="John") first_name: str = Field(max_length=150, default="", description="Имя", example="John")
last_name: Optional[str] = Field(max_length=150, default="", description="Фамилия", example="Doe") last_name: str = Field(max_length=150, default="", description="Фамилия", example="Doe")
#is_staff: bool = Field(default=False, description="Статус администратора") #is_staff: bool = Field(default=False, description="Статус администратора")
#is_active: bool = Field(default=False, description="Активен") #is_active: bool = Field(default=False, description="Активен")
#is_superuser: bool = Field(default=False, description="Суперпользователь") #is_superuser: bool = Field(default=False, description="Суперпользователь")
#date_joined: str = Field(description="Дата создания", example="2024-01-01T12:00:00") #date_joined: str = Field(description="Дата создания", example="2024-01-01T12:00:00")
#last_login: Optional[str] = Field(null=True, default=None, description="Последний вход") #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: class Config:
extra = "ignore" extra = "forbid"
from_attributes = True from_attributes = True
@ -68,6 +92,24 @@ class SIPAccount(BaseModel):
internal_number: Optional[str] = Field(max_length=255, null=True, blank=True, description="Внутренний номер") 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="Имя конечной точки") 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") @validator("username")
def validate_username(cls, v): def validate_username(cls, v):
if len(v) > 40: if len(v) > 40:
@ -99,7 +141,7 @@ class SIPAccount(BaseModel):
return v return v
class Config: class Config:
extra = "ignore" extra = "forbid"
from_attributes = True from_attributes = True
class CallPrompt(BaseModel): class CallPrompt(BaseModel):
@ -113,7 +155,7 @@ class CallPrompt(BaseModel):
updated_at: Optional[str] = Field(description="Дата обновления", example="2024-01-01T12:00:00") updated_at: Optional[str] = Field(description="Дата обновления", example="2024-01-01T12:00:00")
class Config: class Config:
extra = "ignore" extra = "forbid"
from_attributes = True from_attributes = True
@ -150,7 +192,7 @@ class YandexFleet(BaseModel):
updated_at: Optional[str] = Field(description="Дата обновления", example="2024-01-01T12:00:00") updated_at: Optional[str] = Field(description="Дата обновления", example="2024-01-01T12:00:00")
class Config: class Config:
extra = "ignore" extra = "forbid"
from_attributes = True from_attributes = True
@ -162,7 +204,7 @@ class Driver(BaseModel):
updated_at: Optional[str] = Field(description="Дата обновления", example="2024-01-01T12:00:00") updated_at: Optional[str] = Field(description="Дата обновления", example="2024-01-01T12:00:00")
class Config: class Config:
extra = "ignore" extra = "forbid"
from_attributes = True from_attributes = True
@ -181,7 +223,7 @@ class Call(BaseModel):
updated_at: Optional[str] = Field(description="Дата обновления", example="2024-01-01T12:00:00") updated_at: Optional[str] = Field(description="Дата обновления", example="2024-01-01T12:00:00")
class Config: class Config:
extra = "ignore" extra = "forbid"
from_attributes = True from_attributes = True
@ -197,7 +239,7 @@ class CallIn(BaseModel):
audio_file: Optional[str] = Field(description="Путь к аудио", example="/audio/call-123.mp3", null=True) audio_file: Optional[str] = Field(description="Путь к аудио", example="/audio/call-123.mp3", null=True)
class Config: class Config:
extra = "ignore" extra = "forbid"
from_attributes = True from_attributes = True
@ -212,7 +254,7 @@ class CallDialog(BaseModel):
updated_at: Optional[str] = Field(description="Дата обновления", example="2024-01-01T12:00:00") updated_at: Optional[str] = Field(description="Дата обновления", example="2024-01-01T12:00:00")
class Config: class Config:
extra = "ignore" extra = "forbid"
from_attributes = True from_attributes = True
class CallDialogIn(BaseModel): class CallDialogIn(BaseModel):
@ -223,7 +265,7 @@ class CallDialogIn(BaseModel):
call_time: Optional[int] = Field(default=0, description="Время звонка (в секундах)", ge=0) call_time: Optional[int] = Field(default=0, description="Время звонка (в секундах)", ge=0)
class Config: class Config:
extra = "ignore" extra = "forbid"
from_attributes = True from_attributes = True
@ -234,7 +276,7 @@ class CallDialogPart(BaseModel):
call_time: int = Field(default=0, description="Время звонка (в секундах)", ge=0) call_time: int = Field(default=0, description="Время звонка (в секундах)", ge=0)
class Config: class Config:
extra = "ignore" extra = "forbid"
from_attributes = True from_attributes = True
class CallDialogPartIn(BaseModel): class CallDialogPartIn(BaseModel):
@ -244,5 +286,5 @@ class CallDialogPartIn(BaseModel):
call_time: Optional[int] = Field(default=0, description="Время звонка (в секундах)", ge=0) call_time: Optional[int] = Field(default=0, description="Время звонка (в секундах)", ge=0)
class Config: class Config:
extra = "ignore" extra = "forbid"
from_attributes = True from_attributes = True