def qualify(qualification, value, worker): """Assign a qualification to a worker.""" # create connection to AWS from boto.mturk.connection import MTurkConnection config = PsiturkConfig() config.load_config() aws_access_key_id = config.get('AWS Access', 'aws_access_key_id') aws_secret_access_key = config.get('AWS Access', 'aws_secret_access_key') conn = MTurkConnection(aws_access_key_id, aws_secret_access_key) def get_workers_with_qualification(qualification): """Get workers with the given qualification.""" results = [] continue_flag = True page = 1 while(continue_flag): new_results = conn.get_qualifications_for_qualification_type( qualification, page_size=100, page_number=page) if(len(new_results) == 0): continue_flag = False else: results.extend(new_results) page = page + 1 return results results = get_workers_with_qualification(qualification) workers = [x.SubjectId for x in results] # assign the qualification click.echo( "Assigning qualification {} with value {} to worker {}".format( qualification, value, worker)) if worker in workers: result = conn.update_qualification_score(qualification, worker, value) else: result = conn.assign_qualification(qualification, worker, value) if result: click.echo(result) # print out the current set of workers with the qualification results = get_workers_with_qualification(qualification) click.echo("{} workers with qualification {}:".format( len(results), qualification)) values = [r.IntegerValue for r in results] unique_values = list(set([r.IntegerValue for r in results])) for v in unique_values: click.echo("{} with value {}".format( len([val for val in values if val == v]), v))
def run(script=None, execute=None, testfile=None, quiet=False): try: using_libedit = 'libedit' in readline.__doc__ if using_libedit: print('\n'.join([ 'libedit version of readline detected.', 'readline will not be well behaved, which may cause all sorts', 'of problems for the psiTurk shell. We highly recommend installing', 'the gnu version of readline by running "sudo pip install gnureadline".', 'Note: "pip install readline" will NOT work because of how the OSX', 'pythonpath is structured.' ])) except TypeError: pass # pyreadline doesn't have anything for __doc__ # Drop arguments which were already processed in command_line.py sys.argv = [sys.argv[0]] config = PsiturkConfig() config.load_config() server = control.ExperimentServerController(config) shell = PsiturkNetworkShell(config, server, mode=config.get('Shell Parameters', 'launch_in_mode'), quiet=quiet) if script: shell.runcmds_plus_hooks([f'load {script}']) elif execute: shell.runcmds_plus_hooks([execute]) else: shell.cmdloop()
def ad_address(mode, hit_id): if mode == "debug": address = '/complete' elif mode in ["sandbox", "live"]: CONFIG = PsiturkConfig() CONFIG.load_config() username = os.getenv('psiturk_access_key_id', CONFIG.get("psiTurk Access", "psiturk_access_key_id")) password = os.getenv('psiturk_secret_access_id', CONFIG.get("psiTurk Access", "psiturk_secret_access_id")) try: req = requests.get('https://api.psiturk.org/api/ad/lookup/' + hit_id, auth=(username, password)) except: raise ValueError('api_server_not_reachable') else: if req.status_code == 200: hit_address = req.json()['ad_id'] else: raise ValueError("something here") if mode == "sandbox": address = 'https://sandbox.ad.psiturk.org/complete/' + str(hit_address) elif mode == "live": address = 'https://ad.psiturk.org/complete/' + str(hit_address) else: raise ValueError("Unknown mode: {}".format(mode)) return Response(dumps({"address": address}), status=200)
def run(script=None, execute=None, testfile=None, quiet=False): using_libedit = 'libedit' in readline.__doc__ if using_libedit: self.poutput( colorize( '\n'.join([ 'libedit version of readline detected.', 'readline will not be well behaved, which may cause all sorts', 'of problems for the psiTurk shell. We highly recommend installing', 'the gnu version of readline by running "sudo pip install gnureadline".', 'Note: "pip install readline" will NOT work because of how the OSX', 'pythonpath is structured.' ]), 'red', False)) # Drop arguments which were already processed in command_line.py sys.argv = [sys.argv[0]] #opt = docopt(__doc__, sys.argv[1:]) config = PsiturkConfig() config.load_config() server = control.ExperimentServerController(config) shell = PsiturkNetworkShell(config, server, config.getboolean('Shell Parameters', 'launch_in_sandbox_mode'), quiet=quiet) if script: shell.runcmds_plus_hooks(['load {}'.format(script)]) elif execute: shell.runcmds_plus_hooks([execute]) elif testfile: shell.run_transcript_tests(testfile) else: shell.cmdloop()
def do_it(): from psiturk.psiturk_shell import PsiturkNetworkShell import psiturk.experiment_server_controller as control from psiturk.psiturk_config import PsiturkConfig import psiturk.experiment_server_controller mocker.patch.object(psiturk.experiment_server_controller.ExperimentServerController, 'is_port_available', lambda *args, **kwargs: True) mocker.patch.object(PsiturkNetworkShell,'get_intro_prompt', lambda *args, **kwargs: '') mocker.patch.object(PsiturkNetworkShell,'update_hit_tally', lambda *args, **kwargs: None) mocker.patch.object(PsiturkNetworkShell,'_confirm_dialog', lambda *args, **kwargs: True) config = PsiturkConfig() config.load_config() server = control.ExperimentServerController(config) launch_in_sandbox_mode = True quiet = False shell = PsiturkNetworkShell( config, server, launch_in_sandbox_mode, quiet=quiet) shell.persistent_history_file = None shell.echo = True stubber.assert_no_pending_responses() return shell
def test_awskeys_invalid(capfd): import psiturk.experiment_server_controller as control from psiturk.psiturk_config import PsiturkConfig from psiturk.psiturk_shell import PsiturkNetworkShell import psiturk.psiturk_shell as ps config = PsiturkConfig() config.load_config() config.set('Shell Parameters', 'persistent_history_file', '') config.set('AWS Access', 'aws_access_key_id', '') config.set('AWS Access', 'aws_secret_access_key', '') server = control.ExperimentServerController(config) launch_in_sandbox_mode = True quiet = False try: shell = PsiturkNetworkShell(config, server, launch_in_sandbox_mode, quiet=quiet) except SystemExit: pass out, err = capfd.readouterr() assert NoMturkConnectionError().message in out
def test_awscreds_notset_shell(capfd, experiment_server_controller, psiturk_shell): from psiturk.psiturk_config import PsiturkConfig from psiturk.psiturk_shell import PsiturkNetworkShell import psiturk.psiturk_shell as ps import psiturk.experiment_server_controller config = PsiturkConfig() config.load_config() config.set('Shell Parameters', 'persistent_history_file', '') config.set('AWS Access', 'aws_access_key_id', 'YourAccessKeyId') config.set('AWS Access', 'aws_secret_access_key', 'YourSecretAccessKey') server = psiturk.experiment_server_controller.ExperimentServerController( config) launch_in_sandbox_mode = True quiet = False try: shell = PsiturkNetworkShell(config, server, launch_in_sandbox_mode, quiet=quiet) except SystemExit: pass out, err = capfd.readouterr() assert AWSAccessKeysNotSetError().message in err
def configure_hit(self, hit_config): ''' Configure HIT ''' # configure question_url based on the id experiment_portal_url = hit_config['ad_location'] frame_height = 600 mturk_question = ExternalQuestion(experiment_portal_url, frame_height) # Qualification: quals = Qualifications() approve_requirement = hit_config['approve_requirement'] quals.add( PercentAssignmentsApprovedRequirement("GreaterThanOrEqualTo", approve_requirement)) if hit_config['us_only']: quals.add(LocaleRequirement("EqualTo", "US")) # Create a HIT type for this HIT. hit_type = self.mtc.register_hit_type(hit_config['title'], hit_config['description'], hit_config['reward'], hit_config['duration'], keywords=hit_config['keywords'], approval_delay=None, qual_req=quals)[0] # Check the config file to see if notifications are wanted. config = PsiturkConfig() config.load_config() try: url = config.get('Server Parameters', 'notification_url') all_event_types = [ "AssignmentAccepted", "AssignmentAbandoned", "AssignmentReturned", "AssignmentSubmitted", "HITReviewable", "HITExpired", ] self.mtc.set_rest_notification(hit_type.HITTypeId, url, event_types=all_event_types) except: pass # Specify all the HIT parameters self.param_dict = dict(hit_type=hit_type.HITTypeId, question=mturk_question, lifetime=hit_config['lifetime'], max_assignments=hit_config['max_assignments'], questions=None, response_groups=[ 'Minimal', 'HITDetail', 'HITQuestion', 'HITAssignmentSummary' ])
def _set_heroku_config_vars(): from psiturk.psiturk_config import PsiturkConfig CONFIG = PsiturkConfig() CONFIG.load_config() subprocess.call(['heroku', 'config:set', 'ON_CLOUD=true']) print() print('psiturk has finished setting heroku config vars.')
def setup_heroku_remote_config(self): CONFIG = PsiturkConfig() CONFIG.load_config() new_config = {} sections = ['psiTurk Access', 'AWS Access'] for section in sections: for item in CONFIG.items(section): new_config[item[0]] = item[1] new_config['ON_CLOUD'] = True self.app.update_config(new_config) print('Built remote Heroku config from AWS and PsiTurk accounts found in local ' + color.BOLD + '.psiturkconfig' + color.END)
def __init__(self, mode): self.mode = mode if self.mode == 'sandbox': self.hitId = COMPENSATION_HIT_ID_SANDBOX self.qualificationTypeId = BONUS_QUALIFICATION_SANDBOX self.endpoint_url = 'https://mturk-requester-sandbox.us-east-1.amazonaws.com' else: self.hitId = COMPENSATION_HIT_ID self.qualificationTypeId = BONUS_QUALIFICATION_PROD self.endpoint_url = 'https://mturk-requester.us-east-1.amazonaws.com' config = PsiturkConfig() config.load_config() self.config = config self.mtc = None
def test_wrapper_generate_hit_config_reads_qualifications_from_config_file( self, edit_config_file, stubber, amt_services_wrapper): ''' makes sure that whitelist_qualid finds its way into the qual list as EXISTS ''' whitelist_config_file_qual_ids = [ 'whitelist_config_123', 'whitelist_config_456' ] blacklist_config_file_qual_ids = [ 'blacklist_config_123', 'blacklist_config_456' ] edit_config_file( 'require_quals =', 'require_quals = {}'.format( ','.join(whitelist_config_file_qual_ids))) edit_config_file( 'block_quals =', 'block_quals = {}'.format( ','.join(blacklist_config_file_qual_ids))) whitelist_qualification_ids_passed = [ 'white_passed_123', 'white_passed_456' ] blacklist_qualification_ids_passed = [ 'black_passed_123', 'black_passed_456' ] # need to reset the amt_services_wrapper config after editing config file above. from psiturk.psiturk_config import PsiturkConfig config = PsiturkConfig() config.load_config() amt_services_wrapper.config = config hit_config = amt_services_wrapper._generate_hit_config( 'loc_123', 1, '1.00', 1, whitelist_qualification_ids=whitelist_qualification_ids_passed, blacklist_qualification_ids=blacklist_qualification_ids_passed) whitelist_qual_ids = whitelist_config_file_qual_ids + whitelist_qualification_ids_passed blacklist_qual_ids = blacklist_config_file_qual_ids + blacklist_qualification_ids_passed for qual in whitelist_qual_ids: assert qual in hit_config['whitelist_qualification_ids'] for qual in blacklist_qual_ids: assert qual in hit_config['blacklist_qualification_ids']
def _set_heroku_config_vars(): from psiturk.psiturk_config import PsiturkConfig CONFIG = PsiturkConfig() CONFIG.load_config() subprocess.call(['heroku', 'config:set', 'ON_CLOUD=true']) sections = ['psiTurk Access', 'AWS Access'] for section in sections: for item in CONFIG.items(section): subprocess.call(['heroku', 'config:set', '='.join(item)]) print() print('psiturk has finished setting heroku config vars.')
def deploy(verbose, app): """Deploy app using Heroku to MTurk.""" # Load psiTurk configuration. config = PsiturkConfig() config.load_config() # Set the mode. config.set("Experiment Configuration", "mode", "deploy") config.set("Server Parameters", "logfile", "-") # Ensure that psiTurk is not in sandbox mode. config.set("Shell Parameters", "launch_in_sandbox_mode", "false") # Do shared setup. deploy_sandbox_shared_setup(verbose=verbose, app=app)
def __init__(self, config=None, mode='sandbox'): """__init__.""" if config: self.config = config else: config = PsiturkConfig() config.load_config() self.config = config self.mode = None self.mtc = None self.param_dict = None self.set_mode(mode) self.valid_login = self.verify_aws_login() if not self.valid_login: raise NoMturkConnectionError()
def awaken(app, databaseurl): """Restore the database from a given url.""" config = PsiturkConfig() config.load_config() database_size = config.get('Database Parameters', 'database_size') subprocess.call( "heroku addons:create heroku-postgresql:{} --app {}".format( database_size, app), shell=True) subprocess.call("heroku pg:wait --app {}".format(app), shell=True) conn = boto.connect_s3( config.get('AWS Access', 'aws_access_key_id'), config.get('AWS Access', 'aws_secret_access_key'), ) bucket = conn.get_bucket(app) key = bucket.lookup('database.dump') url = key.generate_url(expires_in=300) cmd = "heroku pg:backups restore" subprocess.call("{} '{}' DATABASE_URL --app {} --confirm {}".format( cmd, url, app, app), shell=True) subprocess.call("heroku addons:create rediscloud:250 --app {}".format(app), shell=True) # Scale up the dynos. scale_up_dynos(app)
def sandbox(verbose, app): """Deploy app using Heroku to the MTurk Sandbox.""" # Load psiTurk configuration. config = PsiturkConfig() config.load_config() # Set the mode. config.set("Experiment Configuration", "mode", "sandbox") config.set("Server Parameters", "logfile", "-") # Ensure that psiTurk is in sandbox mode. config.set("Shell Parameters", "launch_in_sandbox_mode", "true") # Do shared setup. deploy_sandbox_shared_setup(verbose=verbose, app=app)
def deploy(verbose): """Deploy app using Heroku to MTurk.""" # Load psiTurk configuration. config = PsiturkConfig() config.load_config() # Set the mode. config.set("Experiment Configuration", "mode", "deploy") config.set("Server Parameters", "logfile", "-") # Ensure that psiTurk is not in sandbox mode. config.set("Shell Parameters", "launch_in_sandbox_mode", "false") # Do shared setup. deploy_sandbox_shared_setup(verbose=verbose)
def __init__(self): """Set up the connection to MTurk and psiTurk web services.""" # load the configuration options self.config = PsiturkConfig() self.config.load_config() class FakeExperimentServerController(object): def is_server_running(self): return 'yes' self.server = FakeExperimentServerController() # Get keys from environment variables or config file. self.aws_access_key_id = os.getenv( "aws_access_key_id", self.config.get("AWS Access", "aws_access_key_id")) self.aws_secret_access_key = os.getenv( "aws_secret_access_key", self.config.get("AWS Access", "aws_secret_access_key")) self.aws_region = os.getenv( "aws_region", self.config.get("AWS Access", "aws_region"))
def backup(app): """Dump the database.""" dump_path = dump_database(app) config = PsiturkConfig() config.load_config() conn = boto.connect_s3( config.get('AWS Access', 'aws_access_key_id'), config.get('AWS Access', 'aws_secret_access_key'), ) bucket = conn.create_bucket( app, location=boto.s3.connection.Location.DEFAULT ) k = boto.s3.key.Key(bucket) k.key = 'database.dump' k.set_contents_from_filename(dump_path) url = k.generate_url(expires_in=0, query_auth=False) log("The database backup URL is...") print(url)
def __init__(self, config=None): if not config: config = PsiturkConfig() config.load_config() self.access_key = config.get('psiTurk Access', 'psiturk_access_key_id') self.secret_key = config.get('psiTurk Access', 'psiturk_secret_access_id') self.local_port = config.getint('Server Parameters', 'port') self.is_open = False self.tunnel_port = 8000 # Set by tunnel server self.tunnel_host = 'tunnel.psiturk.org' self.tunnel_server = os.path.join(os.path.dirname(__file__), "tunnel/ngrok") self.tunnel_config = os.path.join(os.path.dirname(__file__), "tunnel/ngrok-config")
def __init__(self): config = PsiturkConfig() config.load_config() self.access_key = config.get("psiTurk Access", "psiturk_access_key_id") self.secret_key = config.get("psiTurk Access", "psiturk_secret_access_id") self.local_port = config.getint("Server Parameters", "port") self.is_open = False self.tunnel_port = 8000 # Set by tunnel server self.tunnel_host = "tunnel.psiturk.org" self.tunnel_server = os.path.join(os.path.dirname(__file__), "tunnel/ngrok") self.tunnel_config = os.path.join(os.path.dirname(__file__), "tunnel/ngrok-config")
def __init__(self): """Set up the connection to MTurk and psiTurk web services.""" # load the configuration options self.config = PsiturkConfig() self.config.load_config() class FakeExperimentServerController(object): def is_server_running(self): return "yes" self.server = FakeExperimentServerController() # Get keys from environment variables or config file. self.aws_access_key_id = os.getenv("aws_access_key_id", self.config.get("AWS Access", "aws_access_key_id")) self.aws_secret_access_key = os.getenv( "aws_secret_access_key", self.config.get("AWS Access", "aws_secret_access_key") ) self.aws_region = os.getenv("aws_region", self.config.get("AWS Access", "aws_region"))
def scale_up_dynos(id): """Scale up the Heroku dynos.""" # Load psiTurk configuration. config = PsiturkConfig() config.load_config() dyno_type = config.get('Server Parameters', 'dyno_type') num_dynos_web = config.get('Server Parameters', 'num_dynos_web') num_dynos_worker = config.get('Server Parameters', 'num_dynos_worker') log("Scaling up the dynos...") subprocess.call("heroku ps:scale web=" + str(num_dynos_web) + ":" + str(dyno_type) + " --app " + id, shell=True) subprocess.call("heroku ps:scale worker=" + str(num_dynos_worker) + ":" + str(dyno_type) + " --app " + id, shell=True) clock_on = config.getboolean('Server Parameters', 'clock_on') if clock_on: subprocess.call("heroku ps:scale clock=1:" + dyno_type + " --app " + id, shell=True)
def scale_up_dynos(id): """Scale up the Heroku dynos.""" # Load psiTurk configuration. config = PsiturkConfig() config.load_config() dyno_type = config.get('Server Parameters', 'dyno_type') num_dynos_web = config.get('Server Parameters', 'num_dynos_web') num_dynos_worker = config.get('Server Parameters', 'num_dynos_worker') log("Scaling up the dynos...") subprocess.call( "heroku ps:scale web=" + str(num_dynos_web) + ":" + str(dyno_type) + " --app " + id, shell=True) subprocess.call( "heroku ps:scale worker=" + str(num_dynos_worker) + ":" + str(dyno_type) + " --app " + id, shell=True) clock_on = config.getboolean('Server Parameters', 'clock_on') if clock_on: subprocess.call( "heroku ps:scale clock=1:" + dyno_type + " --app " + id, shell=True)
def backup(app): """Dump the database.""" dump_path = dump_database(app) config = PsiturkConfig() config.load_config() conn = boto.connect_s3( config.get('AWS Access', 'aws_access_key_id'), config.get('AWS Access', 'aws_secret_access_key'), ) bucket = conn.create_bucket(app, location=boto.s3.connection.Location.DEFAULT) k = boto.s3.key.Key(bucket) k.key = 'database.dump' k.set_contents_from_filename(dump_path) url = k.generate_url(expires_in=0, query_auth=False) log("The database backup URL is...") print(url)
def awaken(app, databaseurl): """Restore the database from a given url.""" config = PsiturkConfig() config.load_config() database_size = config.get('Database Parameters', 'database_size') subprocess.call( "heroku addons:create heroku-postgresql:{} --app {}".format( database_size, app), shell=True) subprocess.call("heroku pg:wait --app {}".format(app), shell=True) conn = boto.connect_s3( config.get('AWS Access', 'aws_access_key_id'), config.get('AWS Access', 'aws_secret_access_key'), ) bucket = conn.get_bucket(app) key = bucket.lookup('database.dump') url = key.generate_url(expires_in=300) cmd = "heroku pg:backups restore" subprocess.call( "{} '{}' DATABASE_URL --app {} --confirm {}".format( cmd, url, app, app), shell=True) subprocess.call( "heroku addons:create rediscloud:250 --app {}".format(app), shell=True) # Scale up the dynos. scale_up_dynos(app)
def test_awskeys_invalid_shell(capfd, experiment_server_controller, psiturk_shell): """test_awskeys_invalid_shell.""" import psiturk.experiment_server_controller from psiturk.psiturk_config import PsiturkConfig from psiturk.psiturk_shell import PsiturkNetworkShell config = PsiturkConfig() config.load_config() config.set('Shell Parameters', 'persistent_history_file', '') server = psiturk.experiment_server_controller.ExperimentServerController( config) quiet = False try: shell = PsiturkNetworkShell(config, server, mode='sandbox', quiet=quiet) except SystemExit: pass out, err = capfd.readouterr() assert NoMturkConnectionError().message in err
# # Database setup from psiturk.db import db_session, init_db from psiturk.models import Participant from json import dumps, loads import random import csv import os import io from datetime import datetime from datetime import timedelta from psiturk.psiturk_statuses import * from flask_mail import Mail, Message # load the configuration options config = PsiturkConfig() config.load_config() # if you want to add a password protect route use this myauth = PsiTurkAuthorization(config) # explore the Blueprint custom_code = Blueprint('custom_code', __name__, template_folder='templates', static_folder='static') app.config.update(MAIL_SERVER=config.get('Mail Parameters', 'mail_server'), MAIL_PORT=config.get('Mail Parameters', 'mail_port'), MAIL_USE_SSL=config.get('Mail Parameters', 'mail_use_ssl'), MAIL_USE_TLS=config.get('Mail Parameters', 'mail_use_tls'), MAIL_USERNAME=config.get('Mail Parameters', 'mail_username'),
# Verify that the package is usable. log("Verifying that directory is compatible with Wallace...") if not verify_package(verbose=verbose): raise AssertionError( "This is not a valid Wallace app. " + "Fix the errors and then try running 'wallace verify'.") # Verify that the Postgres server is running. try: psycopg2.connect(database="x", user="******", password="******") except psycopg2.OperationalError, e: if "could not connect to server" in str(e): raise RuntimeError("The Postgres server isn't running.") # Load psiTurk configuration. config = PsiturkConfig() config.load_config() # Check that the demo-specific requirements are satisfied. try: with open("requirements.txt", "r") as f: dependencies = f.readlines() except: dependencies = [] pkg_resources.require(dependencies) # Generate a unique id for this experiment. id = "w" + str(uuid.uuid4())[0:28] # If the user provided an app name, use it everywhere that's user-facing.
def configure_hit(self, hit_config): ''' Configure HIT ''' # Qualification: quals = [] quals.append(dict( QualificationTypeId=PERCENT_ASSIGNMENTS_APPROVED_QUAL_ID, Comparator='GreaterThanOrEqualTo', IntegerValues=[int(hit_config['approve_requirement'])] )) quals.append(dict( QualificationTypeId=NUMBER_HITS_APPROVED_QUAL_ID, Comparator='GreaterThanOrEqualTo', IntegerValues=[int(hit_config['number_hits_approved'])] )) if hit_config['require_master_workers']: master_qualId = MASTERS_SANDBOX_QUAL_ID if self.is_sandbox else MASTERS_QUAL_ID quals.append(dict( QualificationTypeId=master_qualId, Comparator='Exists' )) if hit_config['us_only']: quals.append(dict( QualificationTypeId=LOCALE_QUAL_ID, Comparator='EqualTo', LocaleValues=[{'Country': 'US'}] )) # Create a HIT type for this HIT. hit_type = self.mtc.create_hit_type( Title=hit_config['title'], Description=hit_config['description'], Reward=str(hit_config['reward']), AssignmentDurationInSeconds=int(hit_config['duration'].total_seconds()), Keywords=hit_config['keywords'], QualificationRequirements=quals) # Check the config file to see if notifications are wanted. config = PsiturkConfig() config.load_config() try: url = config.get('Server Parameters', 'notification_url') all_event_types = [ "AssignmentAccepted", "AssignmentAbandoned", "AssignmentReturned", "AssignmentSubmitted", "HITReviewable", "HITExpired", ] # TODO: not sure if this works. Can't find documentation in PsiTurk or MTurk self.mtc.update_notification_settings( HitTypeId=hit_type['HITTypeId'], Notification=dict( Destination=url, Transport='REST', Version=NOTIFICATION_VERSION, EventTypes=all_event_types, ), ) except Exception as e: pass schema_url = "http://mechanicalturk.amazonaws.com/AWSMechanicalTurkDataSchemas/2006-07-14/ExternalQuestion.xsd" template = '<ExternalQuestion xmlns="%(schema_url)s"><ExternalURL>%%(external_url)s</ExternalURL><FrameHeight>%%(frame_height)s</FrameHeight></ExternalQuestion>' % vars() question = template % dict( external_url=hit_config['ad_location'], frame_height=600, ) # Specify all the HIT parameters self.param_dict = dict( HITTypeId=hit_type['HITTypeId'], Question=question, LifetimeInSeconds=int(hit_config['lifetime'].total_seconds()), MaxAssignments=hit_config['max_assignments'], # TODO # ResponseGroups=[ # 'Minimal', # 'HITDetail', # 'HITQuestion', # 'HITAssignmentSummary' # ] )
from sqlalchemy import or_ from psiturk.psiturk_config import PsiturkConfig from psiturk.experiment_errors import ExperimentError from psiturk.user_utils import PsiTurkAuthorization, nocache # # Database setup from psiturk.db import db_session, init_db from psiturk.models import Participant from json import dumps, loads # for basic experiment setup from numpy import linspace, array # load the configuration options config = PsiturkConfig() config.load_config() config.SECREY_KEY = 'my_secret_key' myauth = PsiTurkAuthorization(config) # if you want to add a password protect route use this # explore the Blueprint custom_code = Blueprint('custom_code', __name__, template_folder='templates', static_folder='static') import gpExperiment as gpe ## LOAD GP STUFF INTO WORKSPACE @custom_code.route('/init_experiment', methods=['GET']) def init_experiment(): if not request.args.has_key('condition'): raise ExperimentError('improper_inputs') # i don't like returning HTML to JSON requests... maybe should change this
def configure_hit(self, hit_config): ''' Configure HIT ''' # configure question_url based on the id experiment_portal_url = hit_config['ad_location'] frame_height = 600 mturk_question = ExternalQuestion(experiment_portal_url, frame_height) # Qualification: quals = Qualifications() approve_requirement = hit_config['approve_requirement'] quals.add( PercentAssignmentsApprovedRequirement("GreaterThanOrEqualTo", approve_requirement)) if hit_config['us_only']: quals.add(LocaleRequirement("EqualTo", "US")) # Create a HIT type for this HIT. hit_type = self.mtc.register_hit_type( hit_config['title'], hit_config['description'], hit_config['reward'], hit_config['duration'], keywords=hit_config['keywords'], approval_delay=None, qual_req=None)[0] # Check the config file to see if notifications are wanted. config = PsiturkConfig() config.load_config() try: url = config.get('Server Parameters', 'notification_url') all_event_types = [ "AssignmentAccepted", "AssignmentAbandoned", "AssignmentReturned", "AssignmentSubmitted", "HITReviewable", "HITExpired", ] self.mtc.set_rest_notification( hit_type.HITTypeId, url, event_types=all_event_types) except: pass # Specify all the HIT parameters self.param_dict = dict( hit_type=hit_type.HITTypeId, question=mturk_question, lifetime=hit_config['lifetime'], max_assignments=hit_config['max_assignments'], title=hit_config['title'], description=hit_config['description'], keywords=hit_config['keywords'], reward=hit_config['reward'], duration=hit_config['duration'], approval_delay=None, questions=None, qualifications=quals, response_groups=[ 'Minimal', 'HITDetail', 'HITQuestion', 'HITAssignmentSummary' ])
from psiturk.psiturk_config import PsiturkConfig import subprocess CONFIG = PsiturkConfig() CONFIG.load_config() sections = ['psiTurk Access','AWS Access'] for section in sections: for item in CONFIG.items(section): #print 'heroku config:set ' + '='.join(item) subprocess.call('heroku config:set ' + '='.join(item), shell=True) subprocess.call('heroku config:set ON_HEROKU=true', shell=True)
from __future__ import print_function from __future__ import absolute_import # myapp.mycustomapplication from builtins import str from gunicorn.app.base import Application from gunicorn import util import multiprocessing from psiturk.psiturk_config import PsiturkConfig import os import hashlib config = PsiturkConfig() config.load_config() class ExperimentServer(Application): ''' Custom Gunicorn Server Application that serves up the Experiment application ''' def __init__(self): '''__init__ method Load the base config and assign some core attributes. ''' self.load_user_config() self.usage = None self.callable = None self.options = self.user_options self.prog = None self.do_load_config() print("Now serving on", "http://" + self.options["bind"])
from psiturk.psiturk_config import PsiturkConfig from psiturk.experiment_errors import ExperimentError from psiturk.user_utils import PsiTurkAuthorization, nocache # # Database setup from psiturk.db import db_session, init_db from psiturk.models import Participant from json import dumps, loads # for basic experiment setup from numpy import linspace from numpy import array as npa # load the configuration options config = PsiturkConfig() config.load_config() config.SECREY_KEY = 'my_secret_key' myauth = PsiTurkAuthorization( config) # if you want to add a password protect route use this # explore the Blueprint custom_code = Blueprint('custom_code', __name__, template_folder='templates', static_folder='static') from rotationExperiment import rotationExperiment ## GET SUBJECT EXPERIMENT PARAMS
# Verify that the package is usable. log("Verifying that directory is compatible with Wallace...") if not verify_package(verbose=verbose): raise AssertionError( "This is not a valid Wallace app. " + "Fix the errors and then try running 'wallace verify'.") # Verify that the Postgres server is running. try: psycopg2.connect(database="x", user="******", password="******") except psycopg2.OperationalError, e: if "could not connect to server" in str(e): raise RuntimeError("The Postgres server isn't running.") # Load psiTurk configuration. config = PsiturkConfig() config.load_config() # Check that the version of Wallace specified in the config file is the one # that we are currently running. wallace_version = config.get('Experiment Configuration', 'wallace_version') this_version = pkg_resources.require("wallace")[0].version if wallace_version != this_version: raise AssertionError( "You are using Wallace v" + this_version + ", " "but the experiment requires v" + wallace_version) # Generate a unique id for this experiment. id = "w" + str(uuid.uuid4())[0:28] log("Running as experiment " + id + "...")
return subprocess.check_output(x, shell=True).strip() print('== Writing config.txt ==') from jinja2 import Environment, FileSystemLoader env = Environment(loader=FileSystemLoader('templates')) template = env.get_template('config.txt') with open('config.txt', 'w+') as f: f.write( template.render({ 'app_url': bash('heroku domains').split('\n')[1], 'db_url': bash('heroku config:get DATABASE_URL') })) print('== Setting heroku config variables ==') CONFIG = PsiturkConfig() CONFIG.load_config() sections = ['psiTurk Access', 'AWS Access'] for section in sections: for key, val in CONFIG.items(section): if val.startswith('Your'): print('ERROR: {key} is not defined in ~/.psiturkconfig'.format( **locals())) print( 'http://psiturk.readthedocs.io/en/latest/configuration.html#global-configuration-file' ) exit(1) #print 'heroku config:set ' + '='.join(item) bash('heroku config:set {key}={val}'.format(**locals()))
def debug(verbose): """Run the experiment locally.""" (id, tmp) = setup(debug=True, verbose=verbose) # Drop all the tables from the database. db.init_db(drop_all=True) # Switch to the temporary directory. cwd = os.getcwd() os.chdir(tmp) # Load psiTurk configuration. config = PsiturkConfig() config.load_config() # Set the mode to debug. config.set("Experiment Configuration", "mode", "debug") config.set("Shell Parameters", "launch_in_sandbox_mode", "true") config.set( "Server Parameters", "logfile", os.path.join(cwd, config.get("Server Parameters", "logfile"))) # Swap in the HotAirRecruiter os.rename("wallace_experiment.py", "wallace_experiment_tmp.py") with open("wallace_experiment_tmp.py", "r+") as f: with open("wallace_experiment.py", "w+") as f2: f2.write("from wallace.recruiters import HotAirRecruiter\n") for idx, line in enumerate(f): if re.search("\s*self.recruiter = (.*)", line): p = line.partition("self.recruiter =") f2.write(p[0] + p[1] + ' HotAirRecruiter\n') else: f2.write(line) os.remove("wallace_experiment_tmp.py") # Set environment variables. aws_vars = ['aws_access_key_id', 'aws_secret_access_key', 'aws_region'] for var in aws_vars: if var not in os.environ: os.environ[var] = config.get('AWS Access', var) pt_vars = ['psiturk_access_key_id', 'psiturk_secret_access_id'] for var in pt_vars: if var not in os.environ: os.environ[var] = config.get('psiTurk Access', var) if "HOST" not in os.environ: os.environ["HOST"] = config.get('Server Parameters', 'host') # Start up the local server log("Starting up the server...") # Try opening the psiTurk shell. try: p = pexpect.spawn("psiturk") p.expect_exact("]$") p.sendline("server on") p.expect_exact("Experiment server launching...") # Launche the experiment. time.sleep(4) host = config.get("Server Parameters", "host") port = config.get("Server Parameters", "port") subprocess.call( 'curl --data "" http://{}:{}/launch'.format(host, port), shell=True) log("Here's the psiTurk shell...") p.interact() except Exception: print "\nCouldn't open the psiTurk shell. Internet connection okay?" log("Completed debugging of experiment " + id + ".") os.chdir(cwd)
def deploy_sandbox_shared_setup(verbose=True, app=None, web_procs=1): """Set up Git, push to Heroku, and launch the app.""" out = None if verbose else open(os.devnull, 'w') (id, tmp) = setup_experiment(debug=False, verbose=verbose, app=app) # Log in to Heroku if we aren't already. log("Making sure that you are logged in to Heroku.") ensure_heroku_logged_in() # Change to temporary directory. cwd = os.getcwd() os.chdir(tmp) # Commit Heroku-specific files to tmp folder's git repo. cmds = [ "git init", "git add --all", 'git commit -m "Experiment ' + id + '"' ] for cmd in cmds: subprocess.call(cmd, stdout=out, shell=True) time.sleep(0.5) # Load psiTurk configuration. config = PsiturkConfig() config.load_config() # Initialize the app on Heroku. log("Initializing app on Heroku...") subprocess.call( "heroku apps:create " + id + " --buildpack https://github.com/thenovices/heroku-buildpack-scipy", stdout=out, shell=True) database_size = config.get('Database Parameters', 'database_size') try: if config.getboolean('Easter eggs', 'whimsical'): whimsical = "true" else: whimsical = "false" except: whimsical = "false" # Set up postgres database and AWS/psiTurk environment variables. cmds = [ "heroku addons:create heroku-postgresql:{}".format(database_size), "heroku pg:wait", "heroku addons:create rediscloud:250", "heroku addons:create papertrail", "heroku config:set HOST=" + id + ".herokuapp.com", "heroku config:set aws_access_key_id=" + config.get('AWS Access', 'aws_access_key_id'), "heroku config:set aws_secret_access_key=" + config.get('AWS Access', 'aws_secret_access_key'), "heroku config:set aws_region=" + config.get('AWS Access', 'aws_region'), "heroku config:set psiturk_access_key_id=" + config.get('psiTurk Access', 'psiturk_access_key_id'), "heroku config:set psiturk_secret_access_id=" + config.get('psiTurk Access', 'psiturk_secret_access_id'), "heroku config:set auto_recruit=" + config.get('Experiment Configuration', 'auto_recruit'), "heroku config:set wallace_email_username="******"heroku config:set wallace_email_key=" + config.get('Email Access', 'wallace_email_password'), "heroku config:set heroku_email_address=" + config.get('Heroku Access', 'heroku_email_address'), "heroku config:set heroku_password="******"heroku config:set whimsical=" + whimsical, ] for cmd in cmds: subprocess.call(cmd + " --app " + id, stdout=out, shell=True) # Set the notification URL in the cofig file to the notifications URL. config.set("Server Parameters", "notification_url", "http://" + id + ".herokuapp.com/notifications") # Set the database URL in the config file to the newly generated one. log("Saving the URL of the postgres database...") db_url = subprocess.check_output("heroku config:get DATABASE_URL --app " + id, shell=True) config.set("Database Parameters", "database_url", db_url.rstrip()) subprocess.call("git add config.txt", stdout=out, shell=True), time.sleep(0.25) subprocess.call('git commit -m "Save URLs for database and notifications"', stdout=out, shell=True) time.sleep(0.25) # Launch the Heroku app. log("Pushing code to Heroku...") subprocess.call("git push heroku HEAD:master", stdout=out, stderr=out, shell=True) scale_up_dynos(id) time.sleep(8) # Launch the experiment. log("Launching the experiment on MTurk...") subprocess.call('curl --data "" http://{}.herokuapp.com/launch'.format(id), shell=True) time.sleep(8) url = subprocess.check_output("heroku logs --app " + id + " | sort | " + "sed -n 's|.*URL:||p'", shell=True) log("URLs:") click.echo(url) # Return to the branch whence we came. os.chdir(cwd) log("Completed deployment of experiment " + id + ".")
import requests from psiturk.psiturk_config import PsiturkConfig from psiturk.experiment_errors import ExperimentError from psiturk.user_utils import PsiTurkAuthorization, nocache # for bonuses from amt_services import MTurkServices # # Database setup from psiturk.db import db_session, init_db from psiturk.models import Participant from json import dumps, loads # load the configuration options config = PsiturkConfig() config.load_config() myauth = PsiTurkAuthorization(config) # if you want to add a password protect route use this # explore the Blueprint custom_code = Blueprint('custom_code', __name__, template_folder='templates', static_folder='static') recaptcha_secret = <<<SECRET RECAPTCHA KEY GOES HERE>>> # for bonuses amt_services = MTurkServices( config.get('AWS Access', 'aws_access_key_id'), \ config.get('AWS Access', 'aws_secret_access_key'), config.getboolean('Shell Parameters', 'launch_in_sandbox_mode')) # for bonuses
def configure_hit(self, hit_config): ''' Configure HIT ''' # Qualification: quals = [] quals.append(dict( QualificationTypeId=PERCENT_ASSIGNMENTS_APPROVED_QUAL_ID, Comparator='GreaterThanOrEqualTo', IntegerValues=[int(hit_config['approve_requirement'])] )) quals.append(dict( QualificationTypeId=NUMBER_HITS_APPROVED_QUAL_ID, Comparator='GreaterThanOrEqualTo', IntegerValues=[int(hit_config['number_hits_approved'])] )) if hit_config['require_master_workers']: master_qualId = MASTERS_SANDBOX_QUAL_ID if self.is_sandbox else MASTERS_QUAL_ID quals.append(dict( QualificationTypeId=master_qualId, Comparator='Exists' )) if hit_config['us_only']: quals.append(dict( QualificationTypeId=LOCALE_QUAL_ID, Comparator='EqualTo', LocaleValues=[{'Country': 'US'}] )) # Create a HIT type for this HIT. hit_type = self.mtc.create_hit_type( Title=hit_config['title'], Description=hit_config['description'], Reward=str(hit_config['reward']), AssignmentDurationInSeconds=int( hit_config['duration'].total_seconds()), Keywords=hit_config['keywords'], QualificationRequirements=quals) # Check the config file to see if notifications are wanted. config = PsiturkConfig() config.load_config() try: url = config.get('Server Parameters', 'notification_url') all_event_types = [ "AssignmentAccepted", "AssignmentAbandoned", "AssignmentReturned", "AssignmentSubmitted", "HITReviewable", "HITExpired", ] # TODO: not sure if this works. Can't find documentation in PsiTurk or MTurk self.mtc.update_notification_settings( HitTypeId=hit_type['HITTypeId'], Notification=dict( Destination=url, Transport='REST', Version=NOTIFICATION_VERSION, EventTypes=all_event_types, ), ) except Exception as e: pass schema_url = "http://mechanicalturk.amazonaws.com/AWSMechanicalTurkDataSchemas/2006-07-14/ExternalQuestion.xsd" template = '<ExternalQuestion xmlns="%(schema_url)s"><ExternalURL>%%(external_url)s</ExternalURL><FrameHeight>%%(frame_height)s</FrameHeight></ExternalQuestion>' % vars() question = template % dict( external_url=hit_config['ad_location'], frame_height=600, ) # Specify all the HIT parameters self.param_dict = dict( HITTypeId=hit_type['HITTypeId'], Question=question, LifetimeInSeconds=int(hit_config['lifetime'].total_seconds()), MaxAssignments=hit_config['max_assignments'], # TODO # ResponseGroups=[ # 'Minimal', # 'HITDetail', # 'HITQuestion', # 'HITAssignmentSummary' # ] )
def debug(verbose): """Run the experiment locally.""" (id, tmp) = setup_experiment(debug=True, verbose=verbose) # Drop all the tables from the database. db.init_db(drop_all=True) # Switch to the temporary directory. cwd = os.getcwd() os.chdir(tmp) # Load psiTurk configuration. config = PsiturkConfig() config.load_config() # Set the mode to debug. config.set("Experiment Configuration", "mode", "debug") config.set("Shell Parameters", "launch_in_sandbox_mode", "true") config.set("Server Parameters", "logfile", os.path.join(cwd, config.get("Server Parameters", "logfile"))) # Swap in the HotAirRecruiter os.rename("wallace_experiment.py", "wallace_experiment_tmp.py") with open("wallace_experiment_tmp.py", "r+") as f: with open("wallace_experiment.py", "w+") as f2: f2.write("from wallace.recruiters import HotAirRecruiter\n") for idx, line in enumerate(f): if re.search("\s*self.recruiter = (.*)", line): p = line.partition("self.recruiter =") f2.write(p[0] + p[1] + ' HotAirRecruiter\n') else: f2.write(line) os.remove("wallace_experiment_tmp.py") # Set environment variables. aws_vars = ['aws_access_key_id', 'aws_secret_access_key', 'aws_region'] for var in aws_vars: if var not in os.environ: os.environ[var] = config.get('AWS Access', var) pt_vars = ['psiturk_access_key_id', 'psiturk_secret_access_id'] for var in pt_vars: if var not in os.environ: os.environ[var] = config.get('psiTurk Access', var) if "HOST" not in os.environ: os.environ["HOST"] = config.get('Server Parameters', 'host') # Start up the local server log("Starting up the server...") # Try opening the psiTurk shell. try: p = pexpect.spawn("psiturk") p.expect_exact("]$") p.sendline("server on") p.expect_exact("Experiment server launching...") # Launche the experiment. time.sleep(4) host = config.get("Server Parameters", "host") port = config.get("Server Parameters", "port") subprocess.call('curl --data "" http://{}:{}/launch'.format( host, port), shell=True) log("Here's the psiTurk shell...") p.interact() except Exception: click.echo("\nCouldn't open psiTurk shell. Internet connection okay?") log("Completed debugging of experiment " + id + ".") os.chdir(cwd)
class PsiTurkRecruiter(Recruiter): """Recruit participants from Amazon Mechanical Turk.""" def __init__(self): """Set up the connection to MTurk and psiTurk web services.""" # load the configuration options self.config = PsiturkConfig() self.config.load_config() class FakeExperimentServerController(object): def is_server_running(self): return "yes" self.server = FakeExperimentServerController() # Get keys from environment variables or config file. self.aws_access_key_id = os.getenv("aws_access_key_id", self.config.get("AWS Access", "aws_access_key_id")) self.aws_secret_access_key = os.getenv( "aws_secret_access_key", self.config.get("AWS Access", "aws_secret_access_key") ) self.aws_region = os.getenv("aws_region", self.config.get("AWS Access", "aws_region")) def open_recruitment(self, n=1): """Open recruitment for the first HIT, unless it's already open.""" from psiturk.amt_services import MTurkServices, RDSServices from psiturk.psiturk_shell import PsiturkNetworkShell from psiturk.psiturk_org_services import PsiturkOrgServices psiturk_access_key_id = os.getenv( "psiturk_access_key_id", self.config.get("psiTurk Access", "psiturk_access_key_id") ) psiturk_secret_access_id = os.getenv( "psiturk_secret_access_id", self.config.get("psiTurk Access", "psiturk_secret_access_id") ) web_services = PsiturkOrgServices(psiturk_access_key_id, psiturk_secret_access_id) aws_rds_services = RDSServices(self.aws_access_key_id, self.aws_secret_access_key, self.aws_region) self.amt_services = MTurkServices( self.aws_access_key_id, self.aws_secret_access_key, self.config.getboolean("Shell Parameters", "launch_in_sandbox_mode"), ) self.shell = PsiturkNetworkShell( self.config, self.amt_services, aws_rds_services, web_services, self.server, self.config.getboolean("Shell Parameters", "launch_in_sandbox_mode"), ) try: participants = Participant.query.all() assert participants except Exception: # Create the first HIT. self.shell.hit_create( n, self.config.get("HIT Configuration", "base_payment"), self.config.get("HIT Configuration", "duration"), ) else: # HIT was already created, no need to recreate it. print "Reject recruitment reopening: experiment has started." def recruit_participants(self, n=1): """Extend the HIT to recruit more people.""" auto_recruit = os.environ["auto_recruit"] == "true" if auto_recruit: print "Starting Wallace's recruit_participants." hit_id = str(Participant.query.with_entities(Participant.hitid).first().hitid) print "hit_id is {}.".format(hit_id) is_sandbox = self.config.getboolean("Shell Parameters", "launch_in_sandbox_mode") if is_sandbox: host = "mechanicalturk.sandbox.amazonaws.com" else: host = "mechanicalturk.amazonaws.com" mturkparams = dict( aws_access_key_id=self.aws_access_key_id, aws_secret_access_key=self.aws_secret_access_key, host=host ) self.mtc = MTurkConnection(**mturkparams) self.mtc.extend_hit(hit_id, assignments_increment=int(n or 0)) expiration_increment = self.config.get("HIT Configuration", "duration") self.mtc.extend_hit(hit_id, expiration_increment=int(float(expiration_increment or 0) * 3600)) else: print (">>>> auto_recruit set to {}: recruitment suppressed".format(auto_recruit)) def approve_hit(self, assignment_id): """Approve the HIT.""" from psiturk.amt_services import MTurkServices self.amt_services = MTurkServices( self.aws_access_key_id, self.aws_secret_access_key, self.config.getboolean("Shell Parameters", "launch_in_sandbox_mode"), ) return self.amt_services.approve_worker(assignment_id) def reward_bonus(self, assignment_id, amount, reason): """Reward the Turker with a bonus.""" from psiturk.amt_services import MTurkServices self.amt_services = MTurkServices( self.aws_access_key_id, self.aws_secret_access_key, self.config.getboolean("Shell Parameters", "launch_in_sandbox_mode"), ) return self.amt_services.bonus_worker(assignment_id, amount, reason) def close_recruitment(self): """Close recruitment.""" pass
def deploy_sandbox_shared_setup(verbose=True, web_procs=1): """Set up Git, push to Heroku, and launch the app.""" if verbose: OUT = None else: OUT = open(os.devnull, 'w') (id, tmp) = setup(debug=False, verbose=verbose) # Log in to Heroku if we aren't already. log("Making sure that you are logged in to Heroku.") ensure_heroku_logged_in() # Change to temporary directory. cwd = os.getcwd() os.chdir(tmp) # Commit Heroku-specific files to tmp folder's git repo. cmds = ["git init", "git add --all", 'git commit -m "Experiment ' + id + '"'] for cmd in cmds: subprocess.call(cmd, stdout=OUT, shell=True) time.sleep(0.5) # Load psiTurk configuration. config = PsiturkConfig() config.load_config() # Initialize the app on Heroku. log("Initializing app on Heroku...") subprocess.call( "heroku apps:create " + id + " --buildpack https://github.com/thenovices/heroku-buildpack-scipy", stdout=OUT, shell=True) database_size = config.get('Database Parameters', 'database_size') # Set up postgres database and AWS/psiTurk environment variables. cmds = [ "heroku addons:create heroku-postgresql:{}".format(database_size), "heroku pg:wait", "heroku addons:create redistogo:small", "heroku addons:create papertrail", "heroku config:set HOST=" + id + ".herokuapp.com", "heroku config:set aws_access_key_id=" + config.get('AWS Access', 'aws_access_key_id'), "heroku config:set aws_secret_access_key=" + config.get('AWS Access', 'aws_secret_access_key'), "heroku config:set aws_region=" + config.get('AWS Access', 'aws_region'), "heroku config:set psiturk_access_key_id=" + config.get('psiTurk Access', 'psiturk_access_key_id'), "heroku config:set psiturk_secret_access_id=" + config.get('psiTurk Access', 'psiturk_secret_access_id'), "heroku config:set auto_recruit=" + config.get('Experiment Configuration', 'auto_recruit'), ] for cmd in cmds: subprocess.call(cmd + " --app " + id, stdout=OUT, shell=True) # Set the notification URL in the cofig file to the notifications URL. config.set( "Server Parameters", "notification_url", "http://" + id + ".herokuapp.com/notifications") # Set the database URL in the config file to the newly generated one. log("Saving the URL of the postgres database...") db_url = subprocess.check_output( "heroku config:get DATABASE_URL --app " + id, shell=True) config.set("Database Parameters", "database_url", db_url.rstrip()) subprocess.call("git add config.txt", stdout=OUT, shell=True), time.sleep(0.25) subprocess.call( 'git commit -m "Save URLs for database and notifications"', stdout=OUT, shell=True) time.sleep(0.25) # Launch the Heroku app. log("Pushing code to Heroku...") subprocess.call("git push heroku HEAD:master", stdout=OUT, stderr=OUT, shell=True) dyno_type = config.get('Server Parameters', 'dyno_type') num_dynos_web = config.get('Server Parameters', 'num_dynos_web') num_dynos_worker = config.get('Server Parameters', 'num_dynos_worker') log("Starting up the web server...") subprocess.call("heroku ps:scale web=" + str(num_dynos_web) + ":" + str(dyno_type) + " --app " + id, stdout=OUT, shell=True) subprocess.call("heroku ps:scale worker=" + str(num_dynos_worker) + ":" + str(dyno_type) + " --app " + id, stdout=OUT, shell=True) time.sleep(8) # Launch the experiment. log("Launching the experiment on MTurk...") subprocess.call( 'curl --data "" http://{}.herokuapp.com/launch'.format(id), shell=True) time.sleep(8) url = subprocess.check_output("heroku logs --app " + id + " | sort | " + "sed -n 's|.*URL:||p'", shell=True) log("URLs:") print url # Return to the branch whence we came. os.chdir(cwd) log("Completed deployment of experiment " + id + ".")
from json import dumps from wallace import db, models import imp import inspect from operator import attrgetter import datetime from rq import Queue from worker import conn from sqlalchemy import and_, exc # Load the configuration options. config = PsiturkConfig() config.load_config() myauth = PsiTurkAuthorization(config) # Explore the Blueprint. custom_code = Blueprint( 'custom_code', __name__, template_folder='templates', static_folder='static') # Initialize the Wallace database. session = db.get_session() # Connect to the Redis queue for notifications. q = Queue(connection=conn)
class PsiTurkRecruiter(Recruiter): """Recruit participants from Amazon Mechanical Turk via PsiTurk.""" def __init__(self): """Set up the connection to MTurk and psiTurk web services.""" # load the configuration options self.config = PsiturkConfig() self.config.load_config() class FakeExperimentServerController(object): def is_server_running(self): return 'yes' self.server = FakeExperimentServerController() # Get keys from environment variables or config file. self.aws_access_key_id = os.getenv( "aws_access_key_id", self.config.get("AWS Access", "aws_access_key_id")) self.aws_secret_access_key = os.getenv( "aws_secret_access_key", self.config.get("AWS Access", "aws_secret_access_key")) self.aws_region = os.getenv( "aws_region", self.config.get("AWS Access", "aws_region")) def open_recruitment(self, n=1): """Open recruitment for the first HIT, unless it's already open.""" from psiturk.amt_services import MTurkServices, RDSServices from psiturk.psiturk_shell import PsiturkNetworkShell from psiturk.psiturk_org_services import PsiturkOrgServices psiturk_access_key_id = os.getenv( "psiturk_access_key_id", self.config.get("psiTurk Access", "psiturk_access_key_id")) psiturk_secret_access_id = os.getenv( "psiturk_secret_access_id", self.config.get("psiTurk Access", "psiturk_secret_access_id")) web_services = PsiturkOrgServices(psiturk_access_key_id, psiturk_secret_access_id) aws_rds_services = RDSServices(self.aws_access_key_id, self.aws_secret_access_key, self.aws_region) self.amt_services = MTurkServices( self.aws_access_key_id, self.aws_secret_access_key, self.config.getboolean('Shell Parameters', 'launch_in_sandbox_mode')) self.shell = PsiturkNetworkShell( self.config, self.amt_services, aws_rds_services, web_services, self.server, self.config.getboolean('Shell Parameters', 'launch_in_sandbox_mode')) try: participants = Participant.query.all() assert (participants) except Exception: # Create the first HIT. self.shell.hit_create( n, self.config.get('HIT Configuration', 'base_payment'), self.config.get('HIT Configuration', 'duration')) else: # HIT was already created, no need to recreate it. print "Reject recruitment reopening: experiment has started." def recruit_participants(self, n=1): """Recruit n participants.""" auto_recruit = os.environ['auto_recruit'] == 'true' if auto_recruit: print "Starting Dallinger's recruit_participants." hit_id = str( Participant.query.with_entities( Participant.hitid).first().hitid) print "hit_id is {}.".format(hit_id) is_sandbox = self.config.getboolean('Shell Parameters', 'launch_in_sandbox_mode') if is_sandbox: host = 'mechanicalturk.sandbox.amazonaws.com' else: host = 'mechanicalturk.amazonaws.com' mturkparams = dict( aws_access_key_id=self.aws_access_key_id, aws_secret_access_key=self.aws_secret_access_key, host=host) self.mtc = MTurkConnection(**mturkparams) self.mtc.extend_hit(hit_id, assignments_increment=int(n or 0)) expiration_increment = self.config.get('HIT Configuration', 'duration') self.mtc.extend_hit(hit_id, expiration_increment=int( float(expiration_increment or 0) * 3600)) else: print(">>>> auto_recruit set to {}: recruitment suppressed".format( auto_recruit)) def approve_hit(self, assignment_id): """Approve the HIT.""" from psiturk.amt_services import MTurkServices self.amt_services = MTurkServices( self.aws_access_key_id, self.aws_secret_access_key, self.config.getboolean('Shell Parameters', 'launch_in_sandbox_mode')) return self.amt_services.approve_worker(assignment_id) def reward_bonus(self, assignment_id, amount, reason): """Reward the Turker with a bonus.""" from psiturk.amt_services import MTurkServices self.amt_services = MTurkServices( self.aws_access_key_id, self.aws_secret_access_key, self.config.getboolean('Shell Parameters', 'launch_in_sandbox_mode')) return self.amt_services.bonus_worker(assignment_id, amount, reason) def close_recruitment(self): """Close recruitment.""" pass