You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

72 lines
1.6 KiB

# frozen_string_literal: true
require 'json'
require 'net/http'
require 'net/https'
require 'uri'
class CPIFetcher
def cpi
resp = fetch_raw_response
return nil unless resp['Results']['series']
latest_cpi_value(resp['Results']['series'].first['data'])
end
private def url
@url ||= URI(ENV['CPI_SERIES_URL'] || File.join(
'https://api.bls.gov',
'publicAPI/v2/timeseries/data/'
))
end
private def series_id
@series_id ||= ENV.fetch(
'CPI_SERIES_ID', 'CUURS000SA0,CUUSS000SA0'
).split(/[, ]/).map(&:strip).reject(&:empty?)
end
private def start_year
@start_year ||= ENV.fetch('CPI_SERIES_START_YEAR', '2014')
end
private def end_year
@end_year ||= ENV.fetch('CPI_SERIES_END_YEAR', Time.now.year.to_s)
end
private def bls_token
@bls_token ||= ENV.fetch('BLS_TOKEN')
end
private def latest_cpi_value(data)
data.find { |d| d['latest'] == 'true' }.fetch('value')
end
private def fetch_raw_response
Net::HTTP.new(url.hostname, url.port)
.tap { |h| h.use_ssl = true }
.tap { |h| h.verify_mode = OpenSSL::SSL::VERIFY_PEER }
.then { |h| JSON.parse(h.request(build_request).body) }
end
private def build_request
Net::HTTP::Post.new(url)
.tap { |r| r['Authorization'] = "token #{bls_token}" }
.tap { |r| r['Content-Type'] = 'application/json' }
.tap { |r| r.body = JSON.generate(build_request_body) }
end
private def build_request_body
{
'seriesid' => series_id,
'startyear' => start_year,
'endyear' => end_year
}
end
end
if $PROGRAM_NAME == __FILE__
puts CPIFetcher.new.cpi
exit 0
end