crystal_sdk 1.0.2 → 1.0.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 1dea48c45c081f3af807b9d3d23f1c67cbc6419b
4
- data.tar.gz: 4b7c406415da2322c4c11200f2e4fb68389e2754
3
+ metadata.gz: 6ba27b0a6417d08fd9880ceebb13a9c948687a1c
4
+ data.tar.gz: 319692fbacdf2346768bac7820da9b4f5f4eeb4a
5
5
  SHA512:
6
- metadata.gz: 9ec2f1e41105835b55dd790e543bb9ba5066f4c57a1faf0817bd578e55884041fc09a51892c61d48b64d0721c10497e56648600a1546a8616171572bc5d0c4c0
7
- data.tar.gz: 99acff4789f52394971b2e0e9a585c76755fa6de6fae8991611a7431ecfa5e9e5ef174ba03d4a1c6099cab9cfa37bc8578cc6b47a7008067e5b8f420594ff4d0
6
+ metadata.gz: c9e85319e38fcbf762b87eecee617ae03a0adf3bb2a241292e24abc90a98fa052cc759165219a64d641ef78ac1f4a0ecff67acda949c36b0d565cfe8bc487e5f
7
+ data.tar.gz: b801219d333da34f0bc7425d456d781d027295f8d49ce7e875c902809d888a96eb718d7de0547d491e9af4222201cd03daadd558fba6f84d07b16ccb53c89fba
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- crystal_sdk (1.0.1)
4
+ crystal_sdk (1.0.2)
5
5
  nestful (~> 1.1)
6
6
  recursive-open-struct (~> 1.0)
7
7
 
data/README.md CHANGED
@@ -2,6 +2,8 @@
2
2
 
3
3
  This gem provides access to Crystal, the world's largest and most accurate personality database!
4
4
 
5
+ ![Recommendations Demo](docs/recommendations.png)
6
+
5
7
  Here's how to install it:
6
8
  ```bash
7
9
  $ gem install crystal_sdk
@@ -9,6 +11,8 @@ $ gem install crystal_sdk
9
11
 
10
12
  Here's how you use it:
11
13
 
14
+ ## Synchronous Flow (Recommended)
15
+
12
16
  ```ruby
13
17
  require 'crystal_sdk'
14
18
 
@@ -34,13 +38,13 @@ begin
34
38
 
35
39
  print "Recommendations: #{profile.recommendations}"
36
40
 
37
- rescue CrystalSDK::Profile::NotFoundError => e
41
+ rescue CrystalSDK::Profile::NotFoundError
38
42
  print "No profile was found"
39
43
 
40
44
  rescue CrystalSDK::Profile::NotFoundYetError => e
41
45
  print "Profile search exceeded time limit: #{e.request.id}"
42
46
 
43
- rescue CrystalSDK::Profile::RateLimitHitError => e
47
+ rescue CrystalSDK::Profile::RateLimitHitError
44
48
  print "The organization's API rate limit was hit"
45
49
 
46
50
  rescue CrystalSDK::Profile::NotAuthedError => e
@@ -51,3 +55,95 @@ rescue StandardError => e
51
55
 
52
56
  end
