FluxIP/app/rotation/router.py

95 lines
2.8 KiB
Python

from __future__ import annotations
import math
from fastapi import APIRouter, Depends, Query, Response, status
from app.auth.repository import SessionRecord
from app.dependencies import get_rotation_service, require_session
from app.rotation.service import RotationService
router = APIRouter(prefix="/api/v1", tags=["rotations"])
@router.post("/instances/{instance_id}/rotations", status_code=status.HTTP_202_ACCEPTED)
async def rotate_instance(
instance_id: str,
response: Response,
_: SessionRecord = Depends(require_session),
service: RotationService = Depends(get_rotation_service),
) -> dict:
run = service.start_instance(instance_id)
response.headers["Location"] = f"/api/v1/rotations/{run.id}"
return {"data": run.to_dict()}
@router.post(
"/instance-groups/{group_id}/rotations",
status_code=status.HTTP_202_ACCEPTED,
)
async def rotate_group(
group_id: str,
response: Response,
_: SessionRecord = Depends(require_session),
service: RotationService = Depends(get_rotation_service),
) -> dict:
run = service.start_group(group_id)
response.headers["Location"] = f"/api/v1/rotations/{run.id}"
return {"data": run.to_dict()}
@router.get("/rotations")
def list_rotations(
page: int = Query(default=1, ge=1),
per_page: int = Query(default=20, ge=1, le=100),
instance_id: str | None = Query(default=None),
group_id: str | None = Query(default=None),
run_status: str | None = Query(default=None, alias="status"),
_: SessionRecord = Depends(require_session),
service: RotationService = Depends(get_rotation_service),
) -> dict:
runs, total = service.list(
page,
per_page,
instance_id=instance_id,
group_id=group_id,
status=run_status,
)
return {
"data": runs,
"summary": service.history_summary(),
"pagination": {
"page": page,
"per_page": per_page,
"total": total,
"total_pages": math.ceil(total / per_page) if total else 0,
},
}
@router.get("/rotations/{run_id}")
def get_rotation(
run_id: str,
_: SessionRecord = Depends(require_session),
service: RotationService = Depends(get_rotation_service),
) -> dict:
return {"data": service.get(run_id)}
@router.post("/rotations/{run_id}/resume", status_code=status.HTTP_202_ACCEPTED)
async def resume_rotation(
run_id: str,
_: SessionRecord = Depends(require_session),
service: RotationService = Depends(get_rotation_service),
) -> dict:
return {"data": service.resume(run_id).to_dict()}
@router.post("/rotations/{run_id}/cancel")
def cancel_rotation(
run_id: str,
_: SessionRecord = Depends(require_session),
service: RotationService = Depends(get_rotation_service),
) -> dict:
return {"data": service.cancel(run_id).to_dict()}