def test_open_recruitment_with_blocklist(self, recruiter): recruiter.config.set("mturk_qualification_blocklist", u"foo, bar") # Our fake response will always return the same QualificationType ID recruiter.mturkservice.get_qualification_type_by_name.return_value = { "id": u"fake id" } recruiter.open_recruitment(n=1) recruiter.mturkservice.create_hit.assert_called_once_with( question=MTurkQuestions.external( ad_url="http://fake-domain/ad?recruiter=mturk"), description="fake HIT description", duration_hours=1.0, experiment_id="TEST_EXPERIMENT_UID", lifetime_days=1, keywords=[u"kw1", u"kw2", u"kw3"], max_assignments=1, notification_url="http://fake-domain{}".format(SNS_ROUTE_PATH), reward=0.01, title="fake experiment title", annotation="TEST_EXPERIMENT_UID", qualifications=[ MTurkQualificationRequirements.min_approval(95), MTurkQualificationRequirements.restrict_to_countries(["US"]), MTurkQualificationRequirements.must_not_have(u"fake id"), MTurkQualificationRequirements.must_not_have(u"fake id"), ], )
def test_create_compensation_hit(self, with_cleanup): # In practice, this would include a qualification assigned to a # single worker. hit = with_cleanup.create_hit( **standard_hit_config( title="Compensation Immediate", question=MTurkQuestions.compensation(sandbox=True), ) ) assert hit["status"] == "Assignable" assert hit["max_assignments"] == 1
def compensate_worker(self, worker_id, email, dollars, notify=True): """Pay a worker by means of a special HIT that only they can see. """ qualification = self.mturkservice.create_qualification_type( name="Dallinger Compensation Qualification - {}".format( generate_random_id()), description=( "You have received a qualification to allow you to complete a " "compensation HIT from Dallinger for ${}.".format(dollars)), ) qid = qualification["id"] self.mturkservice.assign_qualification(qid, worker_id, 1, notify=notify) hit_request = { "experiment_id": "(compensation only)", "max_assignments": 1, "title": "Dallinger Compensation HIT", "description": "For compenation only; no task required.", "keywords": [], "reward": float(dollars), "duration_hours": 1, "lifetime_days": 3, "question": MTurkQuestions.compensation(sandbox=self.is_sandbox), "qualifications": [MTurkQualificationRequirements.must_have(qid)], "do_subscribe": False, } hit_info = self.mturkservice.create_hit(**hit_request) if email is not None: message = { "subject": "Dallinger Compensation HIT", "sender": self.config.get("dallinger_email_address"), "recipients": [email], "body": ("A special compenstation HIT is available for you to complete on MTurk.\n\n" "Title: {title}\n" "Reward: ${reward:.2f}\n" "URL: {worker_url}").format(**hit_info), } self.mailer.send(**message) else: message = {} return { "hit": hit_info, "qualification": qualification, "email": message }
def open_recruitment(self, n=1): """Open a connection to AWS MTurk and create a HIT.""" logger.info("Opening MTurk recruitment for {} participants".format(n)) if self.is_in_progress: raise MTurkRecruiterException( "Tried to open_recruitment on already open recruiter.") if self.hit_domain is None: raise MTurkRecruiterException("Can't run a HIT from localhost") self.mturkservice.check_credentials() if self.config.get("assign_qualifications"): self._create_mturk_qualifications() hit_request = { "experiment_id": self.config.get("id"), "max_assignments": n, "title": "{} ({})".format(self.config.get("title"), heroku_tools.app_name(self.config.get("id"))), "description": self.config.get("description"), "keywords": self._config_to_list("keywords"), "reward": self.config.get("base_payment"), "duration_hours": self.config.get("duration"), "lifetime_days": self.config.get("lifetime"), "question": MTurkQuestions.external(self.ad_url), "notification_url": self.notification_url, "annotation": self.config.get("id"), "qualifications": self._build_hit_qualifications(), } hit_info = self.mturkservice.create_hit(**hit_request) self._record_current_hit_id(hit_info["id"]) url = hit_info["worker_url"] return { "items": [url], "message": "HIT now published to Amazon Mechanical Turk", }
def test_open_recruitment_single_recruitee_builds_hit(self, recruiter): recruiter.open_recruitment(n=1) recruiter.mturkservice.create_hit.assert_called_once_with( question=MTurkQuestions.external( ad_url="http://fake-domain/ad?recruiter=mturk"), description=u"fake HIT description", duration_hours=1.0, experiment_id="TEST_EXPERIMENT_UID", keywords=[u"kw1", u"kw2", u"kw3"], lifetime_days=1, max_assignments=1, notification_url=u"http://fake-domain{}".format(SNS_ROUTE_PATH), reward=0.01, title=u"fake experiment title", annotation="TEST_EXPERIMENT_UID", qualifications=[ MTurkQualificationRequirements.min_approval(95), MTurkQualificationRequirements.restrict_to_countries(["US"]), ], )
def test_open_recruitment_with_more_than_pool_size_uses_requested_count( self, recruiter): num_recruits = recruiter.pool_size + 1 recruiter.open_recruitment(n=num_recruits) recruiter.mturkservice.create_hit.assert_called_once_with( question=MTurkQuestions.external( ad_url="http://fake-domain/ad?recruiter=mturklarge"), description="fake HIT description", duration_hours=1.0, experiment_id="TEST_EXPERIMENT_UID", keywords=["kw1", "kw2", "kw3"], lifetime_days=1, max_assignments=num_recruits, notification_url="http://fake-domain{}".format(SNS_ROUTE_PATH), reward=0.01, title="fake experiment title", annotation="TEST_EXPERIMENT_UID", qualifications=[ MTurkQualificationRequirements.min_approval(95), MTurkQualificationRequirements.restrict_to_countries(["US"]), ], )
def standard_hit_config(**kwargs): defaults = { "experiment_id": "some-experiment-id", "lifetime_days": 0.0004, # 34 seconds (30 is minimum) "max_assignments": 1, "notification_url": "https://url-of-notification-route", "title": "Test Title", "keywords": ["testkw1", "testkw2"], "reward": 0.01, "question": MTurkQuestions.external(ad_url="https://url-of-ad-route"), "duration_hours": 0.25, "qualifications": [ MTurkQualificationRequirements.min_approval(95), MTurkQualificationRequirements.restrict_to_countries(["US"]), ], "do_subscribe": False, } defaults.update(**kwargs) # Use fixed description, since this is how we clean up: defaults["description"] = TEST_HIT_DESCRIPTION + system_marker() return defaults
def test_open_recruitment_with_explicit_qualifications(self, recruiter): recruiter.config.set( "mturk_qualification_requirements", u""" [ { "QualificationTypeId":"789RVWYBAZW00EXAMPLE", "Comparator":"In", "IntegerValues":[10, 20, 30] } ] """, ) recruiter.open_recruitment(n=1) recruiter.mturkservice.create_hit.assert_called_once_with( question=MTurkQuestions.external( ad_url="http://fake-domain/ad?recruiter=mturk"), description="fake HIT description", duration_hours=1.0, experiment_id="TEST_EXPERIMENT_UID", lifetime_days=1, keywords=[u"kw1", u"kw2", u"kw3"], max_assignments=1, notification_url="http://fake-domain{}".format(SNS_ROUTE_PATH), reward=0.01, title="fake experiment title", annotation="TEST_EXPERIMENT_UID", qualifications=[ MTurkQualificationRequirements.min_approval(95), MTurkQualificationRequirements.restrict_to_countries(["US"]), { "QualificationTypeId": "789RVWYBAZW00EXAMPLE", "Comparator": "In", "IntegerValues": [10, 20, 30], }, ], )