Source code for mygeotab.ext.entitylist

# -*- coding: utf-8 -*-

from collections import UserList
from mygeotab import api


[docs] class API(api.API): """An experimental wrapper around the base MyGeotab API class that adds some helper methods to results when retrieving results with `get()`. """
[docs] def get(self, type_name, **parameters): """Gets entities using the API. Shortcut for using call() with the 'Get' method. This returns an EntityList with added convience methods. :param type_name: The type of entity. :type type_name: str :param parameters: Additional parameters to send. :raise MyGeotabException: Raises when an exception occurs on the MyGeotab server. :raise TimeoutException: Raises when the request does not respond after some time. :return: The results from the server. :rtype: EntityList """ return EntityList(super().get(type_name, **parameters), type_name=type_name)
[docs] class EntityList(UserList): """The customized result list"""
[docs] def __init__(self, data, type_name): """Gets entities using the API. Shortcut for using call() with the 'Get' method. :param data: The list of result data. :type data: list :param type_name: The type of entity. :type type_name: str """ super(EntityList, self).__init__(data) self.type_name = type_name
def _repr_pretty_(self, p, cycle): """The pretty printer for IPython""" if cycle: p.text("{}(...)".format(self.type_name)) else: with p.group(8, "{}([".format(self.type_name), "])"): for idx, item in enumerate(self.data): if idx: p.text(",") p.breakable() p.pretty(item) def __getitem__(self, i): if isinstance(i, slice): return self.__class__(self.data[i], self.type_name) else: return self.data[i] def __getslice__(self, i, j): i = max(i, 0) j = max(j, 0) return self.__class__(self.data[i:j], self.type_name) def __add__(self, other): if isinstance(other, UserList): return self.__class__(self.data + other.data, self.type_name) elif isinstance(other, type(self.data)): return self.__class__(self.data + other, self.type_name) return self.__class__(self.data + list(other), self.type_name) def __radd__(self, other): if isinstance(other, UserList): return self.__class__(other.data + self.data, self.type_name) elif isinstance(other, type(self.data)): return self.__class__(other + self.data, self.type_name) return self.__class__(list(other) + self.data, self.type_name) def __mul__(self, n): return self.__class__(self.data * n, self.type_name) __rmul__ = __mul__ def __copy__(self): inst = self.__class__.__new__(self.__class__, self.type_name) inst.__dict__.update(self.__dict__) # Create a copy and avoid triggering descriptors inst.__dict__["data"] = self.__dict__["data"][:] return inst
[docs] def sort_by(self, key, reverse=False): """Returns an EntityList, sorted by a provided key. :param key: The key to sort the data with. :type key: str :param reverse: If true, reverse the sort direction. :type reverse: bool :rtype: EntityList """ def sort_by_key(entity): prop = entity[key] if isinstance(prop, str): return prop.lower() return prop return self.__class__(sorted(self.data, key=sort_by_key, reverse=reverse), type_name=self.type_name)
@property def first(self): """Gets the first entity in the list, if it exists. :rtype: dict """ return self.data[0] if self.data else None @property def last(self): """Gets the last entity in the list, if it exists. :rtype: dict """ return self.data[-1] if self.data else None @property def entity(self): """Like `first`, but first asserts that there is only one entity in the results list. :rtype: dict """ data_length = len(self.data) assert data_length == 1, "Expecting one entity, but {} entities were returned".format(data_length) return self.first
[docs] def to_dataframe(self, normalize=False): """Transforms the data into a pandas DataFrame :param normalize: Whether or not to normalize any nested objects in the results into distinct columns. :type normalize: bool :rtype: pandas.DataFrame """ try: import pandas except ImportError as exc: raise ImportError("The 'pandas' package could not be imported") from exc if normalize: try: return pandas.json_normalize(self.data) except AttributeError: from pandas.io.json import json_normalize return json_normalize(self.data) return pandas.DataFrame.from_dict(self.data)