@@ -18,6 +18,19 @@ def wrapper(method, instance, args, kwargs):
18
18
return instance .request (endpoint_url , * method (* args , ** kwargs ))
19
19
return wrapper
20
20
21
+ def get_default_data (** kwargs ):
22
+ """Returns a POST data dict using default values."""
23
+ limit = kwargs .get ('limit' , 20 )
24
+ offset = kwargs .get ('offset' , 0 )
25
+ direction = kwargs .get ('direction' , 'asc' )
26
+ if not isinstance (limit , int ):
27
+ raise TypeError ("`limit` must be int" )
28
+ if not isinstance (offset , int ):
29
+ raise TypeError ("`offset` must be int" )
30
+ if not direction in ('asc' , 'desc' ):
31
+ raise ValueError ("`direction` must be one of 'asc', 'desc'" )
32
+ return { 'limit' : limit , 'offset' : offset , 'direction' : direction }
33
+
21
34
class PaginatedMethod :
22
35
"""Object representing a method that has a POST paginated version (with
23
36
args like limit, offset, direction) as well as optionally a GET
@@ -38,12 +51,8 @@ def __call__(self, *args, **kwargs):
38
51
)
39
52
return self ._method (* args , ** kwargs )
40
53
41
- def verbose (self , * args , limit = None , offset = None , direction = None ):
42
- data = {
43
- 'limit' : 20 if limit is None else limit ,
44
- 'offset' : 0 if offset is None else offset ,
45
- 'direction' : 'asc' if direction is None else direction ,
46
- }
54
+ def verbose (self , * args , ** kwargs ):
55
+ data = get_default_data (** kwargs )
47
56
return self .__call__ (* args , data = data , __verbose = True )
48
57
49
58
class Api (BaseApi ):
@@ -64,6 +73,49 @@ def __init__(self, *args):
64
73
self .wikidotuser_revisions = PaginatedMethod (self ._wikidotuser_revisions )
65
74
self .tags_pages = PaginatedMethod (self ._tags_pages , True )
66
75
76
+ def verbose (self , method : Callable , * args , ** kwargs ):
77
+ """Returns a generator that iterates over a paginated method.
78
+
79
+ callable `method`: The paginated method to iterate.
80
+ Remaining arguments will be passed to this method.
81
+
82
+
83
+ Pass this function int `limit`, an initial int `offset`, and str
84
+ `direction`. Each time the returned generator is called, it will
85
+ increment `offset` by `limit` and return the method for the resulting
86
+ set of parameters. Effectively, applied to a paginated method, this
87
+ generator is the same as turning the page.
88
+
89
+ wiki = scuttle(domain, API_KEY, 1)
90
+ generator = wiki.verbose(wiki.thread_posts, thread_id, limit=5)
91
+ for posts in generator:
92
+ print(len(posts)) # will be 5, except at very end
93
+
94
+ Note that at the end of the data, the length of the final 'page' will
95
+ very likely be less than `limit`.
96
+ """
97
+ print ("hello!" )
98
+ print (method , isinstance (method , PaginatedMethod ))
99
+ if not isinstance (method , PaginatedMethod ):
100
+ raise TypeError ("Iterated method must be a paginated method" )
101
+ data = get_default_data (** kwargs )
102
+
103
+ def paginated_generator ():
104
+ limit : int = data ['limit' ]
105
+ length : int = limit
106
+ offset : int = data ['offset' ]
107
+ direction : str = data ['direction' ]
108
+ while True :
109
+ result = method .verbose (* args , limit = limit , offset = offset ,
110
+ direction = direction )
111
+ yield result
112
+ if length < data ['limit' ]:
113
+ return
114
+ length = len (result )
115
+ offset += length
116
+
117
+ return paginated_generator ()
118
+
67
119
@endpoint ("wikis" )
68
120
def wikis (self ):
69
121
return None , None
0 commit comments