77
app/api/v1/automations.py
Normal file
77
app/api/v1/automations.py
Normal file
@@ -0,0 +1,77 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from fastapi import APIRouter, HTTPException, Request, Response, status
|
||||
|
||||
from app.automations.models import (
|
||||
AutomationProposal,
|
||||
ProposalDecision,
|
||||
ProposalStatus,
|
||||
)
|
||||
from app.automations.store import AutomationStore
|
||||
|
||||
router = APIRouter(prefix="/v1/automations", tags=["automations"])
|
||||
|
||||
|
||||
@router.post("/proposals", response_model=AutomationProposal, status_code=201)
|
||||
def create_proposal(payload: AutomationProposal, request: Request) -> AutomationProposal:
|
||||
if payload.trigger.above is None and payload.trigger.below is None:
|
||||
raise HTTPException(status_code=422, detail="Trigger benötigt above oder below.")
|
||||
return _store(request).create(payload.model_copy(update={"status": ProposalStatus.DRAFT}))
|
||||
|
||||
|
||||
@router.get("/proposals", response_model=list[AutomationProposal])
|
||||
def list_proposals(request: Request) -> list[AutomationProposal]:
|
||||
return _store(request).list()
|
||||
|
||||
|
||||
@router.post("/proposals/{proposal_id}/approve", response_model=AutomationProposal)
|
||||
def approve(
|
||||
proposal_id: str,
|
||||
payload: ProposalDecision,
|
||||
request: Request,
|
||||
) -> AutomationProposal:
|
||||
return _decide(request, proposal_id, ProposalStatus.APPROVED, payload.expected_revision)
|
||||
|
||||
|
||||
@router.post("/proposals/{proposal_id}/reject", response_model=AutomationProposal)
|
||||
def reject(
|
||||
proposal_id: str,
|
||||
payload: ProposalDecision,
|
||||
request: Request,
|
||||
) -> AutomationProposal:
|
||||
return _decide(request, proposal_id, ProposalStatus.REJECTED, payload.expected_revision)
|
||||
|
||||
|
||||
@router.get("/proposals/{proposal_id}/yaml")
|
||||
def export_yaml(proposal_id: str, request: Request) -> Response:
|
||||
try:
|
||||
content = _store(request).export_yaml(proposal_id)
|
||||
except KeyError as exc:
|
||||
raise HTTPException(status_code=404, detail=str(exc)) from exc
|
||||
except ValueError as exc:
|
||||
raise HTTPException(status_code=409, detail=str(exc)) from exc
|
||||
return Response(content=content, media_type="application/yaml")
|
||||
|
||||
|
||||
def _decide(
|
||||
request: Request,
|
||||
proposal_id: str,
|
||||
decision: ProposalStatus,
|
||||
expected_revision: int,
|
||||
) -> AutomationProposal:
|
||||
try:
|
||||
return _store(request).decide(proposal_id, decision, expected_revision)
|
||||
except KeyError as exc:
|
||||
raise HTTPException(status_code=404, detail=str(exc)) from exc
|
||||
except ValueError as exc:
|
||||
raise HTTPException(status_code=409, detail=str(exc)) from exc
|
||||
|
||||
|
||||
def _store(request: Request) -> AutomationStore:
|
||||
store = getattr(request.app.state, "automation_store", None)
|
||||
if not isinstance(store, AutomationStore):
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_503_SERVICE_UNAVAILABLE,
|
||||
detail="Automation Store nicht initialisiert.",
|
||||
)
|
||||
return store
|
||||
Reference in New Issue
Block a user