97 lines
3.0 KiB
Python
97 lines
3.0 KiB
Python
from __future__ import annotations
|
|
|
|
from datetime import datetime, time
|
|
from typing import Self
|
|
from uuid import UUID
|
|
from zoneinfo import ZoneInfo, ZoneInfoNotFoundError
|
|
|
|
from pydantic import BaseModel, ConfigDict, Field, field_validator
|
|
|
|
from models.automation_jobs import AutomationJob as OrmAutomationJob
|
|
from models.automation_jobs import AutomationJobStatus, ScheduleType
|
|
from schemas.automation import AutomationJobConfig
|
|
|
|
|
|
class AutomationJobResponse(BaseModel):
|
|
model_config = ConfigDict(extra="forbid")
|
|
|
|
id: UUID
|
|
owner_id: UUID
|
|
bootstrap_key: str | None = None
|
|
title: str
|
|
schedule_type: ScheduleType
|
|
run_at: time
|
|
timezone: str
|
|
status: AutomationJobStatus
|
|
is_system: bool
|
|
config: AutomationJobConfig
|
|
next_run_at: datetime
|
|
last_run_at: datetime | None = None
|
|
created_at: datetime
|
|
updated_at: datetime
|
|
|
|
@classmethod
|
|
def from_orm(cls, obj: OrmAutomationJob) -> Self:
|
|
return cls(
|
|
id=obj.id,
|
|
owner_id=obj.owner_id,
|
|
bootstrap_key=obj.bootstrap_key,
|
|
title=obj.title,
|
|
schedule_type=obj.schedule_type,
|
|
run_at=obj.run_at.time(),
|
|
timezone=obj.timezone,
|
|
status=obj.status,
|
|
is_system=obj.bootstrap_key is not None,
|
|
config=AutomationJobConfig.model_validate(obj.config or {}),
|
|
next_run_at=obj.next_run_at,
|
|
last_run_at=obj.last_run_at,
|
|
created_at=obj.created_at,
|
|
updated_at=obj.updated_at,
|
|
)
|
|
|
|
|
|
class AutomationJobCreateRequest(BaseModel):
|
|
model_config = ConfigDict(extra="forbid")
|
|
|
|
title: str = Field(..., min_length=1, max_length=255)
|
|
schedule_type: ScheduleType
|
|
run_at: time = Field(..., description="Local time in HH:MM:SS format")
|
|
timezone: str = Field(..., min_length=1, max_length=50)
|
|
status: AutomationJobStatus = Field(default=AutomationJobStatus.ACTIVE)
|
|
config: AutomationJobConfig
|
|
|
|
@field_validator("timezone")
|
|
@classmethod
|
|
def validate_timezone(cls, value: str) -> str:
|
|
try:
|
|
ZoneInfo(value)
|
|
except ZoneInfoNotFoundError as exc:
|
|
raise ValueError("timezone must be a valid IANA timezone") from exc
|
|
return value
|
|
|
|
|
|
class AutomationJobUpdateRequest(BaseModel):
|
|
model_config = ConfigDict(extra="forbid")
|
|
|
|
title: str | None = Field(None, min_length=1, max_length=255)
|
|
schedule_type: ScheduleType | None = None
|
|
run_at: time | None = None
|
|
timezone: str | None = Field(None, min_length=1, max_length=50)
|
|
status: AutomationJobStatus | None = None
|
|
config: AutomationJobConfig | None = None
|
|
|
|
@field_validator("timezone")
|
|
@classmethod
|
|
def validate_timezone(cls, value: str | None) -> str | None:
|
|
if value is None:
|
|
return value
|
|
try:
|
|
ZoneInfo(value)
|
|
except ZoneInfoNotFoundError as exc:
|
|
raise ValueError("timezone must be a valid IANA timezone") from exc
|
|
return value
|
|
|
|
|
|
class AutomationJobListResponse(BaseModel):
|
|
items: list[AutomationJobResponse]
|