Class: Geoloqi::Session

Inherits:
Object
  • Object
show all
Defined in:
lib/geoloqi/session.rb

Overview

This class is used to instantiate a session object. It is designed to be thread safe, and multiple sessions can be used simultaneously, allowing for one ruby application to potentially handle multiple Geoloqi applications.

Examples:

# Instantiate a session with your access token (obtained from the Geoloqi Developers Site):
geoloqi_session = Geoloqi::Session.new :access_token => 'YOUR ACCESS TOKEN'

# Instantiate a session with a custom config:
geoloqi_session = Geoloqi::Session.new :access_token => 'YOUR ACCESS TOKEN', :config => {:use_hashie_mash => true}

# Instantiate a session with OAuth2 credentials (obtained from the Geoloqi Developers Site):
geoloqi_session = Geoloqi::Session.new :config => {:client_id => 'CLIENT ID', :client_secret => 'CLIENT SECRET'}

# Get profile:
result = geoloqi_session.get 'account/profile'

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(opts = {}) ⇒ Config

Instantiate a Geoloqi session.

Examples:

# With access token
geoloqi_session = Geoloqi::Session.new :access_token => 'YOUR ACCESS TOKEN'

# With OAuth2
geoloqi_session = Geoloqi::Session.new :config => {:client_id => 'CLIENT ID', :client_secret => 'CLIENT SECRET'}


37
38
39
40
41
42
43
44
45
46
# File 'lib/geoloqi/session.rb', line 37

def initialize(opts={})
  opts[:config] = Geoloqi::Config.new opts[:config] if opts[:config].is_a? Hash
  @config = opts[:config] || (Geoloqi.config || Geoloqi::Config.new).dup
  self.auth = opts[:auth] || {}
  self.auth[:access_token] = opts[:access_token] if opts[:access_token]

  @connection = Faraday.new(:url => Geoloqi.api_url, :ssl => {:verify => true, :ca_file => Geoloqi::SSL_CERT_FILE}) do |builder|
    builder.adapter  @config.adapter || :net_http
  end
end

Instance Attribute Details

#authHash

The auth Hash, which is provided by the OAuth2 response. This can be stored externally and used to re-initialize the session.

Returns:

  • (Hash)


22
23
24
# File 'lib/geoloqi/session.rb', line 22

def auth
  @auth
end

#configConfig

The config object attached to this session. It is unique to this session, and can be replaced/changed dynamically.

Returns:



26
27
28
# File 'lib/geoloqi/session.rb', line 26

def config
  @config
end

Instance Method Details

#access_tokenString

The access token for this session.

Returns:

  • (String)


55
56
57
# File 'lib/geoloqi/session.rb', line 55

def access_token
  @auth[:access_token]
end

#access_token?Boolean

Determines if the access token exists.

Returns:

  • (Boolean)


75
76
77
# File 'lib/geoloqi/session.rb', line 75

def access_token?
  !access_token.nil?
end

#application_access_tokenString

Retrieve the application access token for this session. This token is used in the same manner as the user access token, it simply allows the application to make requests on behalf of itself instead of a user within the app. It is strongly recommended that you keep this token private, and don't share it with clients.

This call makes a request to the API server for each instantiation of the object (so it will request once per session object, and then cache the result). It is recommended that you cache this with something like memcache to avoid latency issues.

Returns:

  • (String)


69
70
71
# File 'lib/geoloqi/session.rb', line 69

def application_access_token
  @application_access_token ||= establish(:grant_type => 'client_credentials')[:access_token]
end

#authorize_url(redirect_uri = @config.redirect_uri, opts = {}) ⇒ String

The authorize url for this session.

Returns:

  • (String)


82
83
84
# File 'lib/geoloqi/session.rb', line 82

def authorize_url(redirect_uri=@config.redirect_uri, opts={})
  Geoloqi.authorize_url @config.client_id, redirect_uri, opts
end

#batch(&block) ⇒ Array

Make a batch request to the Geoloqi API. Compiles POST requests (provided in a block) and returns an array of the results, which includes the response code, headers, and body. Calls are made synchronously on the server, and the results are returned in the same order. This should be much faster for scenarios where inserting/updating hundreds or thousands of records is needed.

Examples:

# Create 3 layers at once, return responses in an array
responses_array = geoloqi_session.batch do
  post 'layer/create', :name => 'Layer 1'
  post 'layer/create', :name => 'Layer 2'
  post 'layer/create', :name => 'Layer 3'
end

Returns:

  • (Array)
    • An array of Hash objects containing the response code, headers, and body.

See Also:



207
208
209
# File 'lib/geoloqi/session.rb', line 207

def batch(&block)
  Batch.new(self, &block).run!
end

#establish(opts = {}) ⇒ Hash

Used to retrieve the access token from the Geoloqi OAuth2 server. This is fairly low level and you shouldn't need to use it directly.

Returns:

  • (Hash)
    • The auth hash used to persist the session object.

See Also:



217
218
219
220
221
222
223
224
225
226
227
# File 'lib/geoloqi/session.rb', line 217

def establish(opts={})
  require 'client_id and client_secret are required to get access token' unless @config.client_id? && @config.client_secret?
  auth = post 'oauth/token', {:client_id => @config.client_id,
                              :client_secret => @config.client_secret}.merge!(opts)

  # expires_at is likely incorrect. I'm chopping 5 seconds
  # off to allow for a more graceful failover.
  auth['expires_at'] = auth_expires_at auth['expires_in']
  self.auth = auth
  self.auth
end

#execute(meth, path, query = nil, headers = {}) ⇒ Response

Makes a low-level request to the Geoloqi API server. It does no processing of the response.

Examples:

result = geoloqi_session.execute :get, 'account/profile'

