83 lines
2.6 KiB
Python
83 lines
2.6 KiB
Python
from typing import Annotated, Any
|
|
|
|
import asyncpg
|
|
from dishka.integrations.fastapi import DishkaRoute, FromDishka
|
|
from fastapi import APIRouter, HTTPException, Query
|
|
from pydantic import BaseModel
|
|
|
|
from utils.read import watches
|
|
from utils.read.models import DEFAULT_LIMIT, AlertView, Page, WatchView
|
|
|
|
router = APIRouter(prefix="/api", tags=["watches"], route_class=DishkaRoute)
|
|
|
|
|
|
class WatchCreate(BaseModel):
|
|
account_id: int
|
|
kind: str
|
|
params: dict[str, Any] = {}
|
|
enabled: bool = True
|
|
|
|
|
|
class WatchUpdate(BaseModel):
|
|
params: dict[str, Any] = {}
|
|
enabled: bool = True
|
|
|
|
|
|
@router.get("/watches")
|
|
async def list_watches(
|
|
pool: FromDishka[asyncpg.Pool], account_id: Annotated[int, Query()]
|
|
) -> list[WatchView]:
|
|
return await watches.list_watches(pool, account_id)
|
|
|
|
|
|
@router.post("/watches", status_code=201)
|
|
async def create_watch(pool: FromDishka[asyncpg.Pool], body: WatchCreate) -> WatchView:
|
|
return await watches.create_watch(
|
|
pool, body.account_id, body.kind, body.params, enabled=body.enabled
|
|
)
|
|
|
|
|
|
@router.get("/watches/{watch_id}")
|
|
async def get_watch(pool: FromDishka[asyncpg.Pool], watch_id: int) -> WatchView:
|
|
watch = await watches.get_watch(pool, watch_id)
|
|
if watch is None:
|
|
raise HTTPException(status_code=404, detail="watch not found")
|
|
return watch
|
|
|
|
|
|
@router.put("/watches/{watch_id}")
|
|
async def update_watch(
|
|
pool: FromDishka[asyncpg.Pool], watch_id: int, body: WatchUpdate
|
|
) -> WatchView:
|
|
watch = await watches.update_watch(
|
|
pool, watch_id, body.params, enabled=body.enabled
|
|
)
|
|
if watch is None:
|
|
raise HTTPException(status_code=404, detail="watch not found")
|
|
return watch
|
|
|
|
|
|
@router.delete("/watches/{watch_id}", status_code=204)
|
|
async def delete_watch(pool: FromDishka[asyncpg.Pool], watch_id: int) -> None:
|
|
if not await watches.delete_watch(pool, watch_id):
|
|
raise HTTPException(status_code=404, detail="watch not found")
|
|
|
|
|
|
@router.get("/alerts")
|
|
async def list_alerts(
|
|
pool: FromDishka[asyncpg.Pool],
|
|
account_id: Annotated[int, Query()],
|
|
seen: Annotated[bool | None, Query()] = None,
|
|
limit: Annotated[int, Query()] = DEFAULT_LIMIT,
|
|
offset: Annotated[int, Query()] = 0,
|
|
) -> list[AlertView]:
|
|
return await watches.list_alerts(
|
|
pool, account_id, Page(limit=limit, offset=offset), seen=seen
|
|
)
|
|
|
|
|
|
@router.post("/alerts/{alert_id}/seen", status_code=204)
|
|
async def mark_alert_seen(pool: FromDishka[asyncpg.Pool], alert_id: int) -> None:
|
|
if not await watches.mark_alert_seen(pool, alert_id):
|
|
raise HTTPException(status_code=404, detail="alert not found")
|