from __future__ import annotations from typing import Annotated from fastapi import APIRouter, Depends, Header, HTTPException, Query, status from sqlalchemy.orm import Session from app.api.deps import get_db from app.schemas.agent_asset import ( AgentAssetCreate, AgentAssetListItem, AgentAssetRead, AgentAssetReviewCreate, AgentAssetReviewRead, AgentAssetUpdate, AgentAssetVersionCreate, AgentAssetVersionRead, ) from app.services.agent_assets import AgentAssetService router = APIRouter(prefix="/agent-assets") DbSession = Annotated[Session, Depends(get_db)] def _handle_asset_error(exc: Exception) -> None: if isinstance(exc, LookupError): raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=str(exc)) from exc if isinstance(exc, PermissionError): raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(exc)) from exc if isinstance(exc, ValueError): raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(exc)) from exc raise exc @router.get("", response_model=list[AgentAssetListItem]) def list_agent_assets( db: DbSession, asset_type: str | None = Query(default=None), status_value: str | None = Query(default=None, alias="status"), domain: str | None = Query(default=None), keyword: str | None = Query(default=None), ) -> list[AgentAssetListItem]: return AgentAssetService(db).list_assets( asset_type=asset_type, status=status_value, domain=domain, keyword=keyword, ) @router.get("/{asset_id}", response_model=AgentAssetRead) def get_agent_asset(asset_id: str, db: DbSession) -> AgentAssetRead: asset = AgentAssetService(db).get_asset(asset_id) if asset is None: raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Asset not found") return asset @router.post("", response_model=AgentAssetRead, status_code=status.HTTP_201_CREATED) def create_agent_asset( payload: AgentAssetCreate, db: DbSession, x_actor: Annotated[str | None, Header()] = None, x_request_id: Annotated[str | None, Header()] = None, ) -> AgentAssetRead: try: return AgentAssetService(db).create_asset( payload, actor=(x_actor or payload.owner).strip() or "system", request_id=x_request_id, ) except Exception as exc: _handle_asset_error(exc) @router.patch("/{asset_id}", response_model=AgentAssetRead) def update_agent_asset( asset_id: str, payload: AgentAssetUpdate, db: DbSession, x_actor: Annotated[str | None, Header()] = None, x_request_id: Annotated[str | None, Header()] = None, ) -> AgentAssetRead: try: return AgentAssetService(db).update_asset( asset_id, payload, actor=(x_actor or "system").strip() or "system", request_id=x_request_id, ) except Exception as exc: _handle_asset_error(exc) @router.get("/{asset_id}/versions", response_model=list[AgentAssetVersionRead]) def list_agent_asset_versions( asset_id: str, db: DbSession, limit: int = Query(default=20, ge=1, le=100) ) -> list[AgentAssetVersionRead]: try: return AgentAssetService(db).list_versions(asset_id, limit=limit) except Exception as exc: _handle_asset_error(exc) @router.post( "/{asset_id}/versions", response_model=AgentAssetVersionRead, status_code=status.HTTP_201_CREATED, ) def create_agent_asset_version( asset_id: str, payload: AgentAssetVersionCreate, db: DbSession, x_actor: Annotated[str | None, Header()] = None, x_request_id: Annotated[str | None, Header()] = None, ) -> AgentAssetVersionRead: try: return AgentAssetService(db).create_version( asset_id, payload, actor=(x_actor or payload.created_by).strip() or "system", request_id=x_request_id, ) except Exception as exc: _handle_asset_error(exc) @router.post( "/{asset_id}/reviews", response_model=AgentAssetReviewRead, status_code=status.HTTP_201_CREATED ) def create_agent_asset_review( asset_id: str, payload: AgentAssetReviewCreate, db: DbSession, x_actor: Annotated[str | None, Header()] = None, x_request_id: Annotated[str | None, Header()] = None, ) -> AgentAssetReviewRead: try: return AgentAssetService(db).create_review( asset_id, payload, actor=(x_actor or payload.reviewer).strip() or "system", request_id=x_request_id, ) except Exception as exc: _handle_asset_error(exc) @router.post("/{asset_id}/activate", response_model=AgentAssetRead) def activate_agent_asset( asset_id: str, db: DbSession, x_actor: Annotated[str | None, Header()] = None, x_request_id: Annotated[str | None, Header()] = None, ) -> AgentAssetRead: try: return AgentAssetService(db).activate_asset( asset_id, actor=(x_actor or "system").strip() or "system", request_id=x_request_id, ) except Exception as exc: _handle_asset_error(exc)