spark_api 1.5.7 → 1.6.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +57 -28
- data/VERSION +1 -1
- data/lib/spark_api/authentication/oauth2_impl/cli_provider.rb +2 -2
- data/lib/spark_api/configuration/yaml.rb +3 -1
- data/script/access_token_example.rb +16 -0
- data/script/example.rb +4 -4
- data/script/reso_middleware_example.rb +53 -52
- data/script/spark_auth_example.rb +26 -0
- data/spec/spec_helper.rb +8 -13
- metadata +3 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e315d7b172f1df48cf669a4900fde0367b629dba0fa337b1047d5aeb38c32dfb
|
4
|
+
data.tar.gz: cd034a5ea19d67503c5fca449771fa882a1f0b37b673d3f2259f38db0276a12a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: da7b242dbdeb0dac71a5334a6a26d158ad49a8bc0c835b896b754f4ba4d4da87445c50164406863a8ba23d2f5a99ef6f95c0d08b4cf0b53392243012803289ad
|
7
|
+
data.tar.gz: c172948eff245c7ca407fb7a3d73f7634ce43fc1a1f906bdb90a4f73d2b7166eb0f88046beef6f856bab938dc15d4462af6b6150f0059c79e1b27291266d56b0
|
data/README.md
CHANGED
@@ -10,35 +10,76 @@ Documentation
|
|
10
10
|
|
11
11
|
For further client documentation, please consult our [wiki](https://github.com/sparkapi/spark_api/wiki).
|
12
12
|
|
13
|
-
For full information on the API, see [http://sparkplatform.com/docs/overview/api](http://sparkplatform.com/docs/overview/api)
|
13
|
+
For full information on the Spark API, see [http://sparkplatform.com/docs/overview/api](http://sparkplatform.com/docs/overview/api). If you would instead like information on the RESO Web API, see [http://sparkplatform.com/docs/reso/overview](http://sparkplatform.com/docs/reso/overview)
|
14
14
|
|
15
15
|
|
16
16
|
Installation
|
17
17
|
---------
|
18
18
|
gem install spark_api
|
19
19
|
|
20
|
+
|
21
|
+
Authentication Types
|
22
|
+
--------------
|
23
|
+
Authentication is handled transparently by the request framework in the gem, so you should never need to manually make an authentication request. More than one mode of authentication is supported, so the client needs to be configured accordingly.
|
24
|
+
|
25
|
+
#### [Access Token Authentication](https://github.com/sparkapi/spark_api/wiki/Spark-Authentication) (Preferred)
|
26
|
+
Also known as Bearer Token Authentication. If you've been provided a single non-expiring access (bearer) token for the purpose of accessing data on behalf of one or more MLS users, this method of authentication should be used. See "script/access_token_example.rb" for an example.
|
27
|
+
|
28
|
+
#### [OpenId/OAuth2 Combined Flow](https://github.com/sparkapi/spark_api/wiki/Hybrid-Authentication)
|
29
|
+
Authorization mode that separates application and user authentication. This mode requires the end user to be redirected to Spark Platform's openid endpoint in a web browser window. See "script/combined_flow_example.rb" for an example.
|
30
|
+
|
31
|
+
Read more about Spark Platform's combined flow <a href="http://sparkplatform.com/docs/authentication/openid_oauth2_authentication">here</a>.
|
32
|
+
|
33
|
+
#### [OAuth2 Authorization](https://github.com/sparkapi/spark_api/wiki/OAuth2-Only-Authentication)
|
34
|
+
Authorization mode that separates application and user authentication. This mode requires the end user to be redirected to Spark Platform's auth endpoint in a web browser window. See "script/oauth2_example.rb" for an example.
|
35
|
+
|
36
|
+
Read more about Spark Platform's OAuth 2 flow <a href="http://sparkplatform.com/docs/authentication/oauth2_authentication">here</a>.
|
37
|
+
|
38
|
+
#### [Spark API Authentication](https://github.com/sparkapi/spark_api/wiki/Spark-Authentication) (Deprecated)
|
39
|
+
Usually supplied for a single user, this authentication mode was our old standard, however, is now deprecated in favor of bearer token authentication. See "script/spark_auth_example.rb" for an example.
|
40
|
+
|
41
|
+
|
20
42
|
Usage Examples
|
21
43
|
------------------------
|
22
|
-
|
44
|
+
#### Accessing the Spark API (Default)
|
23
45
|
```ruby
|
24
46
|
require 'spark_api'
|
25
47
|
SparkApi.configure do |config|
|
26
48
|
config.endpoint = 'https://sparkapi.com'
|
27
|
-
|
28
|
-
|
29
|
-
|
49
|
+
config.authentication_mode = SparkApi::Authentication::OAuth2
|
50
|
+
end
|
51
|
+
#Non-expiring bearer token auth. See below if you are using a different authentication method.
|
52
|
+
SparkApi.client.session = SparkApi::Authentication::OAuthSession.new({ :access_token => "your_bearer_token_here" })
|
53
|
+
puts SparkApi.client.get '/system'
|
54
|
+
```
|
55
|
+
|
56
|
+
#### Accessing the RESO Web API
|
57
|
+
```ruby
|
58
|
+
require "spark_api"
|
59
|
+
|
60
|
+
# set up session and set the client to hit the RESO API endpoints.
|
61
|
+
SparkApi.configure do |config|
|
62
|
+
config.authentication_mode = SparkApi::Authentication::OAuth2
|
63
|
+
config.middleware = :reso_api
|
30
64
|
end
|
31
|
-
|
65
|
+
#Non-expiring bearer token auth. See below if you are using a different authentication method.
|
66
|
+
SparkApi.client.session = SparkApi::Authentication::OAuthSession.new({ :access_token => "your_access_token_here" })
|
67
|
+
|
68
|
+
puts SparkApi.client.get("/Property", {:$top => 10 })
|
32
69
|
```
|
33
70
|
|
71
|
+
The examples above utilize access token authentication. For examples using different authentication methods review the wiki and /script folder within this project.
|
34
72
|
|
35
73
|
#### Interactive Console
|
36
|
-
Included in the gem is an interactive spark_api console to interact with the api in a manner similar to the rails console.
|
74
|
+
Included in the gem is an interactive spark_api console to interact with the api in a manner similar to the rails console. Here are a few examples using various auth methods:
|
37
75
|
|
38
|
-
|
39
|
-
|
76
|
+
Access Token Auth:
|
77
|
+
|
78
|
+
> spark_api --oauth2
|
79
|
+
SparkApi:001:0> SparkApi.client.session = SparkApi::Authentication::OAuthSession.new({ :access_token => "your_access_token_here" })
|
80
|
+
SparkApi:002:0> SparkApi.client.get '/my/account'
|
40
81
|
|
41
|
-
|
82
|
+
Standard OAuth2 access is a bit more complicated as it requires a step for logging in through the browser to gain access to the access code for a client_id.
|
42
83
|
|
43
84
|
> bundle exec spark_api --oauth2 --client_id my_oauth2_client_id --client_secret my_oauth2_client_secret
|
44
85
|
Loading spark_api gem...
|
@@ -51,13 +92,18 @@ Using OAuth2 requires different arguments, and is a bit more complicated as it r
|
|
51
92
|
SparkApi:002:0> Account.my.UserType
|
52
93
|
"Member"
|
53
94
|
|
95
|
+
[Spark Auth (deprecated)](http://sparkplatform.com/docs/authentication/spark_api_authentication):
|
96
|
+
|
97
|
+
> spark_api --api_key MY_SPARK_API_KEY --api_secret MY_SPARK_API_SECRET
|
98
|
+
SparkApi> SparkApi.client.get '/my/account'
|
99
|
+
|
54
100
|
You can also provide other options from the command line, see "spark_api -h" for more information.
|
55
101
|
|
56
102
|
#### HTTP Interface
|
57
103
|
The base client provides a bare bones HTTP interface for working with the RESTful Spark API. This is basically a stylized curl interface that handles authentication, error handling, and processes JSON results as Ruby Hashes.
|
58
104
|
|
59
105
|
```ruby
|
60
|
-
SparkApi.client.get "/listings
|
106
|
+
SparkApi.client.get "/listings", :_expand => "CustomFields", :_filter => "MlsStatus Eq 'Active'", :_limit => 1
|
61
107
|
SparkApi.client.post "/listings/#{listing_id}/photos", photo_body_hash
|
62
108
|
SparkApi.client.put "/listings/#{listing_id}/photos/#{photo_id}", updated_photo_name_hash
|
63
109
|
SparkApi.client.delete "/listings/#{listing_id}/photos/#{photo_id}"
|
@@ -81,20 +127,3 @@ JSON Parsing
|
|
81
127
|
--------------
|
82
128
|
By default, this gem uses the pure ruby json gem for parsing API responses for cross platform compatibility. Projects that include the yajl-ruby gem will see noticeable speed improvements when installed.
|
83
129
|
|
84
|
-
|
85
|
-
Authentication Types
|
86
|
-
--------------
|
87
|
-
Authentication is handled transparently by the request framework in the gem, so you should never need to manually make an authentication request. More than one mode of authentication is supported, so the client needs to be configured accordingly.
|
88
|
-
|
89
|
-
#### [Spark API Authentication](https://github.com/sparkapi/spark_api/wiki/Spark-Authentication) (Default)
|
90
|
-
Usually supplied for a single user, this authentication mode is the simplest, and is setup as the default. The example usage above demonstrates how to get started using this authentication mode.
|
91
|
-
|
92
|
-
#### [OpenId/OAuth2 Combined Flow](https://github.com/sparkapi/spark_api/wiki/Hybrid-Authentication) (Preferred)
|
93
|
-
Authorization mode the separates application and user authentication. This mode requires the end user to be redirected to Spark Platform's openid endpoint. See "script/combined_flow_example.rb" for an example.
|
94
|
-
|
95
|
-
Read more about Spark Platform's combined flow <a href="http://sparkplatform.com/docs/authentication/openid_oauth2_authentication">here</a>.
|
96
|
-
|
97
|
-
#### [OAuth2 Authorization](https://github.com/sparkapi/spark_api/wiki/OAuth2-Only-Authentication)
|
98
|
-
Authorization mode the separates application and user authentication. This mode requires the end user to be redirected to Spark Platform's auth endpoint. See "script/oauth2_example.rb" for an example.
|
99
|
-
|
100
|
-
Read more about Spark Platform's OAuth 2 flow <a href="http://sparkplatform.com/docs/authentication/oauth2_authentication">here</a>.
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.
|
1
|
+
1.6.1
|
@@ -82,8 +82,8 @@ module SparkApi
|
|
82
82
|
|
83
83
|
def load_file
|
84
84
|
yaml = {}
|
85
|
-
begin
|
86
|
-
yaml = YAML.load(File.open(filename))
|
85
|
+
begin
|
86
|
+
yaml = YAML.respond_to?(:unsafe_load) ? YAML.unsafe_load(File.open(filename)) : YAML.load(File.open(filename))
|
87
87
|
yaml = {} if yaml == false
|
88
88
|
rescue => e
|
89
89
|
puts "no file: #{e.message}"
|
@@ -16,7 +16,9 @@ module SparkApi
|
|
16
16
|
def load_file(file)
|
17
17
|
@file = file
|
18
18
|
@name = File.basename(file, ".yml")
|
19
|
-
|
19
|
+
|
20
|
+
erb_file = ERB.new(File.read(file)).result
|
21
|
+
config = (YAML.respond_to?(:unsafe_load) ? YAML.unsafe_load(erb_file) : YAML.load(erb_file))[api_env]
|
20
22
|
config["oauth2"] == true ? load_oauth2(config) : load_api_auth(config)
|
21
23
|
rescue => e
|
22
24
|
SparkApi.logger().error("Unable to load config file #{file}[#{api_env}]")
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require "spark_api"
|
2
|
+
|
3
|
+
SparkApi.configure do |config|
|
4
|
+
config.endpoint = 'https://sparkapi.com'
|
5
|
+
config.authentication_mode = SparkApi::Authentication::OAuth2
|
6
|
+
end
|
7
|
+
|
8
|
+
#### COPY/PASTE YOUR ACCESS TOKEN WHERE DESIGNATED BELOW
|
9
|
+
SparkApi.client.session = SparkApi::Authentication::OAuthSession.new({ :access_token => "your_access_token_here" })
|
10
|
+
|
11
|
+
client = SparkApi.client
|
12
|
+
|
13
|
+
list = client.get '/contacts'
|
14
|
+
puts "client: #{list.inspect}"
|
15
|
+
list = SparkApi::Models::Contact.get
|
16
|
+
puts "model: #{list.inspect}"
|
data/script/example.rb
CHANGED
@@ -10,12 +10,12 @@ require path + '/spark_api'
|
|
10
10
|
SparkApi.logger.info("Hello!")
|
11
11
|
|
12
12
|
SparkApi.configure do |config|
|
13
|
-
config.
|
14
|
-
config.
|
15
|
-
config.version = "v1"
|
16
|
-
config.endpoint = "https://api.sparkapi.com"
|
13
|
+
config.endpoint = 'https://sparkapi.com'
|
14
|
+
config.authentication_mode = SparkApi::Authentication::OAuth2
|
17
15
|
end
|
18
16
|
|
17
|
+
SparkApi.client.session = SparkApi::Authentication::OAuthSession.new({ :access_token => "your_access_token_here" })
|
18
|
+
|
19
19
|
client = SparkApi.client
|
20
20
|
|
21
21
|
list = client.get '/contacts'
|
@@ -1,8 +1,6 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
|
-
# This script demonstrates how to
|
4
|
-
# and replacing encoded field values with their corresponding human-readable values, which are
|
5
|
-
# pulled from the XML returned by the RESO metadata endpoint.
|
3
|
+
# This script demonstrates how to access the RESO Web API with FBS's Ruby API client.
|
6
4
|
|
7
5
|
require "spark_api"
|
8
6
|
require "nokogiri"
|
@@ -12,59 +10,62 @@ SparkApi.configure do |config|
|
|
12
10
|
config.authentication_mode = SparkApi::Authentication::OAuth2
|
13
11
|
config.middleware = :reso_api
|
14
12
|
end
|
15
|
-
|
16
|
-
SparkApi.client.session = SparkApi::Authentication::OAuthSession.new({ :access_token => "
|
13
|
+
#### COPY/PASTE YOUR ACCESS TOKEN BELOW
|
14
|
+
SparkApi.client.session = SparkApi::Authentication::OAuthSession.new({ :access_token => "your_access_token_here" })
|
17
15
|
|
18
16
|
# pull metadata from RESO Web API
|
19
|
-
metadata_res =
|
17
|
+
metadata_res = SparkApi.client.get("/$metadata")
|
20
18
|
metadata_xml = Nokogiri::XML(metadata_res).remove_namespaces!
|
21
19
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
20
|
+
## make an array of fields which need to be checked for readable values
|
21
|
+
## API now returns decoded field values. This is no longer necessary
|
22
|
+
#fields_to_lookup = []
|
23
|
+
#metadata_xml.xpath('//Schema/EnumType/@Name').each do |el|
|
24
|
+
# fields_to_lookup << el.to_str
|
25
|
+
#end
|
27
26
|
|
28
27
|
# get 25 listings
|
29
|
-
listings =
|
30
|
-
|
31
|
-
listings['value'].each do |listing| # for each listing,
|
32
|
-
fields_to_lookup.each do |field| # go through the array of fields to be checked.
|
33
|
-
if !!listing[field] # when one of the fields that needs to be checked exists in a listing,
|
34
|
-
if listing[field].is_a? String
|
35
|
-
readable = metadata_xml.xpath( # check for readable value to be swapped in
|
36
|
-
"//Schema/
|
37
|
-
EnumType[@Name=\"#{field}\"]/
|
38
|
-
Member[@Name=\"#{listing[field]}\"]/
|
39
|
-
Annotation"
|
40
|
-
).attr("String")
|
41
|
-
|
42
|
-
# if there is a readable value, swap it in
|
43
|
-
if !!readable
|
44
|
-
listing[field] = readable.to_str
|
45
|
-
end
|
46
|
-
|
47
|
-
elsif listing[field].is_a? Array
|
48
|
-
readable_arr = []
|
49
|
-
listing[field].each do |el|
|
50
|
-
readable = metadata_xml.xpath( # check for readable value to be swapped in
|
51
|
-
"//Schema/
|
52
|
-
EnumType[@Name=\"#{field}\"]/
|
53
|
-
Member[@Name=\"#{el}\"]/
|
54
|
-
Annotation"
|
55
|
-
).attr("String")
|
56
|
-
|
57
|
-
# assemble a new array with readable values and swap it in
|
58
|
-
if !!readable
|
59
|
-
readable_arr << readable.to_str
|
60
|
-
else
|
61
|
-
readable_arr << el
|
62
|
-
end
|
63
|
-
listing[field] = readable_arr
|
64
|
-
end
|
65
|
-
end
|
66
|
-
end
|
67
|
-
end
|
68
|
-
end
|
69
|
-
|
28
|
+
listings = SparkApi.client.get("/Property", {:$top => 25 })
|
70
29
|
puts listings
|
30
|
+
|
31
|
+
## API now returns decoded field values. The code below is no longer needed
|
32
|
+
#listings['value'].each do |listing| # for each listing,
|
33
|
+
# fields_to_lookup.each do |field| # go through the array of fields to be checked.
|
34
|
+
# if !!listing[field] # when one of the fields that needs to be checked exists in a listing,
|
35
|
+
# if listing[field].is_a? String
|
36
|
+
# readable = metadata_xml.xpath( # check for readable value to be swapped in
|
37
|
+
# "//Schema/
|
38
|
+
# EnumType[@Name=\"#{field}\"]/
|
39
|
+
# Member[@Name=\"#{listing[field]}\"]/
|
40
|
+
# Annotation"
|
41
|
+
# ).attr("String")
|
42
|
+
#
|
43
|
+
# # if there is a readable value, swap it in
|
44
|
+
# if !!readable
|
45
|
+
# listing[field] = readable.to_str
|
46
|
+
# end
|
47
|
+
#
|
48
|
+
# elsif listing[field].is_a? Array
|
49
|
+
# readable_arr = []
|
50
|
+
# listing[field].each do |el|
|
51
|
+
# readable = metadata_xml.xpath( # check for readable value to be swapped in
|
52
|
+
# "//Schema/
|
53
|
+
# EnumType[@Name=\"#{field}\"]/
|
54
|
+
# Member[@Name=\"#{el}\"]/
|
55
|
+
# Annotation"
|
56
|
+
# ).attr("String")
|
57
|
+
#
|
58
|
+
# # assemble a new array with readable values and swap it in
|
59
|
+
# if !!readable
|
60
|
+
# readable_arr << readable.to_str
|
61
|
+
# else
|
62
|
+
# readable_arr << el
|
63
|
+
# end
|
64
|
+
# listing[field] = readable_arr
|
65
|
+
# end
|
66
|
+
# end
|
67
|
+
# end
|
68
|
+
# end
|
69
|
+
#end
|
70
|
+
#
|
71
|
+
#puts listings
|
@@ -0,0 +1,26 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require "rubygems"
|
3
|
+
|
4
|
+
Bundler.require(:default, "development") if defined?(Bundler)
|
5
|
+
|
6
|
+
path = File.expand_path(File.dirname(__FILE__) + "/../lib/")
|
7
|
+
$LOAD_PATH.unshift(path) unless $LOAD_PATH.include?(path)
|
8
|
+
require path + '/spark_api'
|
9
|
+
|
10
|
+
SparkApi.logger.info("Hello!")
|
11
|
+
|
12
|
+
#### COPY/PASTE YOUR API KEY AND SECRET BELOW
|
13
|
+
SparkApi.configure do |config|
|
14
|
+
config.api_key = "agent_key"
|
15
|
+
config.api_secret = "agent_secret"
|
16
|
+
config.version = "v1"
|
17
|
+
config.endpoint = "https://api.sparkapi.com"
|
18
|
+
end
|
19
|
+
|
20
|
+
client = SparkApi.client
|
21
|
+
|
22
|
+
list = client.get '/contacts'
|
23
|
+
puts "client: #{list.inspect}"
|
24
|
+
list = SparkApi::Models::Contact.get
|
25
|
+
puts "model: #{list.inspect}"
|
26
|
+
|
data/spec/spec_helper.rb
CHANGED
@@ -2,10 +2,12 @@ if ENV['COVERAGE'] == "on"
|
|
2
2
|
require 'simplecov'
|
3
3
|
require 'simplecov-rcov'
|
4
4
|
SimpleCov.formatter = SimpleCov::Formatter::RcovFormatter
|
5
|
-
SimpleCov.
|
6
|
-
|
7
|
-
|
8
|
-
|
5
|
+
unless SimpleCov.running # Hack to prevent starting SimpleCov multiple times see: https://github.com/simplecov-ruby/simplecov/issues/1003
|
6
|
+
SimpleCov.start do
|
7
|
+
add_filter '/vendor'
|
8
|
+
add_filter '/spec'
|
9
|
+
add_filter '/test'
|
10
|
+
end
|
9
11
|
end
|
10
12
|
end
|
11
13
|
|
@@ -21,13 +23,6 @@ require path + '/spark_api'
|
|
21
23
|
|
22
24
|
require 'spark_api'
|
23
25
|
|
24
|
-
if ENV['COVERAGE'] == "on"
|
25
|
-
require 'simplecov'
|
26
|
-
require 'simplecov-rcov'
|
27
|
-
SimpleCov.formatter = SimpleCov::Formatter::RcovFormatter
|
28
|
-
SimpleCov.start { add_filter %w(/vendor /spec /test) }
|
29
|
-
end
|
30
|
-
|
31
26
|
FileUtils.mkdir 'log' unless File.exists? 'log'
|
32
27
|
|
33
28
|
module SparkApi
|
@@ -51,7 +46,7 @@ end
|
|
51
46
|
|
52
47
|
# Requires supporting ruby files with custom matchers and macros, etc,
|
53
48
|
# # in spec/support/ and its subdirectories.
|
54
|
-
Dir[File.expand_path(File.join(File.dirname(__FILE__),'support','**','*.rb'))].each {|f| require f}
|
49
|
+
Dir[File.expand_path(File.join(File.dirname(__FILE__), 'support', '**', '*.rb'))].each { |f| require f }
|
55
50
|
|
56
51
|
RSpec.configure do |config|
|
57
52
|
|
@@ -66,6 +61,6 @@ RSpec.configure do |config|
|
|
66
61
|
config.color = true
|
67
62
|
end
|
68
63
|
|
69
|
-
def jruby?
|
64
|
+
def jruby?
|
70
65
|
RUBY_PLATFORM == "java"
|
71
66
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: spark_api
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.6.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Brandon Hornseth
|
@@ -327,6 +327,7 @@ files:
|
|
327
327
|
- lib/spark_api/reso_faraday_middleware.rb
|
328
328
|
- lib/spark_api/response.rb
|
329
329
|
- lib/spark_api/version.rb
|
330
|
+
- script/access_token_example.rb
|
330
331
|
- script/bootstrap
|
331
332
|
- script/ci_build
|
332
333
|
- script/combined_flow_example.rb
|
@@ -335,6 +336,7 @@ files:
|
|
335
336
|
- script/oauth2_example.rb
|
336
337
|
- script/release
|
337
338
|
- script/reso_middleware_example.rb
|
339
|
+
- script/spark_auth_example.rb
|
338
340
|
- spec/fixtures/accounts/all.json
|
339
341
|
- spec/fixtures/accounts/my.json
|
340
342
|
- spec/fixtures/accounts/my_portal.json
|