Ejemplo n.º 1
0
    def get_info(self):
        """Return information about this simulator

        If the id is unknown this will search all simulators for one with the
        same name and optionally version. If version is unspecified, but only
        one simulator with that name exists, this lookup should still succeed.
        This returns a new simulator object, but will update the id of the
        current simulator if it was undefined."""
        if 'id' in self:
            resp = self._api._request(
                'get', 'simulators/{sim:d}.json'.format(sim=self.id))
            resp.raise_for_status()
            result = self._api.simulator(resp.json())
            self['id'] = result.id

        elif 'version' in self:
            result = utils.only(
                sim for sim in self._api.get_simulators()
                if sim.name == self.name
                and sim.version == self.version)

        else:
            result = utils.only(
                sim for sim in self._api.get_simulators()
                if sim.name == self.name)

        return result
Ejemplo n.º 2
0
    def get_info(self, verbose=False):
        """Get a scheduler information

        If `id` is specified then this is really efficient, and works for all
        scheduler. Otherwise `nam` may be specified, but only generic
        schedulers will be found."""

        if 'id' in self:
            data = {'granularity': 'with_requirements'} if verbose else {}
            resp = self._api._request(
                'get',
                'schedulers/{sched_id}.json'.format(sched_id=self.id),
                data)
            resp.raise_for_status()
            result = self._api.scheduler(resp.json())
            if verbose:
                result['scheduling_requirements'] = [
                    self.profile(prof, id=prof['profile_id']) for prof
                    in result.get('scheduling_requirements', None) or ()]

        else:
            result = utils.only(
                sched for sched in self._api.get_generic_schedulers()
                if sched.name == self.name)
            self['id'] = result.id
            if verbose:
                result = self.get_info(verbose=True)

        return result
Ejemplo n.º 3
0
    def get_info(self, granularity='structure'):
        """Gets game information from EGTA Online

        granularity can be one of:

        structure    - returns the game information but no profile information.
                       (default)
        summary      - returns the game information and profiles with
                       aggregated payoffs.
        observations - returns the game information and profiles with data
                       aggregated at the observation level.
        full         - returns the game information and profiles with complete
                       observation information
        """
        if 'id' in self:
            # This call breaks convention because the api is broken, so we use
            # a different api.
            resp = self._api._non_api_request(
                'get',
                'games/{gid:d}.json'.format(gid=self.id),
                data={'granularity': granularity})
            resp.raise_for_status()
            if granularity == 'structure':
                result = json.loads(resp.json())
            else:
                result = resp.json()
                result['profiles'] = [
                    Profile(p, api=self._api) for p
                    in result['profiles'] or ()]

        else:
            result = utils.only(g for g in self._api.get_games()
                                if g.name == self.name)
            self['id'] = result.id
            if granularity != 'structure':
                result = self.get_info(granularity=granularity)

        return Game(result, api=self._api)
Ejemplo n.º 4
0
def main():
    """Main function, declared so it doesn't have global scope"""
    # Parse arguments
    args = _parser.parse_args()
    if args.auth_string is None:
        if path.isfile(args.auth_file):
            with open(args.auth_file) as auth_file:
                args.auth_string = auth_file.read().strip()
        else:
            sys.stderr.write(textwrap.fill((
                'This script needs an authorization token to access EGTA '
                'Online. By default, this script looks for file with your '
                'authorization token at "{}". See `egta --help` for other '
                'ways to specify your authorization '
                'token.').format(_def_auth)))
            sys.stderr.write('\n')
            sys.exit(1)

    # Create logger
    log = logging.getLogger(__name__)
    log.setLevel(max(40 - args.verbose * 10, 1))  # 0 is no logging
    handler = logging.StreamHandler(sys.stderr)
    handler.setFormatter(logging.Formatter(
        '%(asctime)s ({gid:d}) %(message)s'.format(gid=args.game)))
    log.addHandler(handler)

    # Email Logging
    if args.recipient:
        email_subject = 'EGTA Online Quiesce Status for Game {gid:d}'.format(
            gid=args.game)
        smtp_host = 'localhost'

        # We need to do this to match the from address to the local host name
        # otherwise, email logging will not work. This seems to vary somewhat
        # by machine
        server = smtplib.SMTP(smtp_host)
        smtp_fromaddr = 'EGTA Online <egta_online@{host}>'.format(
            host=server.local_hostname)
        server.quit()  # dummy server is now useless

        email_handler = handlers.SMTPHandler(smtp_host, smtp_fromaddr,
                                             args.recipient, email_subject)
        email_handler.setLevel(40 - args.email_verbosity * 10)
        log.addHandler(email_handler)

    # Fetch info from egta online
    egta_api = api.EgtaOnline(args.auth_string,
                              logLevel=(0 if args.verbose < 5 else 3))
    gamej = egta_api.game(id=args.game).get_info('summary')
    try:
        game, serial = gameio.read_base_game(gamej)
    except TypeError as e:
        log.error('Caught exception trying to read the initial game, this is '
                  'most likely caused by a game without roles specified: (%s) '
                  '%s\nWith traceback:\n%s\n',
                  e.__class__.__name__, e, traceback.format_exc())
        raise e
    sim = utils.only(s for s in egta_api.get_simulators()
                     if '{name}-{version}'.format(**s)
                     == gamej.simulator_fullname)

    if args.dpr is not None:
        args.dpr = serial.from_role_json(
            dict(zip(args.dpr[::2], map(int, args.dpr[1::2]))))

    try:
        quiesce(sim, game, serial, gamej.name, dict(gamej.configuration),
                args.dpr, log, profiles=gamej.profiles, all_devs=not
                args.role_devs, max_profiles=args.max_profiles,
                max_subgame_size=args.max_subgame_size,
                sleep_time=args.sleep_time,
                required_equilibria=args.num_equilibria,
                regret_thresh=args.regret_threshold, reschedule_limit=10,
                process_memory=args.memory,
                observation_time=args.observation_time,
                observation_increment=args.observation_increment,
                nodes=args.nodes)

    except Exception as e:
        # Other exception, notify, but don't deactivate
        log.error('Caught exception: (%s) %s\nWith traceback:\n%s\n',
                  e.__class__.__name__, e, traceback.format_exc())
        raise e

    finally:
        # Make sure to clean up
        egta_api.close()