def _load_or_fetch(self, persist_path, *args, return_parsed=True, **kwargs): """ A shortcut to try loading from persistence but fetching if we miss Args: persist_path (str): A path to look for in persistence return_parsed (bool): Whether to return the parsed XML. Raw data is persisted *args/**kwargs: Arguments to pass to make_request if we need to """ value = self._load(persist_path, default=None) persistence_miss = value is None if persistence_miss: logger.debug("Missed on persitence for {}, " "fetching from API".format(persist_path)) value = self.make_request(*args, **kwargs) else: logger.debug("Using persisted value for {}".format(persist_path)) try: out = parse_response(value) if return_parsed else value except Exception: logger.warn("Error parsing XML response") logger.warn(f"Response body: {value}") raise # Save here so we make sure it was parseable - prevents saving error data if persistence_miss: self._save(persist_path, value) return out
def load(load_path, default=_DEFAULT_SINGLETON, ttl=DEFAULT_TTL, persist_key=""): """ Load an object from a key path in persistence Args: load_path (str): A pydash path to where the data is stored in persistence persist_key (str): A unique identifier for the persistence file """ if CURRENT_PERSISTENCE: persisted_data = CURRENT_PERSISTENCE else: filename = get_persistence_filename(persist_key) if not isfile(filename): persisted_data = {} else: with open(filename, 'rb') as fp: persisted_data = pickle.load(fp) CURRENT_PERSISTENCE.clear() CURRENT_PERSISTENCE.update(persisted_data) time_saved = get(persisted_data, load_path + '__time', 0) if ttl >= 0 and time_saved + ttl < time(): logger.debug("Persistence data expired, ignoring") out = default else: out = get(persisted_data, load_path, default) if out is _DEFAULT_SINGLETON: raise ValueError("Path {} not found in persistence".format(load_path)) return out
def teams(self, persist_ttl=DEFAULT_TTL): logger.debug("Looking up teams") data = self.ctx._load_or_fetch('teams.' + self.id, 'teams', league=self.id) teams = [] for team in data['fantasy_content']['league']['teams']['team']: t = Team(self.ctx, self, get_value(team['team_key'])) from_response_object(t, team) teams.append(t) return teams
def weeks(self, persist_ttl=DEFAULT_TTL): if not self.start_week or not self.end_week: raise AttributeError( "Can't fetch weeks for a league without start/end weeks. Is it a " "head-to-head league? Did you sync your league already?") logger.debug("Looking up weeks") out = [] for week_num in range(self.start_week, self.end_week + 1): week = Week(self.ctx, self, week_num) week.sync() out.append(week) return out
def standings(self, persist_ttl=DEFAULT_TTL): logger.debug("Looking up standings") data = self.ctx._load_or_fetch('standings.' + self.id, 'standings', league=self.id) standings = [] for team in data['fantasy_content']['league']['standings']['teams'][ 'team']: standing = Standings(self.ctx, self, get_value(team['team_key'])) from_response_object(standing, team) standings.append(standing) return standings
def players(self, persist_ttl=DEFAULT_TTL): logger.debug("Looking up current players on team") data = self.ctx._load_or_fetch( f"team.{self.id}.players", f"team/{self.id}/players", ) players = [] for p in data['fantasy_content']['team']['players']['player']: player = Player(self.league) player = from_response_object(player, p) players.append(player) return players
def make_request(url, token, league=False, **kwargs): if league: url = "league/{}/{}".format(league, url) logger.debug("Making request to {}".format(url)) resp = requests.get("{}/{}".format(YURL, url), headers={ "Authorization": "Bearer {}".format(token), "User-Agent": "Mozilla/5.0", }) try: resp.raise_for_status() except Exception: logger.exception("Bad response status ({}) for request".format( resp.status_code)) raise return resp.text