highlight.py 4.22 KiB
from typing import TYPE_CHECKING
from fastapi import APIRouter, Depends
from sqlalchemy import select
from sqlalchemy import func as F
from server.data import db_engine
from server.api.errors import \
NoDataForKeyError, \
DataNotFoundWarning
from server.util.security import \
UserPermissionChecker, \
InsufficientPermissions
from nacsos_data.util.auth import UserPermissions
from nacsos_data.db.schemas.annotations import AssignmentScope
from nacsos_data.db.schemas.highlight import Highlighter
from nacsos_data.models.highlight import HighlighterModel
if TYPE_CHECKING:
from sqlalchemy.ext.asyncio import AsyncSession # noqa F401
router = APIRouter()
@router.get('/scope/{assignment_scope_id}', response_model=list[HighlighterModel] | None)
async def get_scope_highlighters(assignment_scope_id: str,
permissions: UserPermissions = Depends(UserPermissionChecker('annotations_read'))) \
-> list[HighlighterModel]:
async with db_engine.session() as session: # type: AsyncSession
highlighter_ids = select(F.unnest(AssignmentScope.highlighter_ids).label('highlighter_id')) \
.where(AssignmentScope.assignment_scope_id == assignment_scope_id) \
.subquery()
stmt = select(Highlighter) \
.join(highlighter_ids, highlighter_ids.c.highlighter_id == Highlighter.highlighter_id) \
.where(Highlighter.project_id == permissions.permissions.project_id)
result = (await session.scalars(stmt)).all()
if result is not None and len(result) > 0:
return [HighlighterModel.model_validate(r.__dict__) for r in result]
raise DataNotFoundWarning(f'No highlighter in project {permissions.permissions.project_id} '
f'for scope with id {assignment_scope_id}!')
@router.get('/project', response_model=list[HighlighterModel])
async def get_project_highlighters(permissions: UserPermissions = Depends(UserPermissionChecker('annotations_read'))) \
-> list[HighlighterModel]:
async with db_engine.session() as session: # type: AsyncSession
stmt = select(Highlighter).where(Highlighter.project_id == permissions.permissions.project_id)
results = (await session.scalars(stmt)).all()
return [HighlighterModel.model_validate(r.__dict__) for r in results]
@router.put('/project', response_model=str)
async def upsert_highlighter(highlighter: HighlighterModel,
permissions: UserPermissions = Depends(UserPermissionChecker('annotations_edit'))) \
-> str:
if str(permissions.permissions.project_id) != str(highlighter.project_id):
raise InsufficientPermissions('Project IDs don\'t match!')
async with db_engine.session() as session: # type: AsyncSession
stmt = select(Highlighter).where(Highlighter.project_id == permissions.permissions.project_id,
Highlighter.highlighter_id == highlighter.highlighter_id)
result: Highlighter | None = (await session.scalars(stmt)).one_or_none()
if result is not None:
result.name = highlighter.name
result.style = highlighter.style
result.keywords = highlighter.keywords
else:
new_highlighter = Highlighter(**highlighter.model_dump())
session.add(new_highlighter)
await session.commit()
return str(highlighter.highlighter_id)
@router.get('/{highlighter_id}', response_model=HighlighterModel | None)
async def get_highlighter(highlighter_id: str,
permissions: UserPermissions = Depends(UserPermissionChecker('annotations_read'))) \
-> HighlighterModel:
async with db_engine.session() as session: # type: AsyncSession
stmt = select(Highlighter).where(Highlighter.project_id == permissions.permissions.project_id,
Highlighter.highlighter_id == highlighter_id)
result = (await session.scalars(stmt)).one_or_none()
if result is not None:
return HighlighterModel.model_validate(result.__dict__)
raise NoDataForKeyError(f'No highlighter in project {permissions.permissions.project_id} '
f'with id {highlighter_id}!')