reso_api 1.5.13 → 1.7.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/README.md +28 -4
- data/lib/reso_api/app/models/reso/api/client.rb +19 -11
- data/lib/reso_api/version.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 152e24a12afdb9af2c9385a365335df67b58704676b313c886a1833417ae8763
|
4
|
+
data.tar.gz: 88ca57e2199877808138e07f96999376541c40a138b90a920bf56940e786d212
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0e5c6750cddd94f0dc296e64baf3d008157754360c58c2350feb5df96fa4301f272ad4c1b81a3f20b809523bd16858fc018e38e0a190f71eb2b10f6b2b0552d5
|
7
|
+
data.tar.gz: 1a21eb60cd03e7e39a6cd33123f7635dd194f1cd4bb2e03d326788fecdc187316e9bfc79469f60847fe7d013d286611ef8e4dee49d0524a37d5b2bd3e1814912
|
data/README.md
CHANGED
@@ -26,23 +26,47 @@ Or install it yourself as:
|
|
26
26
|
|
27
27
|
### Authentication and Access
|
28
28
|
|
29
|
-
|
29
|
+
This gem supports two types of authentication:
|
30
|
+
|
31
|
+
- OAuth2
|
32
|
+
- Access Token
|
33
|
+
|
34
|
+
#### OAuth2
|
35
|
+
|
36
|
+
To set up an API client using OAuth2 authentication, you need four pieces of information:
|
30
37
|
|
31
38
|
- Client ID
|
32
39
|
- Client Secret
|
33
|
-
- Base API endpoint
|
34
40
|
- Authentication URL
|
41
|
+
- Base URL
|
42
|
+
- Scope
|
35
43
|
|
36
|
-
|
44
|
+
Often, the base URL ends with `/odata`, and the authentication URL often ends with `/token`.
|
45
|
+
|
46
|
+
Scope defaults to "api" and only needs to be included if it is "OData" or something else.
|
37
47
|
|
38
48
|
You pass these four pieces of information to create an instance of an API client:
|
39
49
|
|
40
50
|
```ruby
|
41
|
-
client = RESO::API::Client.new(client_id: client_id, client_secret: client_secret, auth_url: auth_url, base_url: base_url)
|
51
|
+
client = RESO::API::Client.new(client_id: client_id, client_secret: client_secret, auth_url: auth_url, base_url: base_url, scope: scope)
|
42
52
|
```
|
43
53
|
|
44
54
|
When calling API endpoints using the initialized client, it will automatically fetch and manage access and authentication tokens transparently in the background.
|
45
55
|
|
56
|
+
#### Access Token
|
57
|
+
|
58
|
+
Some systems, like MLSGRID and Spark/Flexmls provides a persistent Access Token. In these cases, you need these two pieces of information to set up an API client:
|
59
|
+
|
60
|
+
- Access Token
|
61
|
+
- Base API endpoint
|
62
|
+
|
63
|
+
You pass these two pieces of information to create an instance of an API client:
|
64
|
+
|
65
|
+
```ruby
|
66
|
+
client = RESO::API::Client.new(access_token: access_token, base_url: base_url)
|
67
|
+
```
|
68
|
+
|
69
|
+
|
46
70
|
### Resources
|
47
71
|
|
48
72
|
#### Supported Resources
|
@@ -7,18 +7,22 @@ module RESO
|
|
7
7
|
require 'json'
|
8
8
|
require 'tmpdir'
|
9
9
|
|
10
|
-
attr_accessor :client_id, :client_secret, :auth_url, :base_url
|
10
|
+
attr_accessor :access_token, :client_id, :client_secret, :auth_url, :base_url, :scope
|
11
11
|
|
12
12
|
def initialize(**opts)
|
13
|
-
@client_id, @client_secret, @auth_url, @base_url = opts.values_at(:client_id, :client_secret, :auth_url, :base_url)
|
13
|
+
@access_token, @client_id, @client_secret, @auth_url, @base_url, @scope = opts.values_at(:access_token, :client_id, :client_secret, :auth_url, :base_url, :scope)
|
14
14
|
validate!
|
15
15
|
end
|
16
16
|
|
17
17
|
def validate!
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
18
|
+
if access_token.nil?
|
19
|
+
raise 'Missing Client ID `client_id`' if client_id.nil?
|
20
|
+
raise 'Missing Client Secret `client_secret`' if client_secret.nil?
|
21
|
+
raise 'Missing Authentication URL `auth_url`' if auth_url.nil?
|
22
|
+
raise 'Missing API Base URL `base_url`' if base_url.nil?
|
23
|
+
else
|
24
|
+
raise 'Missing API Base URL `base_url`' if base_url.nil?
|
25
|
+
end
|
22
26
|
end
|
23
27
|
|
24
28
|
RESOURCE_KEYS = {
|
@@ -96,12 +100,16 @@ module RESO
|
|
96
100
|
end
|
97
101
|
end
|
98
102
|
|
103
|
+
def auth_token
|
104
|
+
access_token.presence ? access_token : oauth2_token
|
105
|
+
end
|
106
|
+
|
99
107
|
def oauth2_client
|
100
108
|
OAuth2::Client.new(
|
101
109
|
client_id,
|
102
110
|
client_secret,
|
103
111
|
token_url: auth_url,
|
104
|
-
scope: "api",
|
112
|
+
scope: scope.presence || "api",
|
105
113
|
grant_type: "client_credentials"
|
106
114
|
)
|
107
115
|
end
|
@@ -120,7 +128,7 @@ module RESO
|
|
120
128
|
end
|
121
129
|
|
122
130
|
def fresh_oauth2_payload
|
123
|
-
@oauth2_payload = oauth2_client.client_credentials.get_token('client_id' => client_id, 'client_secret' => client_secret)
|
131
|
+
@oauth2_payload = oauth2_client.client_credentials.get_token('client_id' => client_id, 'client_secret' => client_secret, 'scope' => scope || "api")
|
124
132
|
File.write(oauth2_token_path, @oauth2_payload.to_hash.to_json)
|
125
133
|
return @oauth2_payload
|
126
134
|
end
|
@@ -138,7 +146,7 @@ module RESO
|
|
138
146
|
persisted = File.read(oauth2_token_path)
|
139
147
|
payload = OAuth2::AccessToken.from_hash(oauth2_client, JSON.parse(persisted))
|
140
148
|
else
|
141
|
-
payload = oauth2_client.client_credentials.get_token('client_id' => client_id, 'client_secret' => client_secret)
|
149
|
+
payload = oauth2_client.client_credentials.get_token('client_id' => client_id, 'client_secret' => client_secret, 'scope' => scope || "api")
|
142
150
|
File.write(oauth2_token_path, payload.to_hash.to_json)
|
143
151
|
end
|
144
152
|
return payload
|
@@ -158,7 +166,7 @@ module RESO
|
|
158
166
|
end
|
159
167
|
begin
|
160
168
|
req = Net::HTTP::Get.new(uri.request_uri)
|
161
|
-
req['Authorization'] = "Bearer #{
|
169
|
+
req['Authorization'] = "Bearer #{auth_token}"
|
162
170
|
res = Net::HTTP.start(uri.host, uri.port, :use_ssl => uri.scheme == 'https') do |http|
|
163
171
|
http.request(req)
|
164
172
|
end
|
@@ -171,7 +179,7 @@ module RESO
|
|
171
179
|
fresh_oauth2_payload
|
172
180
|
raise StandardError
|
173
181
|
elsif response.is_a?(Hash) && response.has_key?("error")
|
174
|
-
puts "Error."
|
182
|
+
puts "Error: #{response.inspect}"
|
175
183
|
raise StandardError
|
176
184
|
elsif response.is_a?(Hash) && response.has_key?("retry-after")
|
177
185
|
puts "Error: Retrying in #{response["retry-after"].to_i}} seconds."
|
data/lib/reso_api/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: reso_api
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.7.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Michael Edlund
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2024-04-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -123,7 +123,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
123
123
|
- !ruby/object:Gem::Version
|
124
124
|
version: '0'
|
125
125
|
requirements: []
|
126
|
-
rubygems_version: 3.
|
126
|
+
rubygems_version: 3.5.9
|
127
127
|
signing_key:
|
128
128
|
specification_version: 4
|
129
129
|
summary: RESO Web API Wrapper
|