Skip to content

iterators

This module contains iterators used internally by ro.py to provide paginated information.

IteratorItems

Bases: AsyncIterator

Represents the items inside of an iterator.

Source code in roblox/utilities/iterators.py
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
class IteratorItems(AsyncIterator):
    """
    Represents the items inside of an iterator.
    """

    def __init__(self, iterator: RobloxIterator, max_items: Optional[int] = None):
        self._iterator = iterator
        self._position: int = 0
        self._global_position: int = 0
        self._items: list = []
        self._max_items = max_items

    def __aiter__(self):
        self._position = 0
        self._items = []
        return self

    async def __anext__(self):
        if self._position == len(self._items):
            # we are at the end of our current page of items. start again with a new page
            self._position = 0
            try:
                # get new items
                self._items = await self._iterator.next()
            except NoMoreItems:
                # if there aren't any more items, reset and break the loop
                self._position = 0
                self._global_position = 0
                self._items = []
                raise StopAsyncIteration

        if self._max_items is not None and self._global_position >= self._max_items:
            raise StopAsyncIteration

        # if we got here we know there are more items
        try:
            item = self._items[self._position]
        except IndexError:
            # edge case for group roles
            raise StopAsyncIteration
        # we advance the iterator by one for the next iteration
        self._position += 1
        self._global_position += 1
        return item

IteratorPages

Bases: AsyncIterator

Represents the pages inside of an iterator.

Source code in roblox/utilities/iterators.py
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
class IteratorPages(AsyncIterator):
    """
    Represents the pages inside of an iterator.
    """

    def __init__(self, iterator: RobloxIterator):
        self._iterator = iterator

    def __aiter__(self):
        return self

    async def __anext__(self):
        try:
            page = await self._iterator.next()
            return page
        except NoMoreItems:
            raise StopAsyncIteration

PageIterator

Bases: RobloxIterator

Represents a cursor-based, paginated Roblox object. Learn more about iterators in the pagination tutorial: Pagination For more information about how cursor-based pagination works, see https://robloxapi.wiki/wiki/Pagination.

Attributes:

Name Type Description
_client Client

The Client.

url str

The endpoint to hit for new page data.

sort_order SortOrder

The sort order to use for returned data.

page_size int

How much data should be returned per-page.

extra_parameters dict

Extra parameters to pass to the endpoint.

handler Callable

A callable object to use to convert raw endpoint data to parsed objects.

handler_kwargs dict

Extra keyword arguments to pass to the handler.

next_cursor str

Cursor to use to advance to the next page.

previous_cursor str

Cursor to use to advance to the previous page.

iterator_position int

What position in the iterator_items the iterator is currently at.

iterator_items list

List of current items the iterator is working on.

Source code in roblox/utilities/iterators.py
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
class PageIterator(RobloxIterator):
    """
    Represents a cursor-based, paginated Roblox object. Learn more about iterators in the pagination tutorial:
    [Pagination](../../tutorials/pagination.md)
    For more information about how cursor-based pagination works, see https://robloxapi.wiki/wiki/Pagination.

    Attributes:
        _client: The Client.
        url: The endpoint to hit for new page data.
        sort_order: The sort order to use for returned data.
        page_size: How much data should be returned per-page.
        extra_parameters: Extra parameters to pass to the endpoint.
        handler: A callable object to use to convert raw endpoint data to parsed objects.
        handler_kwargs: Extra keyword arguments to pass to the handler.
        next_cursor: Cursor to use to advance to the next page.
        previous_cursor: Cursor to use to advance to the previous page.
        iterator_position: What position in the iterator_items the iterator is currently at.
        iterator_items: List of current items the iterator is working on.
    """

    def __init__(
            self,
            client: Client,
            url: str,
            sort_order: SortOrder = SortOrder.Ascending,
            page_size: int = 10,
            max_items: int = None,
            extra_parameters: Optional[dict] = None,
            handler: Optional[Callable] = None,
            handler_kwargs: Optional[dict] = None
    ):
        """
        Parameters:
            client: The Client.
            url: The endpoint to hit for new page data.
            sort_order: The sort order to use for returned data.
            page_size: How much data should be returned per-page.
            max_items: The maximum amount of items to return when this iterator is looped through.
            extra_parameters: Extra parameters to pass to the endpoint.
            handler: A callable object to use to convert raw endpoint data to parsed objects.
            handler_kwargs: Extra keyword arguments to pass to the handler.
        """
        super().__init__(max_items=max_items)

        self._client: Client = client

        # store some basic arguments in the object
        self.url: str = url
        self.sort_order: SortOrder = sort_order
        self.page_size: int = page_size

        self.extra_parameters: dict = extra_parameters or {}
        self.handler: Callable = handler
        self.handler_kwargs: dict = handler_kwargs or {}

        # cursors to use for next, previous
        self.next_cursor: str = ""
        self.previous_cursor: str = ""

        # iter values
        self.iterator_position: int = 0
        self.iterator_items: list = []
        self.next_started: bool = False

    async def next(self):
        """
        Advances the iterator to the next page.
        """
        if self.next_started and not self.next_cursor:
            """
            If we just started and there is no cursor, this is the last page, because we can go back but not forward.
            We should raise an exception here.
            """
            raise NoMoreItems("No more items.")

        if not self.next_started:
            self.next_started = True

        page_response = await self._client.requests.get(
            url=self.url,
            params={
                "cursor": self.next_cursor,
                "limit": self.page_size,
                "sortOrder": self.sort_order.value,
                **self.extra_parameters
            }
        )
        page_data = page_response.json()

        # fill in cursors
        self.next_cursor = page_data["nextPageCursor"]
        self.previous_cursor = page_data["previousPageCursor"]

        data = page_data["data"]

        if self.handler:
            data = [
                self.handler(
                    client=self._client,
                    data=item_data,
                    **self.handler_kwargs
                ) for item_data in data
            ]

        return data