Returns:



173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
# File 'lib/geoloqi/session.rb', line 173

def execute(meth, path, query=nil, headers={})
  query = Rack::Utils.parse_query query if query.is_a?(String)
  headers = default_headers.merge! headers

  raw = @connection.send(meth) do |req|
    req.url "/#{Geoloqi.api_version.to_s}/#{path.gsub(/^\//, '')}"
    req.headers = headers
    if query
      meth == :get ? req.params = query : req.body = query.to_json
    end
  end

  if @config.logger
    @config.logger.print "### Geoloqi::Session - #{meth.to_s.upcase} #{path}"
    @config.logger.print "?#{Rack::Utils.build_query query}" unless query.nil?
    @config.logger.puts "\n### Request Headers: #{headers.inspect}"
    @config.logger.puts "### Status: #{raw.status}\n### Headers: #{raw.headers.inspect}\n### Body: #{raw.body}"
  end

  Response.new raw.status, raw.headers, raw.body
end

#get(path, query = nil, headers = {}) ⇒ Hash, Hashie::Mash

Makes a GET request to the Geoloqi API server and returns response.

Examples:

# Get your user profile
result = geoloqi_session.get 'YOUR ACCESS TOKEN', 'account/profile'

# Get the last 5 locations
result = geoloqi_session.get 'YOUR ACCESS TOKEN', 'account/profile', :count => 5

Parameters:

  • path (String)

    Path to the resource being requested.

  • query (String, Hash) (defaults to: nil)

    (optional) A query string or Hash to be appended to the request.

  • headers (Hash) (defaults to: {})

    (optional) Adds and overwrites headers in request sent to server.

Returns:

  • (Hash, Hashie::Mash)

See Also:



105
106
107
# File 'lib/geoloqi/session.rb', line 105

def get(path, query=nil, headers={})
  run :get, path, query, headers
end

#get_auth(code, redirect_uri = @config.redirect_uri) ⇒ Hash

Get the OAuth2 authentication information. This call also stores the auth to the session automatically.

Parameters:

  • code (String)

    The code provided by the Geoloqi OAuth2 server.

  • redirect_uri (String) (defaults to: @config.redirect_uri)

    The redirect URI provided to the Geoloqi OAuth2 server. This value must match the redirect_uri sent to the server.

Returns:

  • (Hash)

    The auth hash used to persist the session object.

See Also:



244
245
246
# File 'lib/geoloqi/session.rb', line 244

def get_auth(code, redirect_uri=@config.redirect_uri)
  establish :grant_type => 'authorization_code', :code => code, :redirect_uri => redirect_uri
end

#post(path, query = nil, headers = {}) ⇒ Hash, Hashie::Mash

Makes a POST request to the Geoloqi API server and returns response.

Examples:

# Create a new layer
result = geoloqi_session.post 'layer/create', :name => 'Portland Food Carts'

Parameters:

  • path (String)

    Path to the resource being requested (example: '/account/profile').

  • query (String, Hash) (defaults to: nil)

    (optional) A query string or Hash to be converted to POST parameters.

  • headers (Hash) (defaults to: {})

    (optional) Adds and overwrites headers in request sent to server.

Returns:

  • (Hash, Hashie::Mash)

See Also:



125
126
127
# File 'lib/geoloqi/session.rb', line 125

def post(path, query=nil, headers={})
  run :post, path, query, headers
end

#renew_access_token!Hash

Renew the access token provided from Geoloqi using the stored refresh token. This method is automatically called by the session object when it detects an expiration, so you shouldn't need to explicitly call it.

Returns:

  • (Hash)

    The auth hash used to persist the session object.

See Also:



234
235
236
# File 'lib/geoloqi/session.rb', line 234

def renew_access_token!
  establish :grant_type => 'refresh_token', :refresh_token => self.auth[:refresh_token]
end

#run(meth, path, query = nil, headers = {}) ⇒ Hash, Hashie::Mash

Makes a request to the Geoloqi API server.

Examples:

# Create a new layer
result = geoloqi_session.run :get, 'layer/create', :name => 'Northeast Portland'

Returns:

  • (Hash, Hashie::Mash)


135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
# File 'lib/geoloqi/session.rb', line 135

def run(meth, path, query=nil, headers={})
  renew_access_token! if auth[:expires_at] && Time.rfc2822(auth[:expires_at]) <= Time.now && !(path =~ /^\/?oauth\/token$/)
  retry_attempt = 0

  begin
    response = execute meth, path, query, headers
    hash = JSON.parse response.body, :symbolize_names => @config.symbolize_names

    if hash.is_a?(Hash) && hash[:error] && @config.throw_exceptions
      if @config.use_dynamic_exceptions && !hash[:error].nil? && !hash[:error].empty?
        exception_class_name = hash[:error].gsub(/\W+/, '_').split('_').collect {|w| w.capitalize}.join+'Error'
        Geoloqi.const_set exception_class_name, Class.new(Geoloqi::ApiError) unless Geoloqi.const_defined? exception_class_name
        raise_class = Geoloqi.const_get exception_class_name
      else
        raise_class = ApiError
      end
      raise raise_class.new(response.status, hash[:error], hash[:error_description])
    end
  rescue Geoloqi::ApiError
    raise Error.new('Unable to procure fresh access token from API on second attempt') if retry_attempt > 0
    if hash[:error] == 'expired_token' && !(hash[:error_description] =~ /The auth code expired/)
      renew_access_token!
      retry_attempt += 1
      retry
    else
      fail
    end
  rescue JSON::ParserError
    raise Geoloqi::Error, "API returned invalid JSON. Status: #{response.status} Body: #{response.body}"
  end
  @config.use_hashie_mash ? Hashie::Mash.new(hash) : hash
end