"""Template (Ontology) CRUD endpoints.""" import logging from typing import List from fastapi import APIRouter, Depends, HTTPException, status from sqlalchemy.orm import Session from database import get_db from models import Template from schemas import TemplateCreate, TemplateOut, TemplateUpdate logger = logging.getLogger(__name__) router = APIRouter(prefix="/api/templates", tags=["Templates"]) @router.post( "", response_model=TemplateOut, status_code=status.HTTP_201_CREATED, summary="Create a new template", ) def create_template(payload: TemplateCreate, db: Session = Depends(get_db)) -> Template: """Create a new ontology template / segmentation class.""" template = Template(**payload.model_dump()) db.add(template) db.commit() db.refresh(template) logger.info("Created template id=%s name=%s", template.id, template.name) return template @router.get( "", response_model=List[TemplateOut], summary="List all templates", ) def list_templates( skip: int = 0, limit: int = 100, db: Session = Depends(get_db), ) -> List[Template]: """Retrieve all ontology templates.""" return db.query(Template).offset(skip).limit(limit).all() @router.get( "/{template_id}", response_model=TemplateOut, summary="Get a single template", ) def get_template(template_id: int, db: Session = Depends(get_db)) -> Template: """Retrieve a template by its ID.""" template = db.query(Template).filter(Template.id == template_id).first() if not template: raise HTTPException(status_code=404, detail="Template not found") return template @router.patch( "/{template_id}", response_model=TemplateOut, summary="Update a template", ) def update_template( template_id: int, payload: TemplateUpdate, db: Session = Depends(get_db), ) -> Template: """Update template fields partially.""" template = db.query(Template).filter(Template.id == template_id).first() if not template: raise HTTPException(status_code=404, detail="Template not found") for key, value in payload.model_dump(exclude_unset=True).items(): setattr(template, key, value) db.commit() db.refresh(template) logger.info("Updated template id=%s", template_id) return template @router.delete( "/{template_id}", status_code=status.HTTP_204_NO_CONTENT, summary="Delete a template", ) def delete_template(template_id: int, db: Session = Depends(get_db)) -> None: """Delete a template. Associated annotations will have template_id set to NULL.""" template = db.query(Template).filter(Template.id == template_id).first() if not template: raise HTTPException(status_code=404, detail="Template not found") db.delete(template) db.commit() logger.info("Deleted template id=%s", template_id)