|
9 | 9 | from fastapi.encoders import jsonable_encoder |
10 | 10 | from fastapi.exceptions import HTTPException |
11 | 11 | from fastapi.responses import StreamingResponse |
12 | | -from sqlalchemy import or_ |
13 | | -from sqlalchemy.exc import MultipleResultsFound |
| 12 | +from sqlalchemy import or_, select |
| 13 | +from sqlalchemy.exc import MultipleResultsFound, NoResultFound |
14 | 14 | from sqlalchemy.orm import Session |
15 | 15 |
|
16 | 16 | from mavedb import deps |
17 | 17 | from mavedb.lib.authentication import UserData |
18 | | -from mavedb.lib.authorization import get_current_user, require_current_user, require_current_user_with_email |
| 18 | +from mavedb.lib.authorization import ( |
| 19 | + get_current_user, |
| 20 | + require_current_user, |
| 21 | + require_current_user_with_email, |
| 22 | + RoleRequirer, |
| 23 | +) |
19 | 24 | from mavedb.lib.contributors import find_or_create_contributor |
20 | 25 | from mavedb.lib.exceptions import MixedTargetError, NonexistentOrcidUserError, ValidationError |
21 | 26 | from mavedb.lib.identifiers import ( |
|
49 | 54 | ) |
50 | 55 | from mavedb.models.contributor import Contributor |
51 | 56 | from mavedb.models.enums.processing_state import ProcessingState |
| 57 | +from mavedb.models.enums.user_role import UserRole |
52 | 58 | from mavedb.models.experiment import Experiment |
53 | 59 | from mavedb.models.license import License |
54 | 60 | from mavedb.models.mapped_variant import MappedVariant |
|
57 | 63 | from mavedb.models.target_gene import TargetGene |
58 | 64 | from mavedb.models.target_sequence import TargetSequence |
59 | 65 | from mavedb.models.variant import Variant |
60 | | -from mavedb.view_models import mapped_variant, score_set |
| 66 | +from mavedb.view_models import mapped_variant, score_set, calibration |
61 | 67 | from mavedb.view_models.search import ScoreSetsSearch |
62 | 68 |
|
63 | 69 | logger = logging.getLogger(__name__) |
@@ -336,8 +342,10 @@ async def create_score_set( |
336 | 342 | raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="Unknown experiment") |
337 | 343 | # Not allow add score set in meta-analysis experiments. |
338 | 344 | if any(s.meta_analyzes_score_sets for s in experiment.score_sets): |
339 | | - raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, |
340 | | - detail="Score sets may not be added to a meta-analysis experiment.") |
| 345 | + raise HTTPException( |
| 346 | + status_code=status.HTTP_403_FORBIDDEN, |
| 347 | + detail="Score sets may not be added to a meta-analysis experiment.", |
| 348 | + ) |
341 | 349 |
|
342 | 350 | save_to_logging_context({"experiment": experiment.urn}) |
343 | 351 | assert_permission(user_data, experiment, Action.ADD_SCORE_SET) |
@@ -656,6 +664,43 @@ async def upload_score_set_variant_data( |
656 | 664 | return item |
657 | 665 |
|
658 | 666 |
|
| 667 | +@router.post( |
| 668 | + "/score-sets/{urn}/calibration/data", |
| 669 | + response_model=score_set.ScoreSet, |
| 670 | + responses={422: {}}, |
| 671 | + response_model_exclude_none=True, |
| 672 | +) |
| 673 | +async def update_score_set_calibration_data( |
| 674 | + *, |
| 675 | + urn: str, |
| 676 | + calibration_update: dict[str, calibration.Calibration], |
| 677 | + db: Session = Depends(deps.get_db), |
| 678 | + user_data: UserData = Depends(RoleRequirer([UserRole.admin])), |
| 679 | +): |
| 680 | + """ |
| 681 | + Update thresholds / score calibrations for a score set. |
| 682 | + """ |
| 683 | + save_to_logging_context({"requested_resource": urn, "resource_property": "score_thresholds"}) |
| 684 | + |
| 685 | + try: |
| 686 | + item = db.scalars(select(ScoreSet).where(ScoreSet.urn == urn)).one() |
| 687 | + except NoResultFound: |
| 688 | + logger.info( |
| 689 | + msg="Failed to add score thresholds; The requested score set does not exist.", extra=logging_context() |
| 690 | + ) |
| 691 | + raise HTTPException(status_code=404, detail=f"score set with URN '{urn}' not found") |
| 692 | + |
| 693 | + assert_permission(user_data, item, Action.UPDATE) |
| 694 | + |
| 695 | + item.score_calibrations = {k: v.dict() for k, v in calibration_update.items()} |
| 696 | + db.add(item) |
| 697 | + db.commit() |
| 698 | + db.refresh(item) |
| 699 | + |
| 700 | + save_to_logging_context({"updated_resource": item.urn}) |
| 701 | + return item |
| 702 | + |
| 703 | + |
659 | 704 | @router.put( |
660 | 705 | "/score-sets/{urn}", response_model=score_set.ScoreSet, responses={422: {}}, response_model_exclude_none=True |
661 | 706 | ) |
|
0 commit comments