schemas.py 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. from pydantic import BaseModel, field_validator
  2. from typing import Optional, List, Any
  3. from datetime import datetime
  4. from apscheduler.triggers.cron import CronTrigger
  5. # Auth
  6. class Token(BaseModel):
  7. access_token: str
  8. token_type: str
  9. is_superuser: bool = False
  10. username: str = ""
  11. class TokenData(BaseModel):
  12. username: Optional[str] = None
  13. class SimpleAuthCallback(BaseModel):
  14. ticket: str
  15. # User
  16. class UserBase(BaseModel):
  17. username: str
  18. is_active: Optional[bool] = True
  19. is_superuser: Optional[bool] = False
  20. class UserCreate(UserBase):
  21. password: str
  22. class UserUpdate(BaseModel):
  23. password: Optional[str] = None
  24. is_active: Optional[bool] = None
  25. is_superuser: Optional[bool] = None
  26. class User(UserBase):
  27. id: int
  28. class Config:
  29. from_attributes = True
  30. class UserLogin(BaseModel):
  31. username: str
  32. password: str
  33. # Camera
  34. class CameraBase(BaseModel):
  35. name: str
  36. stream_url: str
  37. class CameraCreate(CameraBase):
  38. pass
  39. class CameraUpdate(CameraBase):
  40. pass
  41. class CameraTest(BaseModel):
  42. stream_url: str
  43. class Camera(CameraBase):
  44. id: int
  45. status: int
  46. created_at: datetime
  47. class Config:
  48. from_attributes = True
  49. # Model Config
  50. class ModelConfigBase(BaseModel):
  51. name: str
  52. base_url: str
  53. api_key: str
  54. model_name: str
  55. class ModelConfigCreate(ModelConfigBase):
  56. pass
  57. class ModelConfig(ModelConfigBase):
  58. id: int
  59. class Config:
  60. from_attributes = True
  61. # Task
  62. def validate_cron_helper(v: str) -> str:
  63. # 1. Try standard 5-field cron
  64. try:
  65. CronTrigger.from_crontab(v)
  66. return v
  67. except ValueError:
  68. pass
  69. # 2. Try 6-field cron (second minute hour day month day_of_week)
  70. try:
  71. parts = v.split()
  72. if len(parts) == 6:
  73. CronTrigger(
  74. second=parts[0],
  75. minute=parts[1],
  76. hour=parts[2],
  77. day=parts[3],
  78. month=parts[4],
  79. day_of_week=parts[5]
  80. )
  81. return v
  82. except Exception:
  83. pass
  84. raise ValueError("Invalid cron expression. Expected 5 fields (standard) or 6 fields (with seconds).")
  85. class TaskRule(BaseModel):
  86. name: str
  87. prompt: str
  88. class TaskBase(BaseModel):
  89. name: str
  90. model_config_id: int
  91. camera_ids: List[int]
  92. rules: List[TaskRule]
  93. cron_expression: str
  94. class TaskCreate(TaskBase):
  95. @field_validator('cron_expression')
  96. @classmethod
  97. def validate_cron(cls, v: str) -> str:
  98. return validate_cron_helper(v)
  99. class TaskUpdate(TaskBase):
  100. @field_validator('cron_expression')
  101. @classmethod
  102. def validate_cron(cls, v: str) -> str:
  103. return validate_cron_helper(v)
  104. class TaskTest(BaseModel):
  105. model_config_id: int
  106. camera_ids: List[int]
  107. rules: List[TaskRule]
  108. class Task(TaskBase):
  109. id: int
  110. is_running: bool
  111. class Config:
  112. from_attributes = True
  113. class TaskToggle(BaseModel):
  114. running: bool
  115. # Log
  116. class TaskLogBase(BaseModel):
  117. task_id: int
  118. camera_id: int
  119. snapshot_path: str
  120. alarm_name: Optional[str] = None
  121. alarm_content: Optional[str] = None
  122. area: Optional[str] = None
  123. is_alarm: bool
  124. class TaskLog(TaskLogBase):
  125. id: int
  126. check_time: datetime
  127. class Config:
  128. from_attributes = True
  129. # Duty Report
  130. class DutyReportBase(BaseModel):
  131. reporter_name: Optional[str] = None
  132. start_time: datetime
  133. end_time: datetime
  134. class DutyReportCreate(DutyReportBase):
  135. pass
  136. class DutyReport(DutyReportBase):
  137. id: int
  138. status: str
  139. file_path: Optional[str] = None
  140. created_at: datetime
  141. class Config:
  142. from_attributes = True