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
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
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)
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()