Source code for clashroyale.royaleapi.models

from box import Box, BoxList

from .utils import API

API_ENDPOINTS = API('https://api.royaleapi.com')

__all__ = [
    'BaseAttrDict', 'Refreshable', 'PartialTournament',
    'PartialClan', 'PartialPlayer', 'PartialPlayerClan',
    'Member', 'FullPlayer', 'FullClan', 'rlist'
]


[docs]class BaseAttrDict: """This class is the base class for all models, its a wrapper around the `python-box`_ which allows access to data via dot notation, in this case, API data will be accessed using this class. This class shouldnt normally be used by the user since its a base class for the actual models returned from the client. .. _python-box: https://github.com/cdgriffith/Box Example ------- Accessing data via dot notation: .. code-block:: python sample_data = { "stats": { "maxTrophies": 5724, "favoriteCard": { "name": "P.E.K.K.A" } } } model = SomeModel(client, sample_data) x = sample_data['stats']['maxTrophies'] # Same as x = model['stats']['max_trophies'] # Same as x = model.stats.max_trophies This functionality allows this library to present API data in a clean dynamic way. Attributes ---------- raw_data: dict The raw data in the form of a dictionary being used cached: bool Whether or not the data being used is cached data from the cache database. last_updated: datetime.datetime When the data which is currently being used was last updated. response: requests.Response or aiohttp.ClientResponse or None Response object containing headers and more information. Returns None if cached """ def __init__(self, client, data, response, cached=False, ts=None): self.client = client self.response = response self.from_data(data, cached, ts, response) def from_data(self, data, cached, ts, response): self.cached = cached self.last_updated = ts self.raw_data = data self.response = response if isinstance(data, list): self._boxed_data = BoxList( data, camel_killer_box=not self.client.camel_case ) else: self._boxed_data = Box( data, camel_killer_box=not self.client.camel_case ) return self def __getattr__(self, attr): try: return getattr(self._boxed_data, attr) except AttributeError: try: return super().__getattr__(attr) except AttributeError: return None def __getitem__(self, item): try: return getattr(self._boxed_data, item) except AttributeError: raise KeyError('No such key: {}'.format(item)) def __repr__(self): _type = self.__class__.__name__ return "<{}: {}>".format(_type, self.raw_data)
[docs]class Refreshable(BaseAttrDict): """Mixin class for re requesting data from the api for the specific model. """
[docs] def refresh(self): """(a)sync refresh the data.""" if self.client.is_async: return self._arefresh() data, cached, ts, response = self.client.request(self.url, timeout=None, refresh=True) return self.from_data(data, cached, ts, response)
async def _arefresh(self): data, cached, ts, response = await self.client.request(self.url, timeout=None, refresh=True) return self.from_data(data, cached, ts, response) @property def url(self): endpoint = self.__class__.__name__.lower() return '{}/{}/{}'.format(API_ENDPOINTS.BASE, endpoint, self.tag)
[docs]class PartialTournament(BaseAttrDict): def get_tournament(self): return self.client.get_player(self.tag)
[docs]class PartialClan(BaseAttrDict):
[docs] def get_clan(self): """(a)sync function to return clan.""" try: return self.client.get_clan(self.clan.tag) except AttributeError: try: return self.client.get_clan(self.tag) except AttributeError: raise ValueError('This player does not have a clan.')
[docs]class PartialPlayer(BaseAttrDict):
[docs] def get_player(self): """(a)sync function to return player.""" return self.client.get_player(self.tag)
[docs]class PartialPlayerClan(PartialClan, PartialPlayer): """Brief player model, does not contain full data, non refreshable. """ pass
[docs]class Member(PartialPlayer): """A clan member model, keeps a reference to the clan object it came from. """ def __init__(self, clan, data, response): self.clan = clan super().__init__(clan.client, data, response)
[docs]class FullPlayer(Refreshable, PartialClan): """A clash royale player model.""" pass
[docs]class FullClan(Refreshable): """A clash royale clan model, full data + refreshable.""" def from_data(self, data, cached, ts, response): super().from_data(data, cached, ts, response) self.members = [Member(self, m, self.response) for m in data.get('members', [])]
[docs]class rlist(list, Refreshable): def __init__(self, client, data, cached, ts, response): self.client = client self.from_data(data, cached, ts, response) def from_data(self, data, cached, ts, response): self.cached = cached self.last_updated = ts self.response = response super().__init__(data) return self @property def url(self): return '{}/endpoints'.format(API_ENDPOINTS.BASE)