50 lines
1.7 KiB
Python
50 lines
1.7 KiB
Python
from fastapi import APIRouter, Depends, HTTPException, Query
|
|
from sqlalchemy import select
|
|
from sqlalchemy.ext.asyncio import AsyncSession
|
|
|
|
from ..cursors import decode, encode
|
|
from ..db import get_session
|
|
from ..models import Agent as AgentModel
|
|
from ..schemas import Agent, AgentsPage
|
|
from ..timeutil import to_utc
|
|
|
|
router = APIRouter()
|
|
|
|
|
|
def _to_schema(a: AgentModel) -> Agent:
|
|
return Agent(
|
|
agent_id=a.agent_id,
|
|
hostname=a.hostname,
|
|
status=a.status,
|
|
last_seen_at=to_utc(a.last_seen_at),
|
|
features=a.features or {"push": False, "metrics": False},
|
|
labels=a.labels or {},
|
|
)
|
|
|
|
|
|
@router.get("/agents", response_model=AgentsPage)
|
|
async def list_agents(
|
|
cursor: str | None = Query(default=None, max_length=512),
|
|
limit: int = Query(default=100, ge=1, le=500),
|
|
session: AsyncSession = Depends(get_session),
|
|
) -> AgentsPage:
|
|
stmt = select(AgentModel).order_by(AgentModel.agent_id)
|
|
if cursor is not None:
|
|
(last_id,) = decode(cursor, 1)
|
|
stmt = stmt.where(AgentModel.agent_id > last_id)
|
|
rows = (await session.execute(stmt.limit(limit + 1))).scalars().all()
|
|
next_cursor = None
|
|
if len(rows) > limit:
|
|
rows = rows[:limit]
|
|
next_cursor = encode(rows[-1].agent_id)
|
|
return AgentsPage(items=[_to_schema(a) for a in rows], next_cursor=next_cursor)
|
|
|
|
|
|
@router.get("/agents/{agent_id}", response_model=Agent)
|
|
async def get_agent(agent_id: str, session: AsyncSession = Depends(get_session)) -> Agent:
|
|
res = await session.execute(select(AgentModel).where(AgentModel.agent_id == agent_id))
|
|
a = res.scalar_one_or_none()
|
|
if a is None:
|
|
raise HTTPException(status_code=404, detail="agent not found")
|
|
return _to_schema(a)
|