def search_rect(self, rect: Rectangle, *, per_query: int = 200, sort_by: Union[str, SortOrder] = SortOrder.date_last_visited, origin: Optional[Point] = None, wait_sleep: bool = True): """ Return a generator of caches in given Rectange area. :param rect: Search area. :param int per_query: Number of caches requested in single query. :param sort_by: Order cached by given criterion. :param origin: Origin point for search by distance. :param wait_sleep: In case of rate limits exceeding, wait appropriate time if set True, otherwise just yield None. """ if not isinstance(sort_by, SortOrder): sort_by = SortOrder(sort_by) params = { "box": "{},{},{},{}".format( rect.corners[0].latitude, rect.corners[0].longitude, rect.corners[1].latitude, rect.corners[1].longitude, ), "take": per_query, "asc": "true", "skip": 0, "sort": sort_by.value, } if sort_by is SortOrder.distance: assert isinstance(origin, Point) params["origin"] = "{},{}".format(origin.latitude, origin.longitude) total, offset = None, 0 while (total is None) or (offset < total): params["skip"] = offset try: resp = self._request(self._urls["api_search"], params=params, expect="json") except TooManyRequestsError as e: if wait_sleep: e.wait_for() else: yield None continue for record in resp["results"]: yield Cache._from_api_record(self, record) total = resp["total"] offset += per_query