Skip to content

Iterator

Iterator classes for working with paginated API responses.

BlockList

Bases: ObjectList

A list of Block objects returned by the Notion API.

Source code in src/notional/iterator.py
50
51
52
53
class BlockList(ObjectList, type="block"):
    """A list of Block objects returned by the Notion API."""

    block: Any = {}

DatabaseList

Bases: ObjectList

A list of Database objects returned by the Notion API.

Source code in src/notional/iterator.py
62
63
64
65
class DatabaseList(ObjectList, type="database"):
    """A list of Database objects returned by the Notion API."""

    database: Any = {}

EndpointIterator

Iterates over results from a paginated API response.

These objects may be reused, however they are not thread safe. For example, after creating the following iterator:

notion = notional.connect(auth=NOTION_AUTH_TOKEN)
query = EndpointIterator(notion.databases().query)

The iterator may be reused with different database ID's:

for items in query(database_id=first_db):
    ...

for items in query(database_id=second_db):
    ...

Objects returned by the iterator may also be converted to a specific type. This is most commonly used to wrap API objects with a higher-level object (such as ORM types).

Source code in src/notional/iterator.py
 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
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
class EndpointIterator:
    """Iterates over results from a paginated API response.

    These objects may be reused, however they are not thread safe.  For example,
    after creating the following iterator:

        notion = notional.connect(auth=NOTION_AUTH_TOKEN)
        query = EndpointIterator(notion.databases().query)

    The iterator may be reused with different database ID's:

        for items in query(database_id=first_db):
            ...

        for items in query(database_id=second_db):
            ...

    Objects returned by the iterator may also be converted to a specific type.  This
    is most commonly used to wrap API objects with a higher-level object (such as ORM
    types).
    """

    def __init__(self, endpoint, datatype=None):
        """Initialize an object list iterator for the specified endpoint.

        If a class is provided, it will be constructued for each result returned by
        this iterator.  The constructor must accept a single argument, which is the
        `NotionObject` contained in the `ObjectList`.
        """
        self._endpoint = endpoint
        self._datatype = datatype

        self.has_more = None
        self.page_num = -1
        self.total_items = -1
        self.next_cursor = None

    def __call__(self, **kwargs):
        """Return a generator for this endpoint using the given parameters."""

        self.has_more = True
        self.page_num = 0
        self.total_items = 0

        if "page_size" not in kwargs:
            kwargs["page_size"] = MAX_PAGE_SIZE

        self.next_cursor = kwargs.pop("start_cursor", None)

        while self.has_more:
            self.page_num += 1

            page = self._endpoint(start_cursor=self.next_cursor, **kwargs)

            api_list = ObjectList.parse_obj(page)

            for obj in api_list.results:
                self.total_items += 1

                if self._datatype is None:
                    yield obj
                else:
                    yield self._datatype(obj)

            self.next_cursor = api_list.next_cursor
            self.has_more = api_list.has_more and self.next_cursor is not None

    def list(self, **kwargs):
        """Collect all items from the endpoint as a list."""

        items = []

        for item in self(**kwargs):
            items.append(item)

        return items

__call__(**kwargs)

Return a generator for this endpoint using the given parameters.

Source code in src/notional/iterator.py
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
def __call__(self, **kwargs):
    """Return a generator for this endpoint using the given parameters."""

    self.has_more = True
    self.page_num = 0
    self.total_items = 0

    if "page_size" not in kwargs:
        kwargs["page_size"] = MAX_PAGE_SIZE

    self.next_cursor = kwargs.pop("start_cursor", None)

    while self.has_more:
        self.page_num += 1

        page = self._endpoint(start_cursor=self.next_cursor, **kwargs)

        api_list = ObjectList.parse_obj(page)

        for obj in api_list.results:
            self.total_items += 1

            if self._datatype is None:
                yield obj
            else:
                yield self._datatype(obj)

        self.next_cursor = api_list.next_cursor
        self.has_more = api_list.has_more and self.next_cursor is not None

__init__(endpoint, datatype=None)

Initialize an object list iterator for the specified endpoint.

If a class is provided, it will be constructued for each result returned by this iterator. The constructor must accept a single argument, which is the NotionObject contained in the ObjectList.

Source code in src/notional/iterator.py
117
118
119
120
121
122
123
124
125
126
127
128
129
130
def __init__(self, endpoint, datatype=None):
    """Initialize an object list iterator for the specified endpoint.

    If a class is provided, it will be constructued for each result returned by
    this iterator.  The constructor must accept a single argument, which is the
    `NotionObject` contained in the `ObjectList`.
    """
    self._endpoint = endpoint
    self._datatype = datatype

    self.has_more = None
    self.page_num = -1
    self.total_items = -1
    self.next_cursor = None

list(**kwargs)

Collect all items from the endpoint as a list.

Source code in src/notional/iterator.py
162
163
164
165
166
167
168
169
170
def list(self, **kwargs):
    """Collect all items from the endpoint as a list."""

    items = []

    for item in self(**kwargs):
        items.append(item)

    return items

ObjectList

Bases: NotionObject, TypedObject

A paginated list of objects returned by the Notion API.

Source code in src/notional/iterator.py
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
class ObjectList(NotionObject, TypedObject, object="list"):
    """A paginated list of objects returned by the Notion API."""

    results: List[NotionObject] = []
    has_more: bool = False
    next_cursor: Optional[str] = None

    @validator("results", pre=True, each_item=True)
    def _convert_results_list(cls, val):
        """Convert the results list to specifc objects."""

        if "object" not in val:
            raise ValueError("Unknown object in results")

        if val["object"] == BlockList.type:
            return Block.parse_obj(val)

        if val["object"] == PageList.type:
            return Page.parse_obj(val)

        if val["object"] == DatabaseList.type:
            return Database.parse_obj(val)

        if val["object"] == PropertyItemList.type:
            return PropertyItem.parse_obj(val)

        if val["object"] == UserList.type:
            return User.parse_obj(val)

        return GenericObject.parse_obj(val)

PageList

Bases: ObjectList

A list of Page objects returned by the Notion API.

Source code in src/notional/iterator.py
56
57
58
59
class PageList(ObjectList, type="page"):
    """A list of Page objects returned by the Notion API."""

    page: Any = {}

PageOrDatabaseList

Bases: ObjectList

A list of Page or Database objects returned by the Notion API.

Source code in src/notional/iterator.py
68
69
70
71
class PageOrDatabaseList(ObjectList, type="page_or_database"):
    """A list of Page or Database objects returned by the Notion API."""

    page_or_database: Any = {}

PropertyItemList

Bases: ObjectList

A paginated list of property items returned by the Notion API.

Property item lists contain one or more pages of basic property items. These types do not typically match the schema for corresponding property values.

Source code in src/notional/iterator.py
80
81
82
83
84
85
86
87
88
89
90
91
92
class PropertyItemList(ObjectList, type="property_item"):
    """A paginated list of property items returned by the Notion API.

    Property item lists contain one or more pages of basic property items.  These types
    do not typically match the schema for corresponding property values.
    """

    class _NestedData(GenericObject):
        id: str = None
        type: str = None
        next_url: Optional[str] = None

    property_item: _NestedData = _NestedData()

UserList

Bases: ObjectList

A list of User objects returned by the Notion API.

Source code in src/notional/iterator.py
74
75
76
77
class UserList(ObjectList, type="user"):
    """A list of User objects returned by the Notion API."""

    user: Any = {}