seam 2.18.0 → 2.20.0
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 +4 -4
- data/Gemfile.lock +1 -1
- data/README.md +98 -0
- data/lib/seam/http_single_workspace.rb +5 -0
- data/lib/seam/paginator.rb +106 -0
- data/lib/seam/request.rb +2 -0
- data/lib/seam/routes/clients/user_identities.rb +6 -0
- data/lib/seam/routes/resources/index.rb +1 -0
- data/lib/seam/routes/resources/instant_key.rb +11 -0
- data/lib/seam/version.rb +1 -1
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6a8ea18ff74b9c148761bee6d9f263d4f724677e515724043dd7eccd4cfe3d3b
|
4
|
+
data.tar.gz: a59b64d0e2b47ca9c864a397e077588d2314f0ecec32a7a6fe4214148e72aa76
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ee6c631bff63f2df1f4b9978066cb1c9552ce7693d76569f0769c76e4af2ff43fb9c3cbbf055467e4068fe7f5e3d9b0ee48a16d62631b5c709458008164533e7
|
7
|
+
data.tar.gz: 3154d05cbedde8d06e6f277a81b47ef325b0bdc996875b665a2fddafd1b94e3cab08b134f6b41f503acc0ef97aa7c078eea78765f416373b11063232046821dc
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -27,6 +27,11 @@ accurate and fully typed.
|
|
27
27
|
- [API Key](#api-key)
|
28
28
|
- [Personal Access Token](#personal-access-token)
|
29
29
|
- [Action Attempts](#action-attempts)
|
30
|
+
- [Pagination](#pagination)
|
31
|
+
- [Manually fetch pages with the next_page_cursor](#manually-fetch-pages-with-the-next_page_cursor)
|
32
|
+
- [Resume pagination](#resume-pagination)
|
33
|
+
- [Iterate over all resources](#iterate-over-all-resources)
|
34
|
+
- [Return all resources across all pages as a list](#return-all-resources-across-all-pages-as-a-list)
|
30
35
|
- [Interacting with Multiple Workspaces](#interacting-with-multiple-workspaces)
|
31
36
|
- [Webhooks](#webhooks)
|
32
37
|
- [Advanced Usage](#advanced-usage)
|
@@ -215,6 +220,99 @@ rescue Seam::ActionAttemptTimeoutError
|
|
215
220
|
end
|
216
221
|
```
|
217
222
|
|
223
|
+
### Pagination
|
224
|
+
|
225
|
+
Some Seam API endpoints that return lists of resources support pagination.
|
226
|
+
Use the `Seam::Paginator` class to fetch and process resources across multiple pages.
|
227
|
+
|
228
|
+
#### Manually fetch pages with the next_page_cursor
|
229
|
+
|
230
|
+
```ruby
|
231
|
+
require "seam"
|
232
|
+
|
233
|
+
seam = Seam.new
|
234
|
+
|
235
|
+
paginator = seam.create_paginator(seam.connected_accounts.method(:list), {limit: 20})
|
236
|
+
|
237
|
+
connected_accounts, pagination = paginator.first_page
|
238
|
+
|
239
|
+
if pagination.has_next_page?
|
240
|
+
more_connected_accounts, _ = paginator.next_page(pagination.next_page_cursor)
|
241
|
+
end
|
242
|
+
```
|
243
|
+
|
244
|
+
#### Resume pagination
|
245
|
+
|
246
|
+
Get the first page on initial load and store the state (e.g., in memory or a file):
|
247
|
+
|
248
|
+
```ruby
|
249
|
+
require "seam"
|
250
|
+
require "json"
|
251
|
+
|
252
|
+
seam = Seam.new
|
253
|
+
|
254
|
+
params = {limit: 20}
|
255
|
+
paginator = seam.create_paginator(seam.connected_accounts.method(:list), params)
|
256
|
+
|
257
|
+
connected_accounts, pagination = paginator.first_page
|
258
|
+
|
259
|
+
# Example: Store state for later use (e.g., in a file or database)
|
260
|
+
pagination_state = {
|
261
|
+
"params" => params,
|
262
|
+
"next_page_cursor" => pagination.next_page_cursor,
|
263
|
+
"has_next_page" => pagination.has_next_page?
|
264
|
+
}
|
265
|
+
File.write("/tmp/seam_connected_accounts_list.json", JSON.dump(pagination_state))
|
266
|
+
```
|
267
|
+
|
268
|
+
Get the next page at a later time using the stored state:
|
269
|
+
|
270
|
+
```ruby
|
271
|
+
require "seam"
|
272
|
+
require "json"
|
273
|
+
|
274
|
+
seam = Seam.new
|
275
|
+
|
276
|
+
# Example: Load state from where it was stored
|
277
|
+
pagination_state_json = File.read("/tmp/seam_connected_accounts_list.json")
|
278
|
+
pagination_state = JSON.parse(pagination_state_json)
|
279
|
+
|
280
|
+
if pagination_state["has_next_page"]
|
281
|
+
paginator = seam.create_paginator(
|
282
|
+
seam.connected_accounts.method(:list), pagination_state["params"]
|
283
|
+
)
|
284
|
+
more_connected_accounts, _ = paginator.next_page(
|
285
|
+
pagination_state["next_page_cursor"]
|
286
|
+
)
|
287
|
+
end
|
288
|
+
```
|
289
|
+
|
290
|
+
#### Iterate over all resources
|
291
|
+
|
292
|
+
```ruby
|
293
|
+
require "seam"
|
294
|
+
|
295
|
+
seam = Seam.new
|
296
|
+
|
297
|
+
paginator = seam.create_paginator(seam.connected_accounts.method(:list), {limit: 20})
|
298
|
+
|
299
|
+
paginator.flatten.each do |account|
|
300
|
+
puts account.account_type_display_name
|
301
|
+
end
|
302
|
+
```
|
303
|
+
|
304
|
+
#### Return all resources across all pages as a list
|
305
|
+
|
306
|
+
```ruby
|
307
|
+
require "seam"
|
308
|
+
|
309
|
+
seam = Seam.new
|
310
|
+
|
311
|
+
paginator = seam.create_paginator(seam.connected_accounts.method(:list), {limit: 20})
|
312
|
+
|
313
|
+
all_connected_accounts = paginator.flatten_to_list
|
314
|
+
```
|
315
|
+
|
218
316
|
### Interacting with Multiple Workspaces
|
219
317
|
|
220
318
|
Some Seam API endpoints interact with multiple workspaces. The `Seam::Http::SeamMultiWorkspace` client is not bound to a specific workspace and may use those endpoints with a personal access token authentication method.
|
@@ -7,6 +7,7 @@ require_relative "routes/clients/index"
|
|
7
7
|
require_relative "routes/routes"
|
8
8
|
require_relative "version"
|
9
9
|
require_relative "deep_hash_accessor"
|
10
|
+
require_relative "paginator"
|
10
11
|
|
11
12
|
module Seam
|
12
13
|
module Http
|
@@ -32,6 +33,10 @@ module Seam
|
|
32
33
|
Seam::LTS_VERSION
|
33
34
|
end
|
34
35
|
|
36
|
+
def create_paginator(request, params = {})
|
37
|
+
Paginator.new(request, params)
|
38
|
+
end
|
39
|
+
|
35
40
|
def self.from_api_key(api_key, endpoint: nil, wait_for_action_attempt: false, faraday_options: {}, faraday_retry_options: {})
|
36
41
|
new(api_key: api_key, endpoint: endpoint, wait_for_action_attempt: wait_for_action_attempt,
|
37
42
|
faraday_options: faraday_options, faraday_retry_options: faraday_retry_options)
|
@@ -0,0 +1,106 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "faraday"
|
4
|
+
require_relative "http"
|
5
|
+
|
6
|
+
module Seam
|
7
|
+
THREAD_CONTEXT_KEY = :seam_pagination_context
|
8
|
+
PaginationContext = Struct.new(:pagination)
|
9
|
+
|
10
|
+
class Paginator
|
11
|
+
def initialize(request, params = {})
|
12
|
+
raise ArgumentError, "request must be a Method" unless request.is_a?(Method)
|
13
|
+
raise ArgumentError, "params must be a Hash" unless params.is_a?(Hash)
|
14
|
+
|
15
|
+
@request = request
|
16
|
+
@params = params.transform_keys(&:to_sym)
|
17
|
+
end
|
18
|
+
|
19
|
+
def first_page
|
20
|
+
fetch_page(@params)
|
21
|
+
end
|
22
|
+
|
23
|
+
def next_page(next_page_cursor)
|
24
|
+
if next_page_cursor.nil? || next_page_cursor.empty?
|
25
|
+
raise ArgumentError,
|
26
|
+
"Cannot get the next page with a nil or empty next_page_cursor."
|
27
|
+
end
|
28
|
+
|
29
|
+
fetch_page(@params.merge(page_cursor: next_page_cursor))
|
30
|
+
end
|
31
|
+
|
32
|
+
def flatten_to_list
|
33
|
+
all_items = []
|
34
|
+
current_items, pagination = first_page
|
35
|
+
|
36
|
+
all_items.concat(current_items) if current_items
|
37
|
+
|
38
|
+
while pagination&.has_next_page? && (cursor = pagination.next_page_cursor)
|
39
|
+
current_items, pagination = next_page(cursor)
|
40
|
+
all_items.concat(current_items) if current_items
|
41
|
+
end
|
42
|
+
|
43
|
+
all_items
|
44
|
+
end
|
45
|
+
|
46
|
+
def flatten
|
47
|
+
Enumerator.new do |yielder|
|
48
|
+
current_items, pagination = first_page
|
49
|
+
current_items&.each { |item| yielder << item }
|
50
|
+
|
51
|
+
while pagination&.has_next_page? && (cursor = pagination.next_page_cursor)
|
52
|
+
current_items, pagination = next_page(cursor)
|
53
|
+
current_items&.each { |item| yielder << item }
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
private
|
59
|
+
|
60
|
+
def fetch_page(params)
|
61
|
+
context = PaginationContext.new(nil)
|
62
|
+
Thread.current[THREAD_CONTEXT_KEY] = context
|
63
|
+
|
64
|
+
begin
|
65
|
+
res_data = @request.call(**params)
|
66
|
+
pagination_result = Pagination.from_hash(context.pagination)
|
67
|
+
[res_data, pagination_result]
|
68
|
+
ensure
|
69
|
+
Thread.current[THREAD_CONTEXT_KEY] = nil
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
Pagination = Struct.new(:has_next_page, :next_page_cursor, :next_page_url, keyword_init: true) do
|
75
|
+
def self.from_hash(hash)
|
76
|
+
return nil unless hash.is_a?(Hash) && !hash.empty?
|
77
|
+
|
78
|
+
new(
|
79
|
+
has_next_page: hash.fetch("has_next_page", false),
|
80
|
+
next_page_cursor: hash.fetch("next_page_cursor", nil),
|
81
|
+
next_page_url: hash.fetch("next_page_url", nil)
|
82
|
+
)
|
83
|
+
end
|
84
|
+
|
85
|
+
def has_next_page?
|
86
|
+
has_next_page == true
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
class PaginationMiddleware < Faraday::Middleware
|
91
|
+
def on_complete(env)
|
92
|
+
context = Thread.current[THREAD_CONTEXT_KEY]
|
93
|
+
return unless context.is_a?(PaginationContext)
|
94
|
+
|
95
|
+
pagination_hash = extract_pagination(env)
|
96
|
+
context.pagination = pagination_hash if pagination_hash
|
97
|
+
end
|
98
|
+
|
99
|
+
private
|
100
|
+
|
101
|
+
def extract_pagination(env)
|
102
|
+
body = env[:body]
|
103
|
+
body["pagination"] if body.is_a?(Hash) && body.key?("pagination")
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
data/lib/seam/request.rb
CHANGED
@@ -4,6 +4,7 @@ require "faraday"
|
|
4
4
|
require "faraday/retry"
|
5
5
|
require_relative "lts_version"
|
6
6
|
require_relative "version"
|
7
|
+
require_relative "paginator"
|
7
8
|
|
8
9
|
module Seam
|
9
10
|
module Http
|
@@ -25,6 +26,7 @@ module Seam
|
|
25
26
|
|
26
27
|
Faraday.new(options) do |builder|
|
27
28
|
builder.request :json
|
29
|
+
builder.use Seam::PaginationMiddleware
|
28
30
|
builder.response :json
|
29
31
|
builder.use ResponseMiddleware
|
30
32
|
builder.request :retry, faraday_retry_options
|
@@ -30,6 +30,12 @@ module Seam
|
|
30
30
|
nil
|
31
31
|
end
|
32
32
|
|
33
|
+
def generate_instant_key(user_identity_id:)
|
34
|
+
res = @client.post("/user_identities/generate_instant_key", {user_identity_id: user_identity_id}.compact)
|
35
|
+
|
36
|
+
Seam::Resources::InstantKey.load_from_response(res.body["instant_key"])
|
37
|
+
end
|
38
|
+
|
33
39
|
def get(user_identity_id: nil, user_identity_key: nil)
|
34
40
|
res = @client.post("/user_identities/get", {user_identity_id: user_identity_id, user_identity_key: user_identity_key}.compact)
|
35
41
|
|
@@ -22,6 +22,7 @@ require_relative "device"
|
|
22
22
|
require_relative "device_provider"
|
23
23
|
require_relative "enrollment_automation"
|
24
24
|
require_relative "event"
|
25
|
+
require_relative "instant_key"
|
25
26
|
require_relative "network"
|
26
27
|
require_relative "noise_threshold"
|
27
28
|
require_relative "pagination"
|
@@ -0,0 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Seam
|
4
|
+
module Resources
|
5
|
+
class InstantKey < BaseResource
|
6
|
+
attr_accessor :client_session_id, :instant_key_id, :instant_key_url, :user_identity_id, :workspace_id
|
7
|
+
|
8
|
+
date_accessor :created_at, :expires_at
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
data/lib/seam/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: seam
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.20.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Seam Labs, Inc.
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2025-
|
11
|
+
date: 2025-05-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: faraday
|
@@ -200,6 +200,7 @@ files:
|
|
200
200
|
- lib/seam/http_single_workspace.rb
|
201
201
|
- lib/seam/lts_version.rb
|
202
202
|
- lib/seam/options.rb
|
203
|
+
- lib/seam/paginator.rb
|
203
204
|
- lib/seam/parse_options.rb
|
204
205
|
- lib/seam/request.rb
|
205
206
|
- lib/seam/routes/clients/access_codes.rb
|
@@ -255,6 +256,7 @@ files:
|
|
255
256
|
- lib/seam/routes/resources/enrollment_automation.rb
|
256
257
|
- lib/seam/routes/resources/event.rb
|
257
258
|
- lib/seam/routes/resources/index.rb
|
259
|
+
- lib/seam/routes/resources/instant_key.rb
|
258
260
|
- lib/seam/routes/resources/network.rb
|
259
261
|
- lib/seam/routes/resources/noise_threshold.rb
|
260
262
|
- lib/seam/routes/resources/pagination.rb
|