greenhouse_api 0.3.0 → 0.3.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 +4 -4
- data/lib/greenhouse_api/base_client.rb +116 -0
- data/lib/greenhouse_api/client.rb +28 -94
- data/lib/greenhouse_api/resources/candidates.rb +17 -0
- data/lib/greenhouse_api/resources/offers.rb +22 -0
- data/lib/greenhouse_api/resources/users.rb +52 -0
- data/lib/greenhouse_api/version.rb +1 -1
- metadata +10 -6
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 9ff456467fd8aef10884057caf6e3b2d7dc2ea9976b64ffa2b2062b255e9b560
|
|
4
|
+
data.tar.gz: 78db6ff1cf53e4dc3d836ad7b40f466ed96c34d5fd5b2f7bc10ee811e119c3eb
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: '0834e93de4a38950e2d2a958690fce1429e86a96d3ca3d74150c1822c0efa23e143b281e242d56ea26cd4d7250e77a0ad2bcd226f944d860746b9db8e5b322ca'
|
|
7
|
+
data.tar.gz: 65808f8f66a3aadbee453d51bc57a713159e9611772f20f28d9074dcad8fc6b34e436604942dc0aff46016461c4f7415458cfcf347723c7f6fa85048405e1988
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
# typed: true
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
require 'faraday'
|
|
5
|
+
require 'base64'
|
|
6
|
+
require 'json'
|
|
7
|
+
require 'sorbet-runtime'
|
|
8
|
+
|
|
9
|
+
module GreenhouseApi
|
|
10
|
+
class Response
|
|
11
|
+
attr_reader :headers, :body, :status
|
|
12
|
+
|
|
13
|
+
def initialize(headers:, body:, status:)
|
|
14
|
+
@headers = headers
|
|
15
|
+
@body = body
|
|
16
|
+
@status = status
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
class BaseClient
|
|
21
|
+
extend T::Sig
|
|
22
|
+
|
|
23
|
+
MAX_PER_PAGE = 500
|
|
24
|
+
API_URL = 'https://harvest.greenhouse.io'
|
|
25
|
+
|
|
26
|
+
def initialize(api_key)
|
|
27
|
+
@api_key = api_key
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def headers
|
|
31
|
+
credential = Base64.strict_encode64(@api_key + ':')
|
|
32
|
+
|
|
33
|
+
{
|
|
34
|
+
'Authorization' => 'Basic ' + credential,
|
|
35
|
+
}
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def request(http_method:, headers:, endpoint:, params: {}, body: {}, api_version: 'v1')
|
|
39
|
+
response = Faraday.public_send(http_method) do |request|
|
|
40
|
+
request.headers = headers
|
|
41
|
+
request.path = "#{API_URL}/#{api_version}/#{endpoint}"
|
|
42
|
+
request.params = params
|
|
43
|
+
request.body = body
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
Response.new(
|
|
47
|
+
body: response.body && !response.body.empty? ? JSON.parse(response.body) : '',
|
|
48
|
+
headers: response.headers,
|
|
49
|
+
status: response.status
|
|
50
|
+
)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def compose_response(response)
|
|
54
|
+
if [200, 201].include?(response&.status)
|
|
55
|
+
Response.new(
|
|
56
|
+
body: response.body,
|
|
57
|
+
headers: response.headers,
|
|
58
|
+
status: response.status
|
|
59
|
+
)
|
|
60
|
+
else
|
|
61
|
+
response
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def list_many(resource, params = {})
|
|
66
|
+
limit = params.delete(:limit)
|
|
67
|
+
page = params[:page] || 1
|
|
68
|
+
data = []
|
|
69
|
+
response = nil
|
|
70
|
+
|
|
71
|
+
loop do
|
|
72
|
+
per_page = if params[:per_page]
|
|
73
|
+
params[:per_page]
|
|
74
|
+
else
|
|
75
|
+
limit ? [limit - data.length, MAX_PER_PAGE].min : MAX_PER_PAGE
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
response = request(
|
|
79
|
+
http_method: :get,
|
|
80
|
+
headers: headers,
|
|
81
|
+
endpoint: resource,
|
|
82
|
+
params: params.merge(page: page, per_page: per_page)
|
|
83
|
+
)
|
|
84
|
+
break if response.status != 200
|
|
85
|
+
|
|
86
|
+
data.concat(response.body)
|
|
87
|
+
|
|
88
|
+
if last_page?(response) || data_limit_reached?(data, limit) || params[:page]
|
|
89
|
+
break
|
|
90
|
+
else
|
|
91
|
+
page += 1
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
if response.status == 200
|
|
96
|
+
Response.new(
|
|
97
|
+
body: data,
|
|
98
|
+
headers: response.headers,
|
|
99
|
+
status: response.status
|
|
100
|
+
)
|
|
101
|
+
else
|
|
102
|
+
response
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
private
|
|
107
|
+
|
|
108
|
+
def last_page?(response)
|
|
109
|
+
!response.headers['link'].to_s.include?('rel="next"')
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
def data_limit_reached?(data, limit)
|
|
113
|
+
limit && data.length >= limit
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
end
|
|
@@ -1,125 +1,59 @@
|
|
|
1
1
|
# typed: false
|
|
2
2
|
# frozen_string_literal: true
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
4
|
+
require_relative 'base_client'
|
|
5
|
+
require_relative 'resources/candidates'
|
|
6
|
+
require_relative 'resources/offers'
|
|
7
|
+
require_relative 'resources/users'
|
|
7
8
|
|
|
8
9
|
module GreenhouseApi
|
|
9
|
-
class Response
|
|
10
|
-
attr_reader :headers, :body, :status
|
|
11
|
-
|
|
12
|
-
def initialize(headers:, body:, status:)
|
|
13
|
-
@headers = headers
|
|
14
|
-
@body = body
|
|
15
|
-
@status = status
|
|
16
|
-
end
|
|
17
|
-
end
|
|
18
|
-
|
|
19
10
|
class Client
|
|
20
|
-
MAX_PER_PAGE = 500
|
|
21
|
-
API_URL = 'https://harvest.greenhouse.io/v1'
|
|
22
|
-
|
|
23
11
|
def initialize(api_key)
|
|
24
12
|
@api_key = api_key
|
|
25
13
|
end
|
|
26
14
|
|
|
15
|
+
def list_many(resource, params = {})
|
|
16
|
+
base_client.list_many(resource, params)
|
|
17
|
+
end
|
|
18
|
+
|
|
27
19
|
def list_candidates(params = {})
|
|
28
|
-
|
|
20
|
+
candidates_client.list_all(params)
|
|
29
21
|
end
|
|
30
22
|
|
|
31
23
|
def get_current_offer_for_application(application_id)
|
|
32
|
-
|
|
33
|
-
http_method: :get,
|
|
34
|
-
headers: headers,
|
|
35
|
-
endpoint: "applications/#{application_id}/offers/current_offer",
|
|
36
|
-
params: {}
|
|
37
|
-
)
|
|
38
|
-
|
|
39
|
-
if response.status == 200
|
|
40
|
-
Response.new(
|
|
41
|
-
body: response.body,
|
|
42
|
-
headers: response.headers,
|
|
43
|
-
status: response.status
|
|
44
|
-
)
|
|
45
|
-
else
|
|
46
|
-
response
|
|
47
|
-
end
|
|
24
|
+
offers_client.get_current_offer_for_application(application_id)
|
|
48
25
|
end
|
|
49
26
|
|
|
50
|
-
def
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
data = []
|
|
54
|
-
response = nil
|
|
55
|
-
|
|
56
|
-
loop do
|
|
57
|
-
per_page = if params[:per_page]
|
|
58
|
-
params[:per_page]
|
|
59
|
-
else
|
|
60
|
-
limit ? [limit - data.length, MAX_PER_PAGE].min : MAX_PER_PAGE
|
|
61
|
-
end
|
|
62
|
-
|
|
63
|
-
response = request(
|
|
64
|
-
http_method: :get,
|
|
65
|
-
headers: headers,
|
|
66
|
-
endpoint: resource,
|
|
67
|
-
params: params.merge(page: page, per_page: per_page)
|
|
68
|
-
)
|
|
69
|
-
break if response.status != 200
|
|
70
|
-
|
|
71
|
-
data.concat(response.body)
|
|
27
|
+
def create_user(first_name:, last_name:, email:, on_behalf_of_id:, **additional_args)
|
|
28
|
+
users_client.create_user(first_name: first_name, last_name: last_name, email: email, on_behalf_of_id: on_behalf_of_id, **additional_args)
|
|
29
|
+
end
|
|
72
30
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
page += 1
|
|
77
|
-
end
|
|
78
|
-
end
|
|
31
|
+
def disable_user(user, on_behalf_of_id)
|
|
32
|
+
users_client.disable_user(user, on_behalf_of_id)
|
|
33
|
+
end
|
|
79
34
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
body: data,
|
|
83
|
-
headers: response.headers,
|
|
84
|
-
status: response.status
|
|
85
|
-
)
|
|
86
|
-
else
|
|
87
|
-
response
|
|
88
|
-
end
|
|
35
|
+
def enable_user(user, on_behalf_of_id)
|
|
36
|
+
users_client.enable_user(user, on_behalf_of_id)
|
|
89
37
|
end
|
|
90
38
|
|
|
91
39
|
private
|
|
92
40
|
|
|
93
|
-
|
|
94
|
-
!response.headers['link'].to_s.include?('rel="next"')
|
|
95
|
-
end
|
|
41
|
+
attr_accessor :api_key
|
|
96
42
|
|
|
97
|
-
def
|
|
98
|
-
|
|
43
|
+
def candidates_client
|
|
44
|
+
@candidates_client ||= Resources::Candidates.new(api_key)
|
|
99
45
|
end
|
|
100
46
|
|
|
101
|
-
def
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
{
|
|
105
|
-
'Authorization' => 'Basic ' + credential,
|
|
106
|
-
}
|
|
47
|
+
def offers_client
|
|
48
|
+
@offers_client ||= Resources::Offers.new(api_key)
|
|
107
49
|
end
|
|
108
50
|
|
|
109
|
-
def
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
request.path = "#{API_URL}/#{endpoint}"
|
|
113
|
-
request.params = params
|
|
114
|
-
request.body = body
|
|
115
|
-
end
|
|
51
|
+
def users_client
|
|
52
|
+
@users_client ||= Resources::Users.new(api_key)
|
|
53
|
+
end
|
|
116
54
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
headers: response.headers,
|
|
120
|
-
status: response.status
|
|
121
|
-
)
|
|
55
|
+
def base_client
|
|
56
|
+
@base_client ||= BaseClient.new(api_key)
|
|
122
57
|
end
|
|
123
58
|
end
|
|
124
59
|
end
|
|
125
|
-
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# typed: true
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
require 'sorbet-runtime'
|
|
5
|
+
|
|
6
|
+
module GreenhouseApi
|
|
7
|
+
module Resources
|
|
8
|
+
class Candidates < BaseClient
|
|
9
|
+
extend T::Sig
|
|
10
|
+
|
|
11
|
+
sig { params(params: T.nilable(T::Hash[String, T.any(Integer, String)])).returns(Response) }
|
|
12
|
+
def list_all(params = {})
|
|
13
|
+
list_many('candidates', params)
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# typed: true
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
require 'sorbet-runtime'
|
|
5
|
+
|
|
6
|
+
module GreenhouseApi
|
|
7
|
+
module Resources
|
|
8
|
+
class Offers < BaseClient
|
|
9
|
+
extend T::Sig
|
|
10
|
+
|
|
11
|
+
sig { params(application_id: String).returns(Response) }
|
|
12
|
+
def get_current_offer_for_application(application_id)
|
|
13
|
+
response = request(
|
|
14
|
+
http_method: :get,
|
|
15
|
+
headers: headers,
|
|
16
|
+
endpoint: "applications/#{application_id}/offers/current_offer",
|
|
17
|
+
)
|
|
18
|
+
compose_response(response)
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# typed: true
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
require 'sorbet-runtime'
|
|
5
|
+
|
|
6
|
+
module GreenhouseApi
|
|
7
|
+
module Resources
|
|
8
|
+
class Users < BaseClient
|
|
9
|
+
extend T::Sig
|
|
10
|
+
|
|
11
|
+
ON_BEHALF_OF = 'On-Behalf-Of'
|
|
12
|
+
|
|
13
|
+
sig { params(first_name: String, last_name: String, email: String, on_behalf_of_id: String, additional_args: T.any(T::Boolean, String)).returns(Response) }
|
|
14
|
+
def create_user(first_name:, last_name:, email:, on_behalf_of_id:, **additional_args)
|
|
15
|
+
body = { first_name: first_name, last_name: last_name, email: email }.merge(additional_args).to_json
|
|
16
|
+
response = request(
|
|
17
|
+
http_method: :post,
|
|
18
|
+
headers: headers.merge(ON_BEHALF_OF => on_behalf_of_id),
|
|
19
|
+
endpoint: "users",
|
|
20
|
+
body: body
|
|
21
|
+
)
|
|
22
|
+
compose_response(response)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
sig { params(user: T::Hash[String, T.any(Integer, String)], on_behalf_of_id: String).returns(Response) }
|
|
26
|
+
def disable_user(user, on_behalf_of_id)
|
|
27
|
+
body = { user: user }.to_json
|
|
28
|
+
response = request(
|
|
29
|
+
http_method: :patch,
|
|
30
|
+
headers: headers.merge(ON_BEHALF_OF => on_behalf_of_id),
|
|
31
|
+
endpoint: "users/disable",
|
|
32
|
+
body: body,
|
|
33
|
+
api_version: 'v2'
|
|
34
|
+
)
|
|
35
|
+
compose_response(response)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
sig { params(user: T::Hash[String, T.any(Integer, String)], on_behalf_of_id: String).returns(Response) }
|
|
39
|
+
def enable_user(user, on_behalf_of_id)
|
|
40
|
+
body = { user: user }.to_json
|
|
41
|
+
response = request(
|
|
42
|
+
http_method: :patch,
|
|
43
|
+
headers: headers.merge(ON_BEHALF_OF => on_behalf_of_id),
|
|
44
|
+
endpoint: "users/enable",
|
|
45
|
+
body: body,
|
|
46
|
+
api_version: 'v2'
|
|
47
|
+
)
|
|
48
|
+
compose_response(response)
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
metadata
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: greenhouse_api
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.3.
|
|
4
|
+
version: 0.3.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Florence Lau
|
|
8
8
|
- Tanner Johnson
|
|
9
9
|
- Quan Nguyen
|
|
10
|
-
autorequire:
|
|
10
|
+
autorequire:
|
|
11
11
|
bindir: exe
|
|
12
12
|
cert_chain: []
|
|
13
|
-
date: 2021-
|
|
13
|
+
date: 2021-03-11 00:00:00.000000000 Z
|
|
14
14
|
dependencies:
|
|
15
15
|
- !ruby/object:Gem::Dependency
|
|
16
16
|
name: faraday
|
|
@@ -104,13 +104,17 @@ extensions: []
|
|
|
104
104
|
extra_rdoc_files: []
|
|
105
105
|
files:
|
|
106
106
|
- lib/greenhouse_api.rb
|
|
107
|
+
- lib/greenhouse_api/base_client.rb
|
|
107
108
|
- lib/greenhouse_api/client.rb
|
|
109
|
+
- lib/greenhouse_api/resources/candidates.rb
|
|
110
|
+
- lib/greenhouse_api/resources/offers.rb
|
|
111
|
+
- lib/greenhouse_api/resources/users.rb
|
|
108
112
|
- lib/greenhouse_api/version.rb
|
|
109
113
|
homepage: https://github.com/gusto/greenhouse_api
|
|
110
114
|
licenses: []
|
|
111
115
|
metadata:
|
|
112
116
|
homepage_uri: https://github.com/gusto/greenhouse_api
|
|
113
|
-
post_install_message:
|
|
117
|
+
post_install_message:
|
|
114
118
|
rdoc_options: []
|
|
115
119
|
require_paths:
|
|
116
120
|
- lib
|
|
@@ -125,8 +129,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
125
129
|
- !ruby/object:Gem::Version
|
|
126
130
|
version: '0'
|
|
127
131
|
requirements: []
|
|
128
|
-
rubygems_version: 3.
|
|
129
|
-
signing_key:
|
|
132
|
+
rubygems_version: 3.0.3
|
|
133
|
+
signing_key:
|
|
130
134
|
specification_version: 4
|
|
131
135
|
summary: API client for working with Greenhouse Harvest API
|
|
132
136
|
test_files: []
|