5
5
6
6
from httpx import Response
7
7
8
- from ._utils import is_mapping
8
+ from ._utils import is_mapping , maybe_coerce_boolean , maybe_coerce_integer
9
9
from ._models import BaseModel
10
10
from ._base_client import BasePage , PageInfo , BaseSyncPage , BaseAsyncPage
11
11
18
18
19
19
class SyncOffsetPagination (BaseSyncPage [_T ], BasePage [_T ], Generic [_T ]):
20
20
items : List [_T ]
21
+ has_more : Optional [bool ] = None
22
+ next_offset : Optional [int ] = None
21
23
22
24
@override
23
25
def _get_page_items (self ) -> List [_T ]:
@@ -26,14 +28,22 @@ def _get_page_items(self) -> List[_T]:
26
28
return []
27
29
return items
28
30
31
+ @override
32
+ def has_next_page (self ) -> bool :
33
+ has_more = self .has_more
34
+ if has_more is not None and has_more is False :
35
+ return False
36
+
37
+ return super ().has_next_page ()
38
+
29
39
@override
30
40
def next_page_info (self ) -> Optional [PageInfo ]:
31
- offset = self ._options . params . get ( "offset" ) or 0
32
- if not isinstance ( offset , int ) :
33
- raise ValueError ( f'Expected "offset" param to be an integer but got { offset } ' )
41
+ next_offset = self .next_offset
42
+ if next_offset is None :
43
+ return None # type: ignore[unreachable]
34
44
35
45
length = len (self ._get_page_items ())
36
- current_count = offset + length
46
+ current_count = next_offset + length
37
47
38
48
return PageInfo (params = {"offset" : current_count })
39
49
@@ -43,12 +53,16 @@ def build(cls: Type[_BaseModelT], *, response: Response, data: object) -> _BaseM
43
53
None ,
44
54
** {
45
55
** (cast (Mapping [str , Any ], data ) if is_mapping (data ) else {"items" : data }),
56
+ "has_more" : maybe_coerce_boolean (response .headers .get ("X-Has-More" )),
57
+ "next_offset" : maybe_coerce_integer (response .headers .get ("X-Next-Offset" )),
46
58
},
47
59
)
48
60
49
61
50
62
class AsyncOffsetPagination (BaseAsyncPage [_T ], BasePage [_T ], Generic [_T ]):
51
63
items : List [_T ]
64
+ has_more : Optional [bool ] = None
65
+ next_offset : Optional [int ] = None
52
66
53
67
@override
54
68
def _get_page_items (self ) -> List [_T ]:
@@ -57,14 +71,22 @@ def _get_page_items(self) -> List[_T]:
57
71
return []
58
72
return items
59
73
74
+ @override
75
+ def has_next_page (self ) -> bool :
76
+ has_more = self .has_more
77
+ if has_more is not None and has_more is False :
78
+ return False
79
+
80
+ return super ().has_next_page ()
81
+
60
82
@override
61
83
def next_page_info (self ) -> Optional [PageInfo ]:
62
- offset = self ._options . params . get ( "offset" ) or 0
63
- if not isinstance ( offset , int ) :
64
- raise ValueError ( f'Expected "offset" param to be an integer but got { offset } ' )
84
+ next_offset = self .next_offset
85
+ if next_offset is None :
86
+ return None # type: ignore[unreachable]
65
87
66
88
length = len (self ._get_page_items ())
67
- current_count = offset + length
89
+ current_count = next_offset + length
68
90
69
91
return PageInfo (params = {"offset" : current_count })
70
92
@@ -74,5 +96,7 @@ def build(cls: Type[_BaseModelT], *, response: Response, data: object) -> _BaseM
74
96
None ,
75
97
** {
76
98
** (cast (Mapping [str , Any ], data ) if is_mapping (data ) else {"items" : data }),
99
+ "has_more" : maybe_coerce_boolean (response .headers .get ("X-Has-More" )),
100
+ "next_offset" : maybe_coerce_integer (response .headers .get ("X-Next-Offset" )),
77
101
},
78
102
)
0 commit comments