def test_nested_get(): baz = 1 bar = {'baz': baz} foo = {'bar': bar} data = {'foo': foo} assert nested_get(data, []) == data assert nested_get(data, ['foo']) == foo assert nested_get(data, ['foo', 'bar']) == bar assert nested_get(data, ['foo', 'bar', 'baz']) == baz assert nested_get({}, ['foo', 'bar'], default=None) is None pytest.raises(KeyError, nested_get, {}, ['foo'])
def _request(self, http_method, method, unwrap=None, collection_key=None, **kwargs): """ Make a LastFM API request, returning the parsed JSON from the response. """ http_method = http_method.upper() request_args = self._request_args(http_method, method, kwargs) try: resp = self._session.request(http_method, self.api_info.url, **request_args) resp.raise_for_status() except requests.exceptions.HTTPError as exc: six.raise_from( error.ApiError(exc.response.status_code, exc.response.reason), exc) except requests.exceptions.RequestException as exc: newexc = error.LastfmError('Request error: {0}'.format(exc)) six.raise_from(newexc, exc) result = resp.json() if ERROR in result: raise error.APIError(result[ERROR], result[MESSAGE]) unwrapped = result[unwrap] if unwrap else result if collection_key is None: return unwrapped coll_keys = collection_key.split('.') return _list_response(nested_get(unwrapped, coll_keys))
def _paginate_request(self, http_method, method, collection_key, perpage=None, limit=None, params=None, paginate_attr_class=None, **kwargs): if paginate_attr_class is None: paginate_attr_class = PaginateMixin if perpage is None: perpage = DEFAULT_PERPAGE if params is None: params = {} params.update(limit=perpage) resp = self._request(http_method, method, params=params, **kwargs) coll_keys = collection_key.split('.') if not nested_in(resp, coll_keys) and resp.get('total') == '0': nested_set(resp, coll_keys, PaginatedIterator(0, 0, iter([]))) return resp attributes = paginate_attr_class(resp) if limit and limit < attributes.total: n_pages = min(attributes.total_pages, ceildiv(limit, perpage)) pagerange = six.moves.range(2, n_pages + 1) else: pagerange = six.moves.range(2, attributes.total_pages + 1) def pagequery(page, http_method=http_method, method=method, collection_key=collection_key, params=params, kwargs=kwargs): params['page'] = page return self._request(http_method, method, params=params, collection_key=collection_key, **kwargs) thispage = _list_response(nested_get(resp, coll_keys)) remaining_pages = chain.from_iterable(pagequery(page) for page in pagerange) iterator = chain(thispage, remaining_pages) nested_set(resp, coll_keys, PaginatedIterator(attributes.total_pages, attributes.total, iterator)) return resp