or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

authentication.mdcli-tools.mdcore-api.mdevents.mdgithub-actions.mdindex.mdpagination.md

pagination.mddocs/

0

# Pagination

1

2

Pagination module providing utilities for handling paginated GitHub API responses and parsing pagination headers efficiently.

3

4

## Capabilities

5

6

### Paginated Operations

7

8

Convert GitHub API operations into iterators for handling large result sets.

9

10

```python { .api }

11

def paged(oper, *args, per_page=30, max_pages=9999, **kwargs):

12

"""

13

Convert API operation into an iterator for pagination.

14

15

Parameters:

16

- oper: callable, GitHub API operation function

17

- *args: positional arguments for the operation

18

- per_page: int, number of items per page (default 30)

19

- max_pages: int, maximum pages to fetch (default 9999)

20

- **kwargs: keyword arguments for the operation

21

22

Yields:

23

API response objects for each page

24

"""

25

26

```

27

28

### Link Header Parsing

29

30

Parse RFC 5988 link headers from GitHub API responses.

31

32

```python { .api }

33

def parse_link_hdr(header):

34

"""

35

Parse RFC 5988 link header from GitHub API response.

36

37

Parameters:

38

- header: str, link header value

39

40

Returns:

41

list: List of tuples containing (url, attributes_dict)

42

"""

43

44

def pages(oper, n_pages, *args, n_workers=None, per_page=100, **kwargs):

45

"""

46

Get multiple pages from an operation in parallel.

47

48

Parameters:

49

- oper: callable, GitHub API operation function

50

- n_pages: int, number of pages to retrieve

51

- *args: positional arguments for the operation

52

- n_workers: int, number of parallel workers (defaults to n_pages)

53

- per_page: int, items per page

54

- **kwargs: keyword arguments for the operation

55

56

Returns:

57

list: List of page results retrieved in parallel

58

"""

59

```

60

61

## Usage Examples

62

63

### Basic Pagination

64

65

```python

66

from ghapi.all import GhApi, paged

67

68

api = GhApi(token='your_token')

69

70

# Paginate through all issues in a repository

71

for page in paged(api.issues.list_for_repo, owner='user', repo='repo', per_page=50):

72

for issue in page:

73

print(f"#{issue.number}: {issue.title}")

74

75

# Limit to first 5 pages

76

for page in paged(api.repos.list_for_user, username='user', per_page=100, max_pages=5):

77

for repo in page:

78

print(f"{repo.full_name}: {repo.stargazers_count} stars")

79

```

80

81

### Repository Pagination

82

83

```python

84

from ghapi.all import GhApi, paged

85

86

api = GhApi(token='your_token')

87

88

# Get all repositories for an organization

89

all_repos = []

90

for page in paged(api.repos.list_for_org, org='organization', per_page=100):

91

all_repos.extend(page)

92

93

print(f"Total repositories: {len(all_repos)}")

94

95

# Process repositories in batches

96

for page in paged(api.repos.list_for_org, org='org', per_page=25):

97

print(f"Processing batch of {len(page)} repositories:")

98

for repo in page:

99

print(f" - {repo.name} ({repo.language})")

100

101

# Get multiple pages in parallel

102

from ghapi.all import pages

103

page_results = pages(api.repos.list_for_org, 5, org='organization', per_page=20)

104

total_repos = sum(len(page) for page in page_results)

105

print(f"Retrieved {total_repos} repositories across 5 pages in parallel")

106

```

107

108

### Issue and Pull Request Pagination

109

110

```python

111

from ghapi.all import GhApi, paged

112

113

api = GhApi(token='your_token', owner='user', repo='repo')

114

115

# Get all open issues

116

open_issues = []

117

for page in paged(api.issues.list_for_repo, state='open', per_page=100):

118

open_issues.extend(page)

119

120

print(f"Open issues: {len(open_issues)}")

121

122

# Get all pull requests with specific label

123

for page in paged(api.pulls.list, state='all', per_page=50):

124

for pr in page:

125

if any(label.name == 'enhancement' for label in pr.labels):

126

print(f"Enhancement PR: #{pr.number} - {pr.title}")

127

128

# Get issue comments across all issues

129

for page in paged(api.issues.list_comments_for_repo, per_page=100):

130

for comment in page:

131

print(f"Comment by {comment.user.login}: {comment.body[:50]}...")

132

```

133

134

### Commit and Event Pagination

135

136

```python

137

from ghapi.all import GhApi, paged

138

139

api = GhApi(token='your_token')

140

141

# Get all commits in repository

142

commit_count = 0

143

for page in paged(api.repos.list_commits, owner='user', repo='repo', per_page=100):

144

commit_count += len(page)

145

for commit in page:

146

print(f"{commit.sha[:8]}: {commit.commit.message.split('\\n')[0]}")

147

148

print(f"Total commits: {commit_count}")

149

150

# Get repository events

151

for page in paged(api.activity.list_repo_events, owner='user', repo='repo', per_page=50):

152

for event in page:

153

print(f"{event.type}: {event.actor.login} at {event.created_at}")

154

```

155

156

### User and Organization Data

157

158

```python

159

from ghapi.all import GhApi, paged

160

161

api = GhApi(token='your_token')

162

163

# Get all followers for a user

164

followers = []

165

for page in paged(api.users.list_followers_for_user, username='user', per_page=100):

166

followers.extend(page)

167

168

print(f"Total followers: {len(followers)}")

169

170

# Get organization members

171

for page in paged(api.orgs.list_members, org='organization', per_page=50):

172

for member in page:

173

print(f"Member: {member.login}")

174

175

# Get user's starred repositories

176

starred_repos = []

177

for page in paged(api.activity.list_repos_starred_by_user, username='user', per_page=100):

178

starred_repos.extend(page)

179

180

print(f"Starred repositories: {len(starred_repos)}")

181

```

182

183

### Advanced Pagination with Filtering

184

185

```python

186

from ghapi.all import GhApi, paged

187

from datetime import datetime, timedelta

188

189

api = GhApi(token='your_token')

190

191

# Get recent issues (last 30 days)

192

thirty_days_ago = datetime.now() - timedelta(days=30)

193

recent_issues = []

194

195

for page in paged(api.issues.list_for_repo,

196

owner='user', repo='repo',

197

state='all',

198

since=thirty_days_ago.isoformat(),

199

per_page=100):

200

recent_issues.extend(page)

201

202

print(f"Issues in last 30 days: {len(recent_issues)}")

203

204

# Get pull requests by author

205

author_prs = []

206

for page in paged(api.pulls.list, owner='user', repo='repo', state='all', per_page=100):

207

for pr in page:

208

if pr.user.login == 'specific_author':

209

author_prs.append(pr)

210

211

print(f"PRs by author: {len(author_prs)}")

212

```

213

214

### Link Header Parsing

215

216

```python

217

from ghapi.all import parse_link_hdr

218

219

# Example link header from GitHub API

220

link_header = '<https://api.github.com/repos/user/repo/issues?page=2>; rel="next", <https://api.github.com/repos/user/repo/issues?page=5>; rel="last"'

221

222

# Parse the header

223

links = parse_link_hdr(link_header)

224

for url, attrs in links:

225

print(f"URL: {url}")

226

for key, value in attrs.items():

227

print(f" {key}: {value}")

228

229

# Extract specific relation types

230

next_url = None

231

last_url = None

232

for url, attrs in links:

233

if attrs.get('rel') == 'next':

234

next_url = url

235

elif attrs.get('rel') == 'last':

236

last_url = url

237

238

if next_url:

239

print(f"Next page: {next_url}")

240

if last_url:

241

print(f"Last page: {last_url}")

242

```

243

244

### Custom Pagination Logic

245

246

```python

247

from ghapi.all import GhApi, paged

248

249

api = GhApi(token='your_token')

250

251

def collect_all_data(operation_func, *args, **kwargs):

252

"""Collect all paginated data into a single list."""

253

all_data = []

254

for page in paged(operation_func, *args, per_page=100, **kwargs):

255

all_data.extend(page)

256

print(f"Collected {len(all_data)} items so far...")

257

return all_data

258

259

# Use custom collector

260

all_issues = collect_all_data(

261

api.issues.list_for_repo,

262

owner='user',

263

repo='repo',

264

state='all'

265

)

266

267

print(f"Total issues collected: {len(all_issues)}")

268

269

def process_in_chunks(operation_func, chunk_processor, *args, **kwargs):

270

"""Process paginated data in chunks."""

271

for page_num, page in enumerate(paged(operation_func, *args, per_page=50, **kwargs)):

272

print(f"Processing page {page_num + 1}...")

273

chunk_processor(page)

274

275

def process_repo_chunk(repos):

276

"""Process a chunk of repositories."""

277

for repo in repos:

278

if repo.stargazers_count > 100:

279

print(f"Popular repo: {repo.full_name} ({repo.stargazers_count} stars)")

280

281

# Process repositories in chunks

282

process_in_chunks(

283

api.repos.list_for_org,

284

process_repo_chunk,

285

org='organization'

286

)

287

```

288

289

### Error Handling with Pagination

290

291

```python

292

from ghapi.all import GhApi, paged

293

import time

294

295

api = GhApi(token='your_token')

296

297

def safe_paginate(operation_func, *args, retry_count=3, **kwargs):

298

"""Paginate with error handling and retries."""

299

page_num = 0

300

for page in paged(operation_func, *args, per_page=100, **kwargs):

301

page_num += 1

302

retries = 0

303

304

while retries < retry_count:

305

try:

306

# Process the page

307

yield page

308

break

309

except Exception as e:

310

retries += 1

311

print(f"Error processing page {page_num}, retry {retries}: {e}")

312

if retries < retry_count:

313

time.sleep(2 ** retries) # Exponential backoff

314

else:

315

print(f"Failed to process page {page_num} after {retry_count} retries")

316

raise

317

318

# Use safe pagination

319

try:

320

for page in safe_paginate(api.repos.list_for_org, org='large_org'):

321

for repo in page:

322

print(f"Processing: {repo.name}")

323

except Exception as e:

324

print(f"Pagination failed: {e}")

325

```