53
57
  ```
58
+
59
+ ## Asynchronous Flow (For bulk analysis)
60
+
61
+ When requesting large amounts of profiles, or when wanting to have more fine-grained control over performance, we recommend using our asynchronous flow. It allows us to process your requests in parallel and get the information back to you more quickly. There are a couple options for using this capability.
62
+
63
+ ### Option 1: Polling (Small Lists + Realtime Enrichment)
64
+ The option we use internally in the SDK, is to poll for request information periodically until a set timeout has been reached:
65
+
66
+ ```ruby
67
+ MAX_RETRIES = 10
68
+ PAUSE_IN_SECONDS = 3
69
+
70
+ # Start the request
71
+ query = { first_name: "Drew", ... }
72
+ request = CrystalSDK::Profile::Request.from_search(query)
73
+
74
+ # Poll server until request finishes
75
+ MAX_RETRIES.times do
76
+
77
+ # If the request hasn't finished, wait and loop again
78
+ unless request.did_finish?
79
+ sleep(PAUSE_IN_SECONDS)
80
+ next
81
+ end
82
+
83
+ # Get profile information
84
+ if request.did_find_profile?
85
+ profile = Profile.from_request(request)
86
+ end
87
+
88
+ break
89
+ end
90
+
91
+ # Use the profile if it was found
92
+ profile
93
+ ```
94
+
95
+ Polling can be extended to poll for multiple profiles. It gives the efficiency of our parallel processing, while writing code that behaves synchronously.
96
+
97
+ This option is great if you want information as fast as possible while keeping open network connections and code complexity to a minimum. It is especially useful if you are requesting multiple profiles and can process the profiles one at a time, as each individual profile comes in (as opposed to waiting for all of them to come in before processing anything).
98
+
99
+
100
+ ### Option 2: Background Processing (Large Lists + Passive Enrichment)
101
+
102
+ Sometimes, it isn't important to have the profile information immediately. Especially when dealing with larger jobs or passive data enrichment. In that case, we allow you to save the Request ID and pull information from the request at a later time via this ID.
103
+
104
+ ```ruby
105
+
106
+ # Send the request to Crystal
107
+ profile_request = CrystalSDK::Profile::Request.from_search(query)
108
+
109
+ # Pull out the Profile Request ID (string)
110
+ profile_request_id = profile_request.id
111
+
112
+ # Save the Request ID somewhere (to a database or background job, for example)
113
+ ...
114
+
115
+ # Later, pull up the Request ID and pull information about it
116
+ backgrounded_request = CrystalSDK::Profile::Request.new(profile_request_id)
117
+
118
+ if backgrounded_request.did_finish? && backgrounded_request.did_find_profile?
119
+ profile = backgrounded_request.profile
120
+ ...
121
+ end
122
+ ```
123
+
124
+ We try and store your request for a few days after the request has been started. Your Request ID should work when you try to pull information from it for at least that period of time!
125
+
126
+
127
+ ## Contributing
128
+
129
+ - Clone the repository:
130
+
131
+ `git clone git@github.com:crystal-project-inc/ruby_sdk.git`
132
+
133
+ - Run rspec tests:
134
+
135
+ `rspec`
136
+
137
+ - Open up an IRB console with the gem loaded to play around with it:
138
+
139
+ `rake console`
140
+
141
+ - Make a code change
142
+
143
+ - Check that the tests still pass
144
+
145
+ - Make a pull request!
146
+
147
+ We will review the Pull Request to make sure that it does not break the external specification of the gem and that it fits with the overall mission of the SDK!
148
+
149
+ We also encourage people to build further libraries that utilize our SDK and extend the use of the Connect API!
Binary file
@@ -21,21 +21,23 @@ module CrystalSDK
21
21
 
22
22
  def search(query, timeout: 30)
23
23
  request = nil
24
+ profile = nil
24
25
 
25
- begin
26
- Timeout.timeout(timeout) do
27
- request = Profile::Request.from_search(query)
26
+ Timeout.timeout(timeout) do
27
+ request = Profile::Request.from_search(query)
28
28
 
29
- loop do
30
- sleep(2) && next unless request.did_finish?
29
+ loop do
30
+ sleep(2) && next unless request.did_finish?
31
+ raise NotFoundError unless request.did_find_profile?
31
32
 
32
- raise NotFoundError unless request.did_find_profile?
33
- return Profile.from_request(request)
34
- end
33
+ profile = Profile.from_request(request)
34
+ break
35
35
  end
36
- rescue Timeout::Error
37
- raise NotFoundYetError.new(request)
38
36
  end
37
+
38
+ profile
39
+ rescue Timeout::Error
40
+ raise NotFoundYetError.new(request)
39
41
  end
40
42
  end
41
43
  end
@@ -56,6 +56,10 @@ module CrystalSDK
56
56
  def did_finish?
57
57
  status = fetch_status
58
58
  status == 'complete' || status == 'error'
59
+ rescue Profile::NotFoundError
60
+ true
61
+ rescue Profile::NotAuthedError
62
+ true
59
63
  end
60
64
 
61
65
  def did_find_profile?
@@ -63,6 +67,8 @@ module CrystalSDK
63
67
 
64
68
  info = fetch_request_info
65
69
  !info[:data][:info][:error]
70
+ rescue Profile::NotFoundError
71
+ false
66
72
  end
67
73
 
68
74
  def profile_info
@@ -1,3 +1,3 @@
1
1
  module CrystalSDK
2
- VERSION = '1.0.2'.freeze
2
+ VERSION = '1.0.3'.freeze
3
3
  end
@@ -156,6 +156,35 @@ describe CrystalSDK::Profile::Request do
156
156
  it { is_expected.to eql(true) }
157
157
  end
158
158
 
159
+ context '#fetch_status raises NotFoundError' do
160
+ before(:each) do
161
+ allow(request).to receive(:fetch_status)
162
+ .and_raise(CrystalSDK::Profile::NotFoundError)
163
+ end
164
+
165
+ it { is_expected.to eql(true) }
166
+ end
167
+
168
+ context '#fetch_status raises NotAuthedError' do
169
+ before(:each) do
170
+ allow(request).to receive(:fetch_status)
171
+ .and_raise(CrystalSDK::Profile::NotAuthedError.new('SomeToken'))
172
+ end
173
+
174
+ it { is_expected.to eql(true) }
175
+ end
176
+
177
+ context '#fetch_status raises an unexpected error' do
178
+ before(:each) do
179
+ allow(request).to receive(:fetch_status)
180
+ .and_raise('SomeError')
181
+ end
182
+
183
+ it 'should not suppress it' do
184
+ expect { subject }.to raise_error('SomeError')
185
+ end
186
+ end
187
+
159
188
  context '#fetch_status returns something else' do
160
189
  before(:each) do
161
190
  allow(request).to receive(:fetch_status).and_return('something')
@@ -177,6 +206,26 @@ describe CrystalSDK::Profile::Request do
177
206
  end
178
207
  end
179
208
 
209
+ context '#fetch_request_info raises NotFoundError' do
210
+ before(:each) do
211
+ allow(request).to receive(:fetch_request_info)
212
+ .and_raise(CrystalSDK::Profile::NotFoundError)
213
+ end
214
+
215
+ it { is_expected.to eql(false) }
216
+ end
217
+
218
+ context '#fetch_request_info raises unexpected error' do
219
+ before(:each) do
220
+ allow(request).to receive(:fetch_request_info)
221
+ .and_raise(CrystalSDK::Profile::NotAuthedError.new('SomeToken'))
222
+ end
223
+
224
+ it 'should not suppress it' do
225
+ expect { subject }.to raise_error(CrystalSDK::Profile::NotAuthedError)
226
+ end
227
+ end
228
+
180
229
  context '#did_finish? is true' do
181
230
  before(:each) do
182
231
  allow(request).to receive(:did_finish?).and_return(true)
@@ -43,11 +43,11 @@ describe CrystalSDK::Profile do
43
43
  .and_return(req)
44
44
 
45
45
  allow(req).to receive(:did_finish?)
46
- .and_raise(StandardError.new)
46
+ .and_raise('SomeError')
47
47
  end
48
48
 
49
49
  it 'should raise exception' do
50
- expect { subject }.to raise_error
50
+ expect { subject }.to raise_error('SomeError')
51
51
  end
52
52
  end
53
53
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: crystal_sdk
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.2
4
+ version: 1.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Cory Finger
@@ -82,6 +82,7 @@ files:
82
82
  - README.md
83
83
  - Rakefile
84
84
  - crystal_sdk.gemspec
85
+ - docs/recommendations.png
85
86
  - lib/crystal_sdk.rb
86
87
  - lib/crystal_sdk/api.rb
87
88
  - lib/crystal_sdk/base.rb