Skip to content
Snippets Groups Projects
Commit 958bec80 authored by Tim Repke's avatar Tim Repke
Browse files

add quality endpoints

parent 00d01b7e
No related branches found
No related tags found
1 merge request!64add quality endpoints
Pipeline #2261 passed
flake8==6.1.0 flake8==6.1.0
tox==4.6.4 tox==4.11.3
pytest==7.4.2 pytest==7.4.3
pytest-cov==4.1.0 pytest-cov==4.1.0
mypy==1.5.1 mypy==1.6.1
types-toml==0.10.8.7 types-toml==0.10.8.7
types-PyYAML==6.0.12.11 types-PyYAML==6.0.12.12
\ No newline at end of file \ No newline at end of file
...@@ -3,17 +3,20 @@ from typing import Literal ...@@ -3,17 +3,20 @@ from typing import Literal
from fastapi import APIRouter, BackgroundTasks, Depends from fastapi import APIRouter, BackgroundTasks, Depends
from nacsos_data.db.crud import upsert_orm from nacsos_data.db.crud import upsert_orm
from nacsos_data.db.schemas import AnnotationTracker, AssignmentScope, AnnotationScheme, BotAnnotationMetaData from nacsos_data.db.schemas import AnnotationTracker, AssignmentScope, AnnotationScheme, BotAnnotationMetaData, \
AnnotationQuality
from nacsos_data.models.annotation_quality import AnnotationQualityModel
from nacsos_data.models.annotation_tracker import AnnotationTrackerModel, DehydratedAnnotationTracker from nacsos_data.models.annotation_tracker import AnnotationTrackerModel, DehydratedAnnotationTracker
from nacsos_data.util.annotations.evaluation import get_new_label_batches from nacsos_data.util.annotations.evaluation import get_new_label_batches
from nacsos_data.util.annotations.evaluation.buscar import ( from nacsos_data.util.annotations.evaluation.buscar import (
calculate_h0s_for_batches, calculate_h0s_for_batches,
compute_recall, compute_recall,
calculate_h0s) calculate_h0s)
from nacsos_data.util.annotations.evaluation.irr import compute_irr_scores
from nacsos_data.util.annotations.label_transform import annotations_to_sequence, get_annotations from nacsos_data.util.annotations.label_transform import annotations_to_sequence, get_annotations
from nacsos_data.util.auth import UserPermissions from nacsos_data.util.auth import UserPermissions
from pydantic import BaseModel from pydantic import BaseModel
from sqlalchemy import select, String, literal from sqlalchemy import select, String, literal, delete
from server.data import db_engine from server.data import db_engine
from server.api.errors import DataNotFoundWarning from server.api.errors import DataNotFoundWarning
...@@ -172,3 +175,36 @@ async def bg_populate_tracker(tracker_id: str, batch_size: int | None = None, la ...@@ -172,3 +175,36 @@ async def bg_populate_tracker(tracker_id: str, batch_size: int | None = None, la
tracker.buscar = tracker.buscar + [(x, y)] tracker.buscar = tracker.buscar + [(x, y)]
# save after each step, so the user can refresh the page and get data as it becomes available # save after each step, so the user can refresh the page and get data as it becomes available
await session.flush() await session.flush()
@router.get('/quality/load/{assignment_scope_id}', response_model=list[AnnotationQualityModel])
async def get_irr(assignment_scope_id: str,
permissions: UserPermissions = Depends(UserPermissionChecker('annotations_read'))) \
-> list[AnnotationQualityModel]:
async with db_engine.session() as session: # type: AsyncSession
results = (
await session.execute(select(AnnotationQuality)
.where(AnnotationQuality.assignment_scope_id == assignment_scope_id))
).scalars().all()
return [AnnotationQualityModel(**r.__dict__) for r in results]
@router.get('/quality/compute/{assignment_scope_id}', response_model=list[AnnotationQualityModel])
async def recompute_irr(assignment_scope_id: str,
permissions: UserPermissions = Depends(UserPermissionChecker('annotations_read'))) \
-> list[AnnotationQualityModel]:
async with db_engine.session() as session: # type: AsyncSession
# Delete existing metrics
await session.execute(delete(AnnotationQuality)
.where(AnnotationQuality.assignment_scope_id == assignment_scope_id))
# Compute new metrics
metrics = await compute_irr_scores(session=session,
assignment_scope_id=assignment_scope_id,
project_id=permissions.permissions.project_id)
metrics_orm = [AnnotationQuality(**metric.model_dump()) for metric in metrics]
session.add_all(metrics_orm)
await session.commit()
return await get_irr(assignment_scope_id, permissions)
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
from fastapi import APIRouter, Depends, Query from fastapi import APIRouter, Depends, Query
from sqlalchemy import select, asc
from nacsos_data.models.users import UserModel, UserInDBModel, UserBaseModel
from nacsos_data.util.auth import UserPermissions from nacsos_data.util.auth import UserPermissions
from nacsos_data.db.schemas import User from nacsos_data.models.users import UserModel, UserInDBModel, UserBaseModel
from nacsos_data.db.crud.users import \ from nacsos_data.db.schemas import User, AssignmentScope, AnnotationScheme, Assignment
read_users, \ from nacsos_data.db.crud.users import (
read_user_by_id, \ read_users,
read_users_by_ids, \ read_user_by_id,
create_or_update_user, get_password_hash read_users_by_ids,
from sqlalchemy import select create_or_update_user,
get_password_hash
)
from server.data import db_engine from server.data import db_engine
from server.api.errors import DataNotFoundWarning, UserNotFoundError, UserPermissionError from server.api.errors import DataNotFoundWarning, UserNotFoundError, UserPermissionError
...@@ -33,6 +35,26 @@ async def get_all_users(current_user: UserModel = Depends(get_current_active_use ...@@ -33,6 +35,26 @@ async def get_all_users(current_user: UserModel = Depends(get_current_active_use
return result return result
@router.get('/list/project/annotators/{project_id}', response_model=dict[str, UserBaseModel])
async def get_project_annotator_users(project_id: str,
permissions: UserPermissions = Depends(UserPermissionChecker())) \
-> dict[str, UserBaseModel]:
session: AsyncSession
async with db_engine.session() as session:
stmt = (select(User)
.join(Assignment, User.user_id == Assignment.user_id)
.join(AssignmentScope, Assignment.assignment_scope_id == AssignmentScope.assignment_scope_id)
.join(AnnotationScheme, AssignmentScope.annotation_scheme_id == AnnotationScheme.annotation_scheme_id)
.where(AnnotationScheme.project_id == project_id)
.order_by(asc(User.username)))
result = (await session.scalars(stmt)).all()
return {
str(res.user_id): UserBaseModel(**res.__dict__)
for res in result
}
@router.get('/list/project/{project_id}', response_model=list[UserBaseModel]) @router.get('/list/project/{project_id}', response_model=list[UserBaseModel])
async def get_project_users(project_id: str, async def get_project_users(project_id: str,
permissions: UserPermissions = Depends(UserPermissionChecker())) \ permissions: UserPermissions = Depends(UserPermissionChecker())) \
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment