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
         |