class Tenka::Client

The main class for the client. TODO: Provide usage examples here.

Constants

DefaultOpts

The defaults when initializing a client. `host` specifies the hostname to connect to. You probably won't need to change this. `ssl` turns HTTPS on or off. If you are using an API key, you probably want to leave it on. `port` specifies the port to connect to.

Units

For endpoints that require units to be specified, this is the list of units.

Attributes

api_tokens_left[RW]
last_error[RW]
last_resp[RW]
opts[RW]
rate_limit_calls_left[RW]

Public Class Methods

new(opts = {}) click to toggle source

Creates a new client. To simplify the API, the client carries information in the form of state, and thus is not thread-safe; you should instantiate one client per thread that accesses Tenka.

# File lib/tenka.rb, line 44
def initialize opts = {}
        self.opts = DefaultOpts.merge(opts)

        # If they don't specify a port but they do turn off SSL, we set
        # the port to 80.
        if !opts.has_key?(port) && !ssl
                self.opts[:port] = 80
        end
end

Public Instance Methods

calls_left() click to toggle source

Returns the number of calls your API token has left, as well as how many calls you can make before you hit the rate limit for the server.

This information is automatically gathered (whether your API key is valid or not) on every request, so you can also just check Tenka::Client#rate_limit_calls_left and Tenka::Client#api_tokens_left.

Making a request against this endpoint does not reduce the number of API tokens you have left. (It does count towards the rate limit.)

A 404 from this endpoint indicates that your API key is invalid.

# File lib/tenka.rb, line 118
def calls_left
        ok, body = get('/tokens-remaining')
        ok && {
                rate_limit: rate_limit_calls_left,
                api_limit: api_tokens_left,
        }
end
containing_lat_lon(lat, long)
Alias for: containing_lat_long
containing_lat_long(lat, long) click to toggle source

Reverse-geocode a latitude/longitude pair.

# File lib/tenka.rb, line 70
def containing_lat_long lat, long
        ok, body = get('/containing/lat-long', lat: lat, long: long)
        ok && body
end
Also aliased as: containing_lat_lon
containing_zip(zip) click to toggle source

Reverse-geocode a ZIP code centroid. (Tenka only supports US ZIPs for now, but this is not enforced client-side.)

Note that ZIP codes often describe very odd shapes; they are based on postal service routes rather than geographical boundaries. As a result, the centroid may lie in a different city than any single point within the actual boundaries of the ZIP code. (ZIP centroids are popular because of their granularity, but they should be used with caution.)

ZIP codes can start with leading zeroes. It is advised to use a string to represent a ZIP code rather than an integer.

# File lib/tenka.rb, line 88
def containing_zip zip
        ok, body = get('/containing/zip', zip: zip)
        ok && body
end
nearby_zip(zip, radius, units = 'mile') click to toggle source

Returns a list of ZIP codes whose centroids are within a given radius of another ZIP code's centroid. (See the remarks about centroids in containing_zip.)

# File lib/tenka.rb, line 96
def nearby_zip zip, radius, units = 'mile'
        unless Units.include?(units)
                raise ArgumentError, "Invalid unit #{units}.  Must be one "\
                        "of #{Units.to_a.join(', ')}."
        end
        ok, body = get('/nearby/zip',
                zip: zip, radius: radius, units: units)
        ok && body['zips']
end

Private Instance Methods

get(path, query = nil) click to toggle source
# File lib/tenka.rb, line 128
def get path, query = nil
        req_headers = {}
        if api_key
                req_headers['API-Token'] = api_key
        end
        path = path + h2query(query) if query
        http_req Net::HTTP::Get.new(path, req_headers)
end
h2query(h) click to toggle source
# File lib/tenka.rb, line 168
def h2query h
        '?' <<
        h.map { |k,v|
                (CGI.escape(k.to_s) << '=' << CGI.escape(v.to_s)).
                        gsub('+', '%20')
        }.join('&')
end
http_req(req, body = nil) click to toggle source

Returns [true/false, parsed_body, response_object].

# File lib/tenka.rb, line 138
def http_req req, body = nil
        resp = Net::HTTP.start(host, port, use_ssl: ssl) { |h|
                h.request req, body
        }
        body = JSON.parse(resp.body)
        self.last_resp = resp
        update_counters!

        # Error detection is easy for Tenka.
        [resp.code[0] == '2', body]
end
server_uri() click to toggle source
# File lib/tenka.rb, line 162
def server_uri
        # Under normal circumstances, `host` shouldn't change (just start
        # a new client).
        @_server_uri ||= URI("http#{ssl ? 's' : ''}://#{host}/")
end
update_counters!() click to toggle source

Check rate limits and API tokens remaining in the headers that came back;

# File lib/tenka.rb, line 152
def update_counters!
        if l = last_resp['rate-limit-calls-left']
                self.rate_limit_calls_left = l.to_i
        end

        if l = last_resp['api-token-calls-remaining']
                self.api_tokens_left = l.to_i
        end
end