lightrate-client 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.rspec +1 -0
- data/.rubocop.yml +32 -0
- data/Gemfile +11 -0
- data/Gemfile.lock +133 -0
- data/README.md +289 -0
- data/Rakefile +11 -0
- data/examples/basic_usage.rb +146 -0
- data/lib/lightrate_client/client.rb +244 -0
- data/lib/lightrate_client/configuration.rb +29 -0
- data/lib/lightrate_client/errors.rb +31 -0
- data/lib/lightrate_client/types.rb +199 -0
- data/lib/lightrate_client/version.rb +5 -0
- data/lib/lightrate_client.rb +33 -0
- metadata +214 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: c63b6519eeb427af97e5de527bc710be417a302dedde208d0915b259c9ef1ed7
|
4
|
+
data.tar.gz: 62a4447c9e7f57358552a447aa06553a51a40a116c09d376e9a3e6d4c18ddcfe
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 47024b5debeb8cbfef45d0cbdb7263bd43a7d4959acf37bf506541a12af07149dc27869775e73468793baddb0dc60d73ffa50fc4868f14fc99098b949ef42189
|
7
|
+
data.tar.gz: d89180c3cb9399316b73903ec63078d9bd02a522a157781916f09c154658a82024ef87064752996a77144f7ac370e97176975bf409817c7960a5820e918a003f
|
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--require spec_helper
|
data/.rubocop.yml
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
AllCops:
|
2
|
+
NewCops: enable
|
3
|
+
TargetRubyVersion: 2.7
|
4
|
+
Exclude:
|
5
|
+
- 'spec/fixtures/**/*'
|
6
|
+
- 'vendor/**/*'
|
7
|
+
|
8
|
+
Layout/LineLength:
|
9
|
+
Max: 120
|
10
|
+
|
11
|
+
Style/Documentation:
|
12
|
+
Enabled: false
|
13
|
+
|
14
|
+
Style/FrozenStringLiteralComment:
|
15
|
+
Enabled: true
|
16
|
+
|
17
|
+
Style/StringLiterals:
|
18
|
+
EnforcedStyle: single_quotes
|
19
|
+
|
20
|
+
Style/ClassAndModuleChildren:
|
21
|
+
Enabled: false
|
22
|
+
|
23
|
+
Metrics/BlockLength:
|
24
|
+
Exclude:
|
25
|
+
- 'spec/**/*'
|
26
|
+
- 'Rakefile'
|
27
|
+
|
28
|
+
Metrics/MethodLength:
|
29
|
+
Max: 20
|
30
|
+
|
31
|
+
Metrics/AbcSize:
|
32
|
+
Max: 20
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,133 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
lightrate-client (1.0.0)
|
5
|
+
faraday (~> 2.0)
|
6
|
+
faraday-retry (~> 2.0)
|
7
|
+
json (~> 2.0)
|
8
|
+
|
9
|
+
GEM
|
10
|
+
remote: https://rubygems.org/
|
11
|
+
specs:
|
12
|
+
addressable (2.8.7)
|
13
|
+
public_suffix (>= 2.0.2, < 7.0)
|
14
|
+
ast (2.4.3)
|
15
|
+
base64 (0.3.0)
|
16
|
+
bigdecimal (3.2.3)
|
17
|
+
byebug (12.0.0)
|
18
|
+
coderay (1.1.3)
|
19
|
+
crack (1.0.0)
|
20
|
+
bigdecimal
|
21
|
+
rexml
|
22
|
+
diff-lcs (1.6.2)
|
23
|
+
docile (1.4.1)
|
24
|
+
faraday (2.13.4)
|
25
|
+
faraday-net_http (>= 2.0, < 3.5)
|
26
|
+
json
|
27
|
+
logger
|
28
|
+
faraday-net_http (3.4.1)
|
29
|
+
net-http (>= 0.5.0)
|
30
|
+
faraday-retry (2.3.2)
|
31
|
+
faraday (~> 2.0)
|
32
|
+
hashdiff (1.2.1)
|
33
|
+
json (2.15.0)
|
34
|
+
language_server-protocol (3.17.0.5)
|
35
|
+
lint_roller (1.1.0)
|
36
|
+
logger (1.7.0)
|
37
|
+
method_source (1.1.0)
|
38
|
+
net-http (0.6.0)
|
39
|
+
uri
|
40
|
+
parallel (1.27.0)
|
41
|
+
parser (3.3.9.0)
|
42
|
+
ast (~> 2.4.1)
|
43
|
+
racc
|
44
|
+
prism (1.5.1)
|
45
|
+
pry (0.15.2)
|
46
|
+
coderay (~> 1.1)
|
47
|
+
method_source (~> 1.0)
|
48
|
+
pry-byebug (3.11.0)
|
49
|
+
byebug (~> 12.0)
|
50
|
+
pry (>= 0.13, < 0.16)
|
51
|
+
public_suffix (6.0.2)
|
52
|
+
racc (1.8.1)
|
53
|
+
rainbow (3.1.1)
|
54
|
+
rake (13.3.0)
|
55
|
+
regexp_parser (2.11.3)
|
56
|
+
rexml (3.4.4)
|
57
|
+
rspec (3.13.1)
|
58
|
+
rspec-core (~> 3.13.0)
|
59
|
+
rspec-expectations (~> 3.13.0)
|
60
|
+
rspec-mocks (~> 3.13.0)
|
61
|
+
rspec-core (3.13.5)
|
62
|
+
rspec-support (~> 3.13.0)
|
63
|
+
rspec-expectations (3.13.5)
|
64
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
65
|
+
rspec-support (~> 3.13.0)
|
66
|
+
rspec-mocks (3.13.5)
|
67
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
68
|
+
rspec-support (~> 3.13.0)
|
69
|
+
rspec-support (3.13.6)
|
70
|
+
rubocop (1.81.1)
|
71
|
+
json (~> 2.3)
|
72
|
+
language_server-protocol (~> 3.17.0.2)
|
73
|
+
lint_roller (~> 1.1.0)
|
74
|
+
parallel (~> 1.10)
|
75
|
+
parser (>= 3.3.0.2)
|
76
|
+
rainbow (>= 2.2.2, < 4.0)
|
77
|
+
regexp_parser (>= 2.9.3, < 3.0)
|
78
|
+
rubocop-ast (>= 1.47.1, < 2.0)
|
79
|
+
ruby-progressbar (~> 1.7)
|
80
|
+
unicode-display_width (>= 2.4.0, < 4.0)
|
81
|
+
rubocop-ast (1.47.1)
|
82
|
+
parser (>= 3.3.7.2)
|
83
|
+
prism (~> 1.4)
|
84
|
+
rubocop-capybara (2.22.1)
|
85
|
+
lint_roller (~> 1.1)
|
86
|
+
rubocop (~> 1.72, >= 1.72.1)
|
87
|
+
rubocop-factory_bot (2.27.1)
|
88
|
+
lint_roller (~> 1.1)
|
89
|
+
rubocop (~> 1.72, >= 1.72.1)
|
90
|
+
rubocop-rspec (2.31.0)
|
91
|
+
rubocop (~> 1.40)
|
92
|
+
rubocop-capybara (~> 2.17)
|
93
|
+
rubocop-factory_bot (~> 2.22)
|
94
|
+
rubocop-rspec_rails (~> 2.28)
|
95
|
+
rubocop-rspec_rails (2.29.1)
|
96
|
+
rubocop (~> 1.61)
|
97
|
+
ruby-progressbar (1.13.0)
|
98
|
+
simplecov (0.22.0)
|
99
|
+
docile (~> 1.1)
|
100
|
+
simplecov-html (~> 0.11)
|
101
|
+
simplecov_json_formatter (~> 0.1)
|
102
|
+
simplecov-html (0.13.2)
|
103
|
+
simplecov_json_formatter (0.1.4)
|
104
|
+
unicode-display_width (3.2.0)
|
105
|
+
unicode-emoji (~> 4.1)
|
106
|
+
unicode-emoji (4.1.0)
|
107
|
+
uri (1.0.3)
|
108
|
+
vcr (6.3.1)
|
109
|
+
base64
|
110
|
+
webmock (3.25.1)
|
111
|
+
addressable (>= 2.8.0)
|
112
|
+
crack (>= 0.3.2)
|
113
|
+
hashdiff (>= 0.4.0, < 2.0.0)
|
114
|
+
|
115
|
+
PLATFORMS
|
116
|
+
ruby
|
117
|
+
x86_64-darwin-22
|
118
|
+
|
119
|
+
DEPENDENCIES
|
120
|
+
bundler (~> 2.0)
|
121
|
+
lightrate-client!
|
122
|
+
pry (~> 0.14)
|
123
|
+
pry-byebug (~> 3.10)
|
124
|
+
rake (~> 13.0)
|
125
|
+
rspec (~> 3.0)
|
126
|
+
rubocop (~> 1.0)
|
127
|
+
rubocop-rspec (~> 2.0)
|
128
|
+
simplecov (~> 0.21)
|
129
|
+
vcr (~> 6.0)
|
130
|
+
webmock (~> 3.0)
|
131
|
+
|
132
|
+
BUNDLED WITH
|
133
|
+
2.5.21
|
data/README.md
ADDED
@@ -0,0 +1,289 @@
|
|
1
|
+
# Lightrate Client Ruby
|
2
|
+
|
3
|
+
A Ruby gem for interacting with the Lightrate token management API, providing easy-to-use methods for consuming tokens.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
```ruby
|
10
|
+
gem 'lightrate-client'
|
11
|
+
```
|
12
|
+
|
13
|
+
And then execute:
|
14
|
+
|
15
|
+
```bash
|
16
|
+
$ bundle install
|
17
|
+
```
|
18
|
+
|
19
|
+
Or install it yourself as:
|
20
|
+
|
21
|
+
```bash
|
22
|
+
$ gem install lightrate-client
|
23
|
+
```
|
24
|
+
|
25
|
+
## Usage
|
26
|
+
|
27
|
+
### Configuration
|
28
|
+
|
29
|
+
Configure the client with your API credentials:
|
30
|
+
|
31
|
+
```ruby
|
32
|
+
require 'lightrate_client'
|
33
|
+
|
34
|
+
LightrateClient.configure do |config|
|
35
|
+
config.api_key = 'your_api_key'
|
36
|
+
config.application_id = 'your_application_id' # required
|
37
|
+
config.timeout = 30 # optional, defaults to 30 seconds
|
38
|
+
config.retry_attempts = 3 # optional, defaults to 3
|
39
|
+
config.logger = Logger.new(STDOUT) # optional, for request logging
|
40
|
+
end
|
41
|
+
```
|
42
|
+
|
43
|
+
### Basic Usage
|
44
|
+
|
45
|
+
```ruby
|
46
|
+
# Simple usage - pass your API key and application ID
|
47
|
+
client = LightrateClient::Client.new('your_api_key', 'your_application_id')
|
48
|
+
|
49
|
+
# Or use the convenience method
|
50
|
+
client = LightrateClient.new_client('your_api_key', 'your_application_id')
|
51
|
+
|
52
|
+
# With additional options
|
53
|
+
client = LightrateClient::Client.new('your_api_key', 'your_application_id',
|
54
|
+
timeout: 60
|
55
|
+
)
|
56
|
+
|
57
|
+
# Or configure globally and use the default client
|
58
|
+
LightrateClient.configure do |config|
|
59
|
+
config.api_key = 'your_api_key'
|
60
|
+
config.application_id = 'your_application_id'
|
61
|
+
end
|
62
|
+
client = LightrateClient.client
|
63
|
+
```
|
64
|
+
|
65
|
+
### Token Consumption Methods
|
66
|
+
|
67
|
+
The Lightrate Client provides two methods for consuming tokens, each with different performance characteristics:
|
68
|
+
|
69
|
+
#### 🚀 Recommended: Local Token Buckets (`consume_local_bucket_token`)
|
70
|
+
|
71
|
+
**Use this method for high-frequency token consumption.** It maintains local token buckets that are refilled in batches from the API, dramatically reducing the number of HTTP requests.
|
72
|
+
|
73
|
+
```ruby
|
74
|
+
# Configure client with default bucket size
|
75
|
+
client = LightrateClient::Client.new(
|
76
|
+
'your_api_key',
|
77
|
+
'your_application_id',
|
78
|
+
default_local_bucket_size: 20 # Default bucket size for all operations
|
79
|
+
)
|
80
|
+
|
81
|
+
# Consume tokens using local buckets (fast, reduces API calls)
|
82
|
+
response = client.consume_local_bucket_token(
|
83
|
+
operation: 'send_email',
|
84
|
+
user_identifier: 'user123'
|
85
|
+
)
|
86
|
+
|
87
|
+
puts "Success: #{response.success}"
|
88
|
+
puts "Used local token: #{response.used_local_token}"
|
89
|
+
puts "Bucket status: #{response.bucket_status}"
|
90
|
+
|
91
|
+
# Or consume by path
|
92
|
+
response = client.consume_local_bucket_token(
|
93
|
+
path: '/api/v1/emails/send',
|
94
|
+
http_method: 'POST',
|
95
|
+
user_identifier: 'user123'
|
96
|
+
)
|
97
|
+
```
|
98
|
+
|
99
|
+
**Benefits of Local Buckets:**
|
100
|
+
- ⚡ **Fast**: Most token consumption happens locally without HTTP requests
|
101
|
+
- 🔄 **Efficient**: Batches token requests to reduce API calls by 95%+
|
102
|
+
- 🛡️ **Resilient**: Continues working even with temporary API outages
|
103
|
+
- 🎯 **Configurable**: Customizable bucket sizes for your application needs
|
104
|
+
|
105
|
+
#### 🌐 Direct API Calls (`consume_tokens`)
|
106
|
+
|
107
|
+
**Use this method for occasional token consumption or when you need immediate API feedback.**
|
108
|
+
|
109
|
+
```ruby
|
110
|
+
# Direct API call - makes HTTP request every time
|
111
|
+
response = client.consume_tokens(
|
112
|
+
operation: 'send_email',
|
113
|
+
user_identifier: 'user123',
|
114
|
+
tokens_requested: 1
|
115
|
+
)
|
116
|
+
|
117
|
+
puts "Tokens consumed: #{response.tokens_consumed}"
|
118
|
+
puts "Tokens remaining: #{response.tokens_remaining}"
|
119
|
+
puts "Throttles: #{response.throttles}"
|
120
|
+
puts "Rule: #{response.rule.name} (ID: #{response.rule.id})"
|
121
|
+
```
|
122
|
+
|
123
|
+
**When to use Direct API Calls:**
|
124
|
+
- 🔍 **Debugging**: When you need immediate API feedback
|
125
|
+
- 📊 **Monitoring**: For applications that rarely consume tokens
|
126
|
+
- 🎛️ **Control**: When you need precise control over token requests
|
127
|
+
- 🔄 **Legacy**: For compatibility with existing code
|
128
|
+
|
129
|
+
### Method Comparison
|
130
|
+
|
131
|
+
| Feature | Local Buckets | Direct API |
|
132
|
+
|---------|---------------|------------|
|
133
|
+
| **Speed** | ⚡ Very Fast | 🐌 Network dependent |
|
134
|
+
| **API Calls** | 📉 Minimal (95%+ reduction) | 📈 Every request |
|
135
|
+
| **Resilience** | 🛡️ High (works offline briefly) | 🔗 Requires network |
|
136
|
+
| **Feedback** | 📊 Bucket status only | 📋 Full API response |
|
137
|
+
| **Best For** | High-frequency usage | Occasional usage |
|
138
|
+
|
139
|
+
### Performance Benefits
|
140
|
+
|
141
|
+
**Local Token Buckets dramatically improve performance:**
|
142
|
+
|
143
|
+
- **95%+ reduction in API calls** - Instead of making an HTTP request for every token consumption, tokens are fetched in batches
|
144
|
+
- **Sub-millisecond response times** - Local token consumption is nearly instant
|
145
|
+
- **Better reliability** - Continues working even during brief API outages
|
146
|
+
- **Reduced bandwidth costs** - Fewer HTTP requests mean lower network usage
|
147
|
+
|
148
|
+
**Example Performance Comparison:**
|
149
|
+
```ruby
|
150
|
+
# ❌ Slow: Direct API calls
|
151
|
+
1000.times do
|
152
|
+
client.consume_tokens(operation: 'send_email', user_identifier: 'user123', tokens_requested: 1)
|
153
|
+
# Each call: ~100-200ms network latency
|
154
|
+
end
|
155
|
+
# Total: 1000 API calls, ~100-200 seconds
|
156
|
+
|
157
|
+
# ✅ Fast: Local buckets
|
158
|
+
1000.times do
|
159
|
+
client.consume_local_bucket_token(operation: 'send_email', user_identifier: 'user123')
|
160
|
+
# Each call: ~0.1ms local operation
|
161
|
+
end
|
162
|
+
# Total: ~1 API call, ~0.1 seconds
|
163
|
+
```
|
164
|
+
|
165
|
+
### When to Use Each Method
|
166
|
+
|
167
|
+
**Use Local Buckets when:**
|
168
|
+
- 🚀 Building high-performance applications
|
169
|
+
- 📧 Sending bulk emails, SMS, or notifications
|
170
|
+
- 🔄 Processing webhooks or background jobs
|
171
|
+
- 📊 Handling user-facing requests that need fast response times
|
172
|
+
- 🏭 Running production applications with high token usage
|
173
|
+
|
174
|
+
**Use Direct API when:**
|
175
|
+
- 🔍 Debugging or testing rate limiting
|
176
|
+
- 📊 Building monitoring dashboards
|
177
|
+
- 🎛️ Need immediate feedback on token consumption
|
178
|
+
- 🔄 Migrating from existing implementations
|
179
|
+
- 📱 Building low-frequency applications (fewer than 10 requests/minute)
|
180
|
+
|
181
|
+
|
182
|
+
|
183
|
+
### Complete Example: High-Performance Token Consumption
|
184
|
+
|
185
|
+
```ruby
|
186
|
+
require 'lightrate_client'
|
187
|
+
|
188
|
+
# Create a client with default bucket size
|
189
|
+
client = LightrateClient::Client.new(
|
190
|
+
ENV['LIGHTRATE_API_KEY'] || 'your_api_key',
|
191
|
+
ENV['LIGHTRATE_APPLICATION_ID'] || 'your_application_id',
|
192
|
+
default_local_bucket_size: 50 # All operations use this bucket size
|
193
|
+
)
|
194
|
+
|
195
|
+
begin
|
196
|
+
# First call: Fetches 50 tokens from API and consumes 1 locally
|
197
|
+
response1 = client.consume_local_bucket_token(
|
198
|
+
operation: 'send_email',
|
199
|
+
user_identifier: 'user123'
|
200
|
+
)
|
201
|
+
|
202
|
+
puts "First call - Success: #{response1.success}"
|
203
|
+
puts "Used local token: #{response1.used_local_token}"
|
204
|
+
puts "Bucket status: #{response1.bucket_status}"
|
205
|
+
|
206
|
+
# Second call: Consumes from local bucket (no API call!)
|
207
|
+
response2 = client.consume_local_bucket_token(
|
208
|
+
operation: 'send_email',
|
209
|
+
user_identifier: 'user123'
|
210
|
+
)
|
211
|
+
|
212
|
+
puts "Second call - Success: #{response2.success}"
|
213
|
+
puts "Used local token: #{response2.used_local_token}"
|
214
|
+
puts "Bucket status: #{response2.bucket_status}"
|
215
|
+
|
216
|
+
# Example with path-based consumption
|
217
|
+
response3 = client.consume_local_bucket_token(
|
218
|
+
path: '/api/v1/emails/send',
|
219
|
+
http_method: 'POST',
|
220
|
+
user_identifier: 'user123'
|
221
|
+
)
|
222
|
+
|
223
|
+
puts "Path-based call - Success: #{response3.success}"
|
224
|
+
puts "Bucket status: #{response3.bucket_status}"
|
225
|
+
|
226
|
+
# Proceed with your operations...
|
227
|
+
|
228
|
+
rescue LightrateClient::UnauthorizedError => e
|
229
|
+
puts "❌ Authentication failed: #{e.message}"
|
230
|
+
rescue LightrateClient::TooManyRequestsError => e
|
231
|
+
puts "⚠️ Rate limited: #{e.message}"
|
232
|
+
rescue LightrateClient::APIError => e
|
233
|
+
puts "❌ API Error (#{e.status_code}): #{e.message}"
|
234
|
+
rescue LightrateClient::NetworkError => e
|
235
|
+
puts "❌ Network error: #{e.message}"
|
236
|
+
end
|
237
|
+
```
|
238
|
+
|
239
|
+
### Advanced Configuration
|
240
|
+
|
241
|
+
```ruby
|
242
|
+
# For applications with very high token consumption
|
243
|
+
client = LightrateClient::Client.new(
|
244
|
+
'your_api_key',
|
245
|
+
'your_application_id',
|
246
|
+
default_local_bucket_size: 500, # Large default bucket for all operations
|
247
|
+
timeout: 60, # Longer timeout for large bucket requests
|
248
|
+
retry_attempts: 5, # More retries for reliability
|
249
|
+
logger: Logger.new(STDOUT) # Enable request logging
|
250
|
+
)
|
251
|
+
```
|
252
|
+
|
253
|
+
## Error Handling
|
254
|
+
|
255
|
+
The gem provides comprehensive error handling with specific exception types:
|
256
|
+
|
257
|
+
```ruby
|
258
|
+
begin
|
259
|
+
client.users
|
260
|
+
rescue LightrateClient::UnauthorizedError => e
|
261
|
+
puts "Authentication failed: #{e.message}"
|
262
|
+
rescue LightrateClient::NotFoundError => e
|
263
|
+
puts "Resource not found: #{e.message}"
|
264
|
+
rescue LightrateClient::APIError => e
|
265
|
+
puts "API Error (#{e.status_code}): #{e.message}"
|
266
|
+
rescue LightrateClient::NetworkError => e
|
267
|
+
puts "Network error: #{e.message}"
|
268
|
+
rescue LightrateClient::TimeoutError => e
|
269
|
+
puts "Request timed out: #{e.message}"
|
270
|
+
end
|
271
|
+
```
|
272
|
+
|
273
|
+
## Development
|
274
|
+
|
275
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
276
|
+
|
277
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
278
|
+
|
279
|
+
## Contributing
|
280
|
+
|
281
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/lightbourne-technologies/lightrate-client-ruby. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/lightbourne-technologies/lightrate-client-ruby/blob/main/CODE_OF_CONDUCT.md).
|
282
|
+
|
283
|
+
## License
|
284
|
+
|
285
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
286
|
+
|
287
|
+
## Code of Conduct
|
288
|
+
|
289
|
+
Everyone interacting in the Lightrate Client Ruby project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/lightbourne-technologies/lightrate-client-ruby/blob/main/CODE_OF_CONDUCT.md).
|
data/Rakefile
ADDED
@@ -0,0 +1,146 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require 'lightrate_client'
|
5
|
+
|
6
|
+
# This example demonstrates the Lightrate Client with the new API response structure.
|
7
|
+
# The consume_tokens API now returns:
|
8
|
+
# - tokensRemaining: Number of tokens left in the bucket
|
9
|
+
# - tokensConsumed: Number of tokens consumed in this request
|
10
|
+
# - throttles: Number of throttles applied (usually 0)
|
11
|
+
# - rule: Object containing rule information (id, name, refillRate, burstRate, isDefault)
|
12
|
+
|
13
|
+
# Create a client with default bucket size
|
14
|
+
# Note: Both API key and application ID are required for all requests
|
15
|
+
client = LightrateClient::Client.new(
|
16
|
+
ENV['LIGHTRATE_API_KEY'] || 'your_api_key_here',
|
17
|
+
ENV['LIGHTRATE_APPLICATION_ID'] || 'your_application_id_here',
|
18
|
+
default_local_bucket_size: 20, # Default bucket size for all operations
|
19
|
+
logger: ENV['DEBUG'] ? Logger.new(STDOUT) : nil
|
20
|
+
)
|
21
|
+
|
22
|
+
puts "=== Lightrate Client with Local Token Buckets ==="
|
23
|
+
puts
|
24
|
+
|
25
|
+
begin
|
26
|
+
# Example 1: Email operation (uses default bucket size)
|
27
|
+
puts "1. Email operation (bucket size: 20):"
|
28
|
+
result1 = client.consume_local_bucket_token(
|
29
|
+
operation: 'operation.one',
|
30
|
+
user_identifier: 'user123'
|
31
|
+
)
|
32
|
+
|
33
|
+
puts " Success: #{result1.success}"
|
34
|
+
puts " Used local token: #{result1.used_local_token}"
|
35
|
+
puts " Bucket status: #{result1.bucket_status}"
|
36
|
+
puts
|
37
|
+
|
38
|
+
# Example 2: SMS operation (uses default bucket size)
|
39
|
+
puts "2. SMS operation (bucket size: 20):"
|
40
|
+
result2 = client.consume_local_bucket_token(
|
41
|
+
operation: 'operation.two',
|
42
|
+
user_identifier: 'user123'
|
43
|
+
)
|
44
|
+
|
45
|
+
puts " Success: #{result2.success}"
|
46
|
+
puts " Used local token: #{result2.used_local_token}"
|
47
|
+
puts " Bucket status: #{result2.bucket_status}"
|
48
|
+
puts
|
49
|
+
|
50
|
+
# Example 3: Notification operation (uses default bucket size)
|
51
|
+
puts "3. Notification operation (bucket size: 20):"
|
52
|
+
result3 = client.consume_local_bucket_token(
|
53
|
+
operation: 'operation.one',
|
54
|
+
user_identifier: 'user123'
|
55
|
+
)
|
56
|
+
|
57
|
+
puts " Success: #{result3.success}"
|
58
|
+
puts " Used local token: #{result3.used_local_token}"
|
59
|
+
puts " Bucket status: #{result3.bucket_status}"
|
60
|
+
puts
|
61
|
+
|
62
|
+
# Example 4: Path-based operation (uses default bucket size)
|
63
|
+
puts "4. Path-based operation (bucket size: 20):"
|
64
|
+
result4 = client.consume_local_bucket_token(
|
65
|
+
path: '/api/v1/emails/send',
|
66
|
+
http_method: 'POST',
|
67
|
+
user_identifier: 'user456'
|
68
|
+
)
|
69
|
+
|
70
|
+
puts " Success: #{result4.success}"
|
71
|
+
puts " Used local token: #{result4.used_local_token}"
|
72
|
+
puts " Bucket status: #{result4.bucket_status}"
|
73
|
+
puts
|
74
|
+
|
75
|
+
# Example 5: Admin path operation (uses default bucket size)
|
76
|
+
puts "5. Admin path operation (bucket size: 20):"
|
77
|
+
result5 = client.consume_local_bucket_token(
|
78
|
+
path: '/api/v1/admin/users/123/notify',
|
79
|
+
http_method: 'POST',
|
80
|
+
user_identifier: 'admin_user'
|
81
|
+
)
|
82
|
+
|
83
|
+
puts " Success: #{result5.success}"
|
84
|
+
puts " Used local token: #{result5.used_local_token}"
|
85
|
+
puts " Bucket status: #{result5.bucket_status}"
|
86
|
+
puts
|
87
|
+
|
88
|
+
# Example 6: Different HTTP methods for same path
|
89
|
+
puts "6. Different HTTP methods for same path:"
|
90
|
+
result6a = client.consume_local_bucket_token(
|
91
|
+
path: '/api/v1/users',
|
92
|
+
http_method: 'GET',
|
93
|
+
user_identifier: 'user123'
|
94
|
+
)
|
95
|
+
result6b = client.consume_local_bucket_token(
|
96
|
+
path: '/api/v1/users',
|
97
|
+
http_method: 'POST',
|
98
|
+
user_identifier: 'user123'
|
99
|
+
)
|
100
|
+
|
101
|
+
puts " GET /api/v1/users - Success: #{result6a.success}"
|
102
|
+
puts " POST /api/v1/users - Success: #{result6b.success}"
|
103
|
+
puts " (These create separate buckets due to different HTTP methods)"
|
104
|
+
puts
|
105
|
+
|
106
|
+
# Example 7: Direct API call using consume_tokens
|
107
|
+
puts "7. Direct API call using consume_tokens:"
|
108
|
+
api_response = client.consume_tokens(
|
109
|
+
operation: 'send_notification',
|
110
|
+
user_identifier: 'user789',
|
111
|
+
tokens_requested: 3
|
112
|
+
)
|
113
|
+
|
114
|
+
puts " Tokens consumed: #{api_response.tokens_consumed}"
|
115
|
+
puts " Tokens remaining: #{api_response.tokens_remaining}"
|
116
|
+
puts " Throttles: #{api_response.throttles}"
|
117
|
+
puts " Rule: #{api_response.rule.name} (ID: #{api_response.rule.id})"
|
118
|
+
puts " Is default rule: #{api_response.rule.is_default}"
|
119
|
+
puts
|
120
|
+
|
121
|
+
rescue LightrateClient::UnauthorizedError => e
|
122
|
+
puts "❌ Authentication failed: #{e.message}"
|
123
|
+
puts " Please check your API key"
|
124
|
+
rescue LightrateClient::ForbiddenError => e
|
125
|
+
puts "❌ Access denied: #{e.message}"
|
126
|
+
puts " Please check your subscription status"
|
127
|
+
rescue LightrateClient::TooManyRequestsError => e
|
128
|
+
puts "⚠️ Rate limited: #{e.message}"
|
129
|
+
puts " Please wait before making more requests"
|
130
|
+
rescue LightrateClient::NotFoundError => e
|
131
|
+
puts "❌ Rule not found: #{e.message}"
|
132
|
+
puts " Please check your operation/path configuration"
|
133
|
+
rescue LightrateClient::APIError => e
|
134
|
+
puts "❌ API Error (#{e.status_code}): #{e.message}"
|
135
|
+
rescue LightrateClient::NetworkError => e
|
136
|
+
puts "❌ Network error: #{e.message}"
|
137
|
+
puts " Please check your internet connection"
|
138
|
+
rescue LightrateClient::TimeoutError => e
|
139
|
+
puts "❌ Request timed out: #{e.message}"
|
140
|
+
rescue => e
|
141
|
+
puts "❌ Unexpected error: #{e.class}: #{e.message}"
|
142
|
+
puts e.backtrace.first(5).join("\n")
|
143
|
+
end
|
144
|
+
|
145
|
+
puts
|
146
|
+
puts "=== Example Complete ==="
|