__init__(client, url, sort_order=SortOrder.Ascending, page_size=10, max_items=None, extra_parameters=None, handler=None, handler_kwargs=None)

Parameters:

Name Type Description Default
client Client

The Client.

required
url str

The endpoint to hit for new page data.

required
sort_order SortOrder

The sort order to use for returned data.

Ascending
page_size int

How much data should be returned per-page.

10
max_items int

The maximum amount of items to return when this iterator is looped through.

None
extra_parameters Optional[dict]

Extra parameters to pass to the endpoint.

None
handler Optional[Callable]

A callable object to use to convert raw endpoint data to parsed objects.

None
handler_kwargs Optional[dict]

Extra keyword arguments to pass to the handler.

None
Source code in roblox/utilities/iterators.py
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
def __init__(
        self,
        client: Client,
        url: str,
        sort_order: SortOrder = SortOrder.Ascending,
        page_size: int = 10,
        max_items: int = None,
        extra_parameters: Optional[dict] = None,
        handler: Optional[Callable] = None,
        handler_kwargs: Optional[dict] = None
):
    """
    Parameters:
        client: The Client.
        url: The endpoint to hit for new page data.
        sort_order: The sort order to use for returned data.
        page_size: How much data should be returned per-page.
        max_items: The maximum amount of items to return when this iterator is looped through.
        extra_parameters: Extra parameters to pass to the endpoint.
        handler: A callable object to use to convert raw endpoint data to parsed objects.
        handler_kwargs: Extra keyword arguments to pass to the handler.
    """
    super().__init__(max_items=max_items)

    self._client: Client = client

    # store some basic arguments in the object
    self.url: str = url
    self.sort_order: SortOrder = sort_order
    self.page_size: int = page_size

    self.extra_parameters: dict = extra_parameters or {}
    self.handler: Callable = handler
    self.handler_kwargs: dict = handler_kwargs or {}

    # cursors to use for next, previous
    self.next_cursor: str = ""
    self.previous_cursor: str = ""

    # iter values
    self.iterator_position: int = 0
    self.iterator_items: list = []
    self.next_started: bool = False

next() async

Advances the iterator to the next page.

Source code in roblox/utilities/iterators.py
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
async def next(self):
    """
    Advances the iterator to the next page.
    """
    if self.next_started and not self.next_cursor:
        """
        If we just started and there is no cursor, this is the last page, because we can go back but not forward.
        We should raise an exception here.
        """
        raise NoMoreItems("No more items.")

    if not self.next_started:
        self.next_started = True

    page_response = await self._client.requests.get(
        url=self.url,
        params={
            "cursor": self.next_cursor,
            "limit": self.page_size,
            "sortOrder": self.sort_order.value,
            **self.extra_parameters
        }
    )
    page_data = page_response.json()

    # fill in cursors
    self.next_cursor = page_data["nextPageCursor"]
    self.previous_cursor = page_data["previousPageCursor"]

    data = page_data["data"]

    if self.handler:
        data = [
            self.handler(
                client=self._client,
                data=item_data,
                **self.handler_kwargs
            ) for item_data in data
        ]

    return data

PageNumberIterator

Bases: RobloxIterator

Represents an iterator that is advanced with page numbers and sizes, like those seen on chat.roblox.com.

Attributes:

Name Type Description
url str

The endpoint to hit for new page data.

page_number int

The current page number.

page_size int

The size of each page.

extra_parameters dict

Extra parameters to pass to the endpoint.

handler Callable

A callable object to use to convert raw endpoint data to parsed objects.

handler_kwargs dict

Extra keyword arguments to pass to the handler.

Source code in roblox/utilities/iterators.py
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
class PageNumberIterator(RobloxIterator):
    """
    Represents an iterator that is advanced with page numbers and sizes, like those seen on chat.roblox.com.

    Attributes:
        url: The endpoint to hit for new page data.
        page_number: The current page number.
        page_size: The size of each page.
        extra_parameters: Extra parameters to pass to the endpoint.
        handler: A callable object to use to convert raw endpoint data to parsed objects.
        handler_kwargs: Extra keyword arguments to pass to the handler.
    """

    def __init__(
            self,
            client: Client,
            url: str,
            page_size: int = 10,
            extra_parameters: Optional[dict] = None,
            handler: Optional[Callable] = None,
            handler_kwargs: Optional[dict] = None
    ):
        super().__init__()

        self._client: Client = client

        self.url: str = url
        self.page_number: int = 1
        self.page_size: int = page_size

        self.extra_parameters: dict = extra_parameters or {}
        self.handler: Callable = handler
        self.handler_kwargs: dict = handler_kwargs or {}

        self.iterator_position = 0
        self.iterator_items = []

    async def next(self):
        """
        Advances the iterator to the next page.
        """
        page_response = await self._client.requests.get(
            url=self.url,
            params={
                "pageNumber": self.page_number,
                "pageSize": self.page_size,
                **self.extra_parameters
            }
        )
        data = page_response.json()

        if len(data) == 0:
            raise NoMoreItems("No more items.")

        self.page_number += 1

        if self.handler:
            data = [
                self.handler(
                    client=self._client,
                    data=item_data,
                    **self.handler_kwargs
                ) for item_data in data
            ]

        return data

next() async

Advances the iterator to the next page.

Source code in roblox/utilities/iterators.py
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
async def next(self):
    """
    Advances the iterator to the next page.
    """
    page_response = await self._client.requests.get(
        url=self.url,
        params={
            "pageNumber": self.page_number,
            "pageSize": self.page_size,
            **self.extra_parameters
        }
    )
    data = page_response.json()

    if len(data) == 0:
        raise NoMoreItems("No more items.")

    self.page_number += 1

    if self.handler:
        data = [
            self.handler(
                client=self._client,
                data=item_data,
                **self.handler_kwargs
            ) for item_data in data
        ]

    return data

RobloxIterator

Represents a basic iterator which all iterators should implement.

Source code in roblox/utilities/iterators.py
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
class RobloxIterator:
    """
    Represents a basic iterator which all iterators should implement.
    """

    def __init__(self, max_items: int = None):
        self.max_items: Optional[int] = max_items

    async def next(self):
        """
        Moves to the next page and returns that page's data.
        """

        raise NotImplementedError

    async def flatten(self, max_items: int = None) -> list:
        """
        Flattens the data into a list.
        """
        if max_items is None:
            max_items = self.max_items

        items: list = []

        while True:
            try:
                new_items = await self.next()
                items += new_items
            except NoMoreItems:
                break

            if max_items is not None and len(items) >= max_items:
                break

        return items[:max_items]

    def __aiter__(self):
        return IteratorItems(
            iterator=self,
            max_items=self.max_items
        )

    def items(self, max_items: int = None) -> IteratorItems:
        """
        Returns an AsyncIterable containing each iterator item.
        """
        if max_items is None:
            max_items = self.max_items
        return IteratorItems(
            iterator=self,
            max_items=max_items
        )

    def pages(self) -> IteratorPages:
        """
        Returns an AsyncIterable containing each iterator page. Each page is a list of items.
        """
        return IteratorPages(self)

flatten(max_items=None) async

Flattens the data into a list.

Source code in roblox/utilities/iterators.py
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
async def flatten(self, max_items: int = None) -> list:
    """
    Flattens the data into a list.
    """
    if max_items is None:
        max_items = self.max_items

    items: list = []

    while True:
        try:
            new_items = await self.next()
            items += new_items
        except NoMoreItems:
            break

        if max_items is not None and len(items) >= max_items:
            break

    return items[:max_items]

items(max_items=None)

Returns an AsyncIterable containing each iterator item.

Source code in roblox/utilities/iterators.py
135
136
137
138
139
140
141
142
143
144
def items(self, max_items: int = None) -> IteratorItems:
    """
    Returns an AsyncIterable containing each iterator item.
    """
    if max_items is None:
        max_items = self.max_items
    return IteratorItems(
        iterator=self,
        max_items=max_items
    )

next() async

Moves to the next page and returns that page's data.

Source code in roblox/utilities/iterators.py
101
102
103
104
105
106
async def next(self):
    """
    Moves to the next page and returns that page's data.
    """

    raise NotImplementedError

pages()

Returns an AsyncIterable containing each iterator page. Each page is a list of items.

Source code in roblox/utilities/iterators.py
146
147
148
149
150
def pages(self) -> IteratorPages:
    """
    Returns an AsyncIterable containing each iterator page. Each page is a list of items.
    """
    return IteratorPages(self)

SortOrder

Bases: Enum

Order in which page data should load in.

Source code in roblox/utilities/iterators.py
19
20
21
22
23
24
25
class SortOrder(Enum):
    """
    Order in which page data should load in.
    """

    Ascending = "Asc"
    Descending = "Desc"