Esempio n. 1
0
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()
Esempio n. 2
0
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)
Esempio n. 3
0
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)
Esempio n. 4
0
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
Esempio n. 5
0
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 + ".")
Esempio n. 6
0
    shutil.copy(src, os.path.join(dst, "custom.py"))

    heroku_files = [
        "Procfile",
        "requirements.txt",
        "psiturkapp.py",
        "worker.py",
        "clock.py",
    ]

    for filename in heroku_files:
        src = os.path.join(os.path.dirname(os.path.realpath(__file__)),
                           "heroku", filename)
        shutil.copy(src, os.path.join(dst, filename))

    clock_on = config.getboolean('Server Parameters', 'clock_on')

    # If the clock process has been disabled, overwrite the Procfile.
    if not clock_on:
        src = os.path.join(os.path.dirname(os.path.realpath(__file__)),
                           "heroku", "Procfile_no_clock")
        shutil.copy(src, os.path.join(dst, "Procfile"))

    frontend_files = [
        "static/css/wallace.css", "static/scripts/wallace.js",
        "static/scripts/reqwest.min.js", "templates/error_wallace.html",
        "templates/launch.html", "templates/complete.html", "static/robots.txt"
    ]

    for filename in frontend_files:
        src = os.path.join(os.path.dirname(os.path.realpath(__file__)),
Esempio n. 7
0
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
Esempio n. 8
0
def deploy_sandbox_shared_setup(verbose=True, app=None, 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_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 + ".")
Esempio n. 9
0
    heroku_files = [
        "Procfile",
        "requirements.txt",
        "psiturkapp.py",
        "worker.py",
        "clock.py",
    ]

    for filename in heroku_files:
        src = os.path.join(
            os.path.dirname(os.path.realpath(__file__)),
            "heroku",
            filename)
        shutil.copy(src, os.path.join(dst, filename))

    clock_on = config.getboolean('Server Parameters', 'clock_on')

    # If the clock process has been disabled, overwrite the Procfile.
    if not clock_on:
        src = os.path.join(
            os.path.dirname(os.path.realpath(__file__)),
            "heroku",
            "Procfile_no_clock")
        shutil.copy(src, os.path.join(dst, "Procfile"))

    frontend_files = [
        "static/css/wallace.css",
        "static/scripts/wallace.js",
        "static/scripts/reqwest.min.js",
        "templates/error_wallace.html",
        "templates/launch.html",
Esempio n. 10
0
# 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
class WorkerAlreadyCredited(Exception):
    pass

class CreditTransactionError(Exception):
    pass

class WorkerNotRegistered(Exception):
    pass

class NoAMTConnection(Exception):
    pass

def yield_participants(condition):