automations(api): API request/response schemas

This commit is contained in:
CREDO23 2026-05-27 19:10:20 +02:00
parent dd6bc30f98
commit 84d99f19a2
5 changed files with 189 additions and 3 deletions

View file

@ -6,17 +6,18 @@ from typing import Any
from fastapi import APIRouter, Body, Depends from fastapi import APIRouter, Body, Depends
from app.automations.api.schemas import RunDispatched
from app.automations.services import AutomationService, get_automation_service from app.automations.services import AutomationService, get_automation_service
router = APIRouter() router = APIRouter()
@router.post("/automations/{automation_id}/run") @router.post("/automations/{automation_id}/run", response_model=RunDispatched)
async def run_automation_now( async def run_automation_now(
automation_id: int, automation_id: int,
payload: dict[str, Any] | None = Body(default=None), payload: dict[str, Any] | None = Body(default=None),
service: AutomationService = Depends(get_automation_service), service: AutomationService = Depends(get_automation_service),
) -> dict[str, Any]: ) -> RunDispatched:
"""Fire a manual run.""" """Fire a manual run."""
run = await service.run_now(automation_id=automation_id, payload=payload) run = await service.run_now(automation_id=automation_id, payload=payload)
return {"run_id": run.id, "status": run.status.value} return RunDispatched(run_id=run.id, status=run.status)

View file

@ -0,0 +1,28 @@
"""Request/response schemas for the automations HTTP layer."""
from __future__ import annotations
from .automation import (
AutomationCreate,
AutomationDetail,
AutomationList,
AutomationSummary,
AutomationUpdate,
)
from .run import RunDetail, RunDispatched, RunList, RunSummary
from .trigger import TriggerCreate, TriggerDetail, TriggerUpdate
__all__ = [
"AutomationCreate",
"AutomationDetail",
"AutomationList",
"AutomationSummary",
"AutomationUpdate",
"RunDetail",
"RunDispatched",
"RunList",
"RunSummary",
"TriggerCreate",
"TriggerDetail",
"TriggerUpdate",
]

View file

@ -0,0 +1,64 @@
"""Request/response schemas for the ``Automation`` resource."""
from __future__ import annotations
from datetime import datetime
from pydantic import BaseModel, ConfigDict, Field
from app.automations.persistence.enums.automation_status import AutomationStatus
from app.automations.schemas.definition import AutomationDefinition
from .trigger import TriggerCreate, TriggerDetail
class AutomationCreate(BaseModel):
"""Create an automation, optionally with initial triggers (atomic)."""
model_config = ConfigDict(extra="forbid")
search_space_id: int
name: str = Field(..., min_length=1, max_length=200)
description: str | None = None
definition: AutomationDefinition
triggers: list[TriggerCreate] = Field(default_factory=list)
class AutomationUpdate(BaseModel):
"""Partial update of an automation. Triggers are managed separately."""
model_config = ConfigDict(extra="forbid")
name: str | None = Field(default=None, min_length=1, max_length=200)
description: str | None = None
status: AutomationStatus | None = None
definition: AutomationDefinition | None = None
class AutomationSummary(BaseModel):
"""Lightweight automation view for list endpoints."""
model_config = ConfigDict(from_attributes=True)
id: int
search_space_id: int
name: str
description: str | None = None
status: AutomationStatus
version: int
created_at: datetime
updated_at: datetime
class AutomationDetail(AutomationSummary):
"""Full automation view including definition and attached triggers."""
definition: AutomationDefinition
triggers: list[TriggerDetail] = Field(default_factory=list)
class AutomationList(BaseModel):
"""Paginated list of automations."""
items: list[AutomationSummary]
total: int

View file

@ -0,0 +1,50 @@
"""Response schemas for run sub-resources and run dispatch."""
from __future__ import annotations
from datetime import datetime
from typing import Any
from pydantic import BaseModel, ConfigDict
from app.automations.persistence.enums.run_status import RunStatus
class RunSummary(BaseModel):
"""Lightweight run view for list endpoints."""
model_config = ConfigDict(from_attributes=True)
id: int
automation_id: int
trigger_id: int | None = None
status: RunStatus
started_at: datetime | None = None
finished_at: datetime | None = None
created_at: datetime
class RunDetail(RunSummary):
"""Full run view including snapshot, results and artifacts."""
definition_snapshot: dict[str, Any]
trigger_payload: dict[str, Any] | None = None
resolved_inputs: dict[str, Any]
step_results: list[dict[str, Any]]
output: dict[str, Any] | None = None
artifacts: list[dict[str, Any]]
error: dict[str, Any] | None = None
class RunList(BaseModel):
"""Paginated list of runs."""
items: list[RunSummary]
total: int
class RunDispatched(BaseModel):
"""Response of a successful run dispatch."""
run_id: int
status: RunStatus

View file

@ -0,0 +1,43 @@
"""Request/response schemas for trigger sub-resources."""
from __future__ import annotations
from datetime import datetime
from typing import Any
from pydantic import BaseModel, ConfigDict, Field
from app.automations.persistence.enums.trigger_type import TriggerType
class TriggerCreate(BaseModel):
"""Attach a trigger to an automation."""
model_config = ConfigDict(extra="forbid")
type: TriggerType
params: dict[str, Any] = Field(default_factory=dict)
enabled: bool = True
class TriggerUpdate(BaseModel):
"""Partial update of an existing trigger."""
model_config = ConfigDict(extra="forbid")
enabled: bool | None = None
params: dict[str, Any] | None = None
class TriggerDetail(BaseModel):
"""Trigger as returned to clients."""
model_config = ConfigDict(from_attributes=True)
id: int
type: TriggerType
params: dict[str, Any]
enabled: bool
last_fired_at: datetime | None = None
next_fire_at: datetime | None = None
created_at: datetime