Skip to content

Commit dc374cf

Browse files
authored
Merge pull request #40 from gofri/gofri/fix_basic_example
docs: fix readme and add example/ dir
2 parents 80a8a21 + f57da4a commit dc374cf

File tree

8 files changed

+126
-37
lines changed

8 files changed

+126
-37
lines changed

README.md

Lines changed: 24 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
[![Go Report Card](https://goreportcard.com/badge/github.com/gofri/go-github-ratelimit)](https://goreportcard.com/report/github.com/gofri/go-github-ratelimit)
44

5-
Package `go-github-ratelimit` providesa middleware (http.RoundTripper) that handles both [Primary Rate Limit](https://docs.github.com/en/rest/using-the-rest-api/rate-limits-for-the-rest-api?#about-primary-rate-limits) and [Secondary Rate Limit](https://docs.github.com/en/rest/using-the-rest-api/rate-limits-for-the-rest-api?#about-secondary-rate-limits) for the GitHub API.
5+
Package `go-github-ratelimit` provides a middleware (http.RoundTripper) that handles both [Primary Rate Limit](https://docs.github.com/en/rest/using-the-rest-api/rate-limits-for-the-rest-api?#about-primary-rate-limits) and [Secondary Rate Limit](https://docs.github.com/en/rest/using-the-rest-api/rate-limits-for-the-rest-api?#about-secondary-rate-limits) for the GitHub API.
66

77
* Primary rate limits are handled by returning a detailed error.
88
* Secondary rate limits are handled by waiting in blocking mode (sleep) and then issuing/retrying requests.
@@ -24,22 +24,21 @@ It is best to stack the pagination round-tripper on top of the rate limit round-
2424

2525
## Usage Example (with [go-github](https://github.com/google/go-github))
2626

27+
see [example/basic.go](example/basic.go) for a runnable example.
2728
```go
28-
import "github.com/google/go-github/v69/github"
29-
import "github.com/gofri/go-github-ratelimit/v2/github_ratelimit"
29+
rateLimiter := github_ratelimit.NewClient(nil)
30+
client := github.NewClient(rateLimiter) // .WithAuthToken("your personal access token")
3031

31-
func main() {
32-
// use the plain ratelimiter, without options / callbacks / underlying http.RoundTripper.
33-
rateLimiter, err := github_ratelimit.New(nil)
34-
if err != nil {
35-
panic(err)
36-
}
37-
client := github.NewClient(rateLimiter).WithAuthToken("your personal access token")
32+
// disable go-github's built-in rate limiting
33+
ctx := context.WithValue(context.Background(), github.BypassRateLimitCheck, true)
3834

39-
// disable go-github's built-in rate limiting
40-
ctx := context.WithValue(context.Background(), github.BypassRateLimitCheck)
35+
tags, _, err := client.Repositories.ListTags(ctx, "gofri", "go-github-ratelimit", nil)
36+
if err != nil {
37+
panic(err)
38+
}
4139

42-
// now use the client as you please
40+
for _, tag := range tags {
41+
fmt.Printf("- %v\n", *tag.Name)
4342
}
4443
```
4544

@@ -48,7 +47,7 @@ func main() {
4847
Both RoundTrippers support a set of options to configure their behavior and set callbacks.
4948
nil callbacks are treated as no-op.
5049

51-
### Primary Rate Limit Options:
50+
### Primary Rate Limit Options (see [options.go](github_ratelimit/github_primary_ratelimit/options.go)):
5251

5352
- `WithLimitDetectedCallback(callback)`: the callback is triggered when any primary rate limit is detected.
5453
- `WithRequestPreventedCallback(callback)`: the callback is triggered when a request is prevented due to an active rate limit.
@@ -57,7 +56,7 @@ nil callbacks are treated as no-op.
5756
- `WithSharedState(state)`: share state between multiple clients (e.g., for a single user running concurrently).
5857
- `WithBypassLimit()`: bypass the rate limit mechanism, i.e., do not prevent requests when a rate limit is active.
5958

60-
### Secondary Rate Limit Options:
59+
### Secondary Rate Limit Options (see [options.go](github_ratelimit/github_secondary_ratelimit/options.go)):
6160

6261
- `WithLimitDetectedCallback(callback)`: the callback is triggered before a sleep.
6362
- `WithSingleSleepLimit(duration, callback)`: limit the sleep duration for a single secondary rate limit & trigger a callback when the limit is exceeded.
@@ -72,18 +71,8 @@ as well as fine-grained policy control (e.g., for a sophisticated pagination mec
7271

7372
## Advanced Example
7473

74+
See [example/advanced.go](example/advanced.go) for a runnable example.
7575
```go
76-
import "github.com/google/go-github/v69/github"
77-
import "github.com/gofri/go-github-ratelimit/v2/github_ratelimit"
78-
import "github.com/gofri/go-github-ratelimit/v2/github_ratelimit/github_primary_ratelimit"
79-
import "github.com/gofri/go-github-ratelimit/v2/github_ratelimit/github_secondary_ratelimit"
80-
import "github.com/gofri/go-github-pagination/githubpagination"
81-
82-
func main() {
83-
var username string
84-
fmt.Print("Enter GitHub username: ")
85-
fmt.Scanf("%s", &username)
86-
8776
rateLimiter := github_ratelimit.New(nil,
8877
github_primary_ratelimit.WithLimitDetectedCallback(func(ctx *github_primary_ratelimit.CallbackContext) {
8978
fmt.Printf("Primary rate limit detected: category %s, reset time: %v\n", ctx.Category, ctx.ResetTime)
@@ -96,19 +85,20 @@ func main() {
9685
paginator := githubpagination.NewClient(rateLimiter,
9786
githubpagination.WithPerPage(100), // default to 100 results per page
9887
)
99-
client := github.NewClient(paginator)
88+
client := github.NewClient(paginator) // .WithAuthToken("your personal access token")
10089

101-
// arbitrary usage of the client
102-
repos, _, err := client.Repositories.ListByUser(context.Background(), username, nil)
90+
// disable go-github's built-in rate limiting
91+
ctx := context.WithValue(context.Background(), github.BypassRateLimitCheck, true)
92+
93+
// list repository tags
94+
tags, _, err := client.Repositories.ListTags(ctx, "gofri", "go-github-ratelimit", nil)
10395
if err != nil {
104-
fmt.Printf("Error: %v\n", err)
105-
return
96+
panic(err)
10697
}
10798

108-
for i, repo := range repos {
109-
fmt.Printf("%v. %v\n", i+1, repo.GetName())
99+
for _, tag := range tags {
100+
fmt.Printf("- %v\n", *tag.Name)
110101
}
111-
}
112102
```
113103

114104
## Migration (V1 => V2)

example/advanced.go

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package main
2+
3+
import (
4+
"context"
5+
"fmt"
6+
7+
"github.com/gofri/go-github-pagination/githubpagination"
8+
"github.com/gofri/go-github-ratelimit/v2/github_ratelimit"
9+
"github.com/gofri/go-github-ratelimit/v2/github_ratelimit/github_primary_ratelimit"
10+
"github.com/gofri/go-github-ratelimit/v2/github_ratelimit/github_secondary_ratelimit"
11+
"github.com/google/go-github/v69/github"
12+
)
13+
14+
func main() {
15+
rateLimiter := github_ratelimit.New(nil,
16+
github_primary_ratelimit.WithLimitDetectedCallback(func(ctx *github_primary_ratelimit.CallbackContext) {
17+
fmt.Printf("Primary rate limit detected: category %s, reset time: %v\n", ctx.Category, ctx.ResetTime)
18+
}),
19+
github_secondary_ratelimit.WithLimitDetectedCallback(func(ctx *github_secondary_ratelimit.CallbackContext) {
20+
fmt.Printf("Secondary rate limit detected: reset time: %v, total sleep time: %v\n", ctx.ResetTime, ctx.TotalSleepTime)
21+
}),
22+
)
23+
24+
paginator := githubpagination.NewClient(rateLimiter,
25+
githubpagination.WithPerPage(100), // default to 100 results per page
26+
)
27+
client := github.NewClient(paginator) // .WithAuthToken("your personal access token")
28+
29+
// disable go-github's built-in rate limiting
30+
ctx := context.WithValue(context.Background(), github.BypassRateLimitCheck, true)
31+
32+
// list repository tags
33+
tags, _, err := client.Repositories.ListTags(ctx, "gofri", "go-github-ratelimit", nil)
34+
if err != nil {
35+
panic(err)
36+
}
37+
38+
for _, tag := range tags {
39+
fmt.Printf("- %v\n", *tag.Name)
40+
}
41+
}

example/basic.go

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package main
2+
3+
import (
4+
"context"
5+
"fmt"
6+
7+
"github.com/gofri/go-github-ratelimit/v2/github_ratelimit"
8+
"github.com/google/go-github/v69/github"
9+
)
10+
11+
func main() {
12+
// use the plain ratelimiter, without options / callbacks / underlying http.RoundTripper.
13+
rateLimiter := github_ratelimit.NewClient(nil)
14+
client := github.NewClient(rateLimiter) // .WithAuthToken("your personal access token")
15+
16+
// disable go-github's built-in rate limiting
17+
ctx := context.WithValue(context.Background(), github.BypassRateLimitCheck, true)
18+
19+
tags, _, err := client.Repositories.ListTags(ctx, "gofri", "go-github-ratelimit", nil)
20+
if err != nil {
21+
panic(err)
22+
}
23+
24+
for _, tag := range tags {
25+
fmt.Printf("- %v\n", *tag.Name)
26+
}
27+
}

example/go.mod

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
module github.com/gofri/go-github-ratelimit/v2/example
2+
3+
replace github.com/gofri/go-github-ratelimit/v2 => ../
4+
5+
go 1.23.1
6+
7+
require (
8+
github.com/gofri/go-github-pagination v1.0.0
9+
github.com/gofri/go-github-ratelimit/v2 v2.0.1
10+
github.com/google/go-github/v69 v69.2.0
11+
)
12+
13+
require github.com/google/go-querystring v1.1.0 // indirect

example/go.sum

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
github.com/gofri/go-github-pagination v1.0.0 h1:nnCi+1xT5ybqY/plctISgiQPWZOtfSciVQlbx/hM/Yw=
2+
github.com/gofri/go-github-pagination v1.0.0/go.mod h1:Qij55Fb4fNPjam3SB+8cLnqp4pgR8RGMyIspYXcyHX0=
3+
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
4+
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
5+
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
6+
github.com/google/go-github/v69 v69.2.0 h1:wR+Wi/fN2zdUx9YxSmYE0ktiX9IAR/BeePzeaUUbEHE=
7+
github.com/google/go-github/v69 v69.2.0/go.mod h1:xne4jymxLR6Uj9b7J7PyTpkMYstEMMwGZa0Aehh1azM=
8+
github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8=
9+
github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU=
10+
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=

github_ratelimit/github_ratelimiter.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ func NewSecondaryLimiter(base http.RoundTripper, opts ...SecondaryRateLimiterOpt
2929

3030
// New creates a combined limiter by stacking a SecondaryRateLimiter on top of a PrimaryRateLimiterOption.
3131
// It accepts options of both types and creates the RoundTrippers.
32+
// Check out options.go @ github_primary_ratelimit / github_secondary_ratelimit for available options.
3233
func New(base http.RoundTripper, opts ...any) http.RoundTripper {
3334
primaryOpts, secondaryOpts := gatherOptions(opts...)
3435
primary := NewPrimaryLimiter(base, primaryOpts...)
@@ -37,6 +38,13 @@ func New(base http.RoundTripper, opts ...any) http.RoundTripper {
3738
return secondary
3839
}
3940

41+
// NewClient creates a new HTTP client with the combined rate limiter.
42+
func NewClient(base http.RoundTripper, opts ...any) *http.Client {
43+
return &http.Client{
44+
Transport: New(base, opts...),
45+
}
46+
}
47+
4048
// WithOverrideConfig adds config overrides to the context.
4149
// The overrides are applied on top of the existing config.
4250
// Allows for request-specific overrides.

github_ratelimit/github_secondary_ratelimit/callback.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ type CallbackContext struct {
1515
Response *http.Response
1616
}
1717

18-
// OnLimitDetected is a callback to be called when a new rate limit is detected (before the sleep)
19-
// The totalSleepTime includes the sleep duration for the upcoming sleep
18+
// OnLimitDetected is a callback to be called when a new rate limit is detected (before the sleep).
19+
// The totalSleepTime includes the sleep duration for the upcoming sleep.
2020
// Note: called while holding the lock.
2121
type OnLimitDetected func(*CallbackContext)
2222

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
module github.com/gofri/go-github-ratelimit/v2
22

3-
go 1.23.1
3+
go 1.23.0

0 commit comments

Comments
 (0)