diff options
| -rw-r--r-- | jb/managers/amt.py | 18 | ||||
| -rw-r--r-- | jb/models/assignment.py | 15 |
2 files changed, 23 insertions, 10 deletions
diff --git a/jb/managers/amt.py b/jb/managers/amt.py index b764ffc..88ae07d 100644 --- a/jb/managers/amt.py +++ b/jb/managers/amt.py @@ -3,6 +3,8 @@ from datetime import timezone, datetime from typing import Tuple, Optional, List, Dict, Any import botocore.exceptions +from generalresearchutils.currency import USDCent +from mypy_boto3_mturk import MTurkClient from mypy_boto3_mturk.type_defs import ( AssignmentTypeDef, BonusPaymentTypeDef, @@ -10,15 +12,14 @@ from mypy_boto3_mturk.type_defs import ( GetHITResponseTypeDef, CreateHITWithHITTypeResponseTypeDef, ) +from pydantic import ValidationError from jb.config import TOPIC_ARN from jb.models import AMTAccount from jb.models.assignment import Assignment from jb.models.bonus import Bonus -from generalresearchutils.currency import USDCent from jb.models.definitions import HitStatus from jb.models.hit import HitType, HitQuestion, Hit -from mypy_boto3_mturk import MTurkClient REJECT_MESSAGE_UNKNOWN_ASSIGNMENT = "Unknown assignment" REJECT_MESSAGE_NO_WORK = "Assignment was submitted with no attempted work." @@ -130,7 +131,17 @@ class AMTManager: """ res = self.amt_client.get_assignment(AssignmentId=amt_assignment_id) ass_res: AssignmentTypeDef = res["Assignment"] - assignment = Assignment.from_amt_get_assignment(ass_res) + try: + assignment = Assignment.from_amt_get_assignment(ass_res) + except ValidationError as e: + # Baddies have been known to submit assignments with purposely + # malformed "answer" (xml) section, which will raise + # a pydantic validation error. Try to parse again with no Answer. + logging.exception(e) + ass_res["Answer"] = None + # If it wasn't the Answer that caused the ValidationError, it'll raise again + assignment = Assignment.from_amt_get_assignment(ass_res) + # to be clear, this has not checked whether it exists in our db assert assignment.id is None return assignment @@ -140,7 +151,6 @@ class AMTManager: try: return self.get_assignment(amt_assignment_id=amt_assignment_id) - except botocore.exceptions.ClientError as e: logging.warning(e) error_code = e.response["Error"]["Code"] diff --git a/jb/models/assignment.py b/jb/models/assignment.py index 5dd0167..92e5a89 100644 --- a/jb/models/assignment.py +++ b/jb/models/assignment.py @@ -155,16 +155,19 @@ class Assignment(AssignmentStub): def check_answers_alignment(self) -> Self: if self.answers_dict is None: return self + if "amt_worker_id" not in self.answers_dict: + raise ValueError("answers_dict missing amt_worker_id") if self.amt_worker_id != self.answers_dict["amt_worker_id"]: raise ValueError("Assignment answer invalid worker_id") + if "amt_assignment_id" not in self.answers_dict: + raise ValueError("answers_dict missing amt_assignment_id") if self.amt_assignment_id != self.answers_dict["amt_assignment_id"]: raise ValueError("Assignment answer invalid amt_assignment_id") - if ( - self.tsid - and self.answers_dict["tsid"] - and self.tsid != self.answers_dict["tsid"] - ): - raise ValueError("Assignment answer invalid tsid") + if self.tsid: + if "tsid" not in self.answers_dict: + raise ValueError("answers_dict missing tsid") + if self.answers_dict["tsid"] and self.tsid != self.answers_dict["tsid"]: + raise ValueError("Assignment answer invalid tsid") return self # --- Properties --- |
