# frozen_string_literal: true require 'json' require 'net/http' require 'net/https' require 'uri' class CPIFetcher DEFAULT_CPI_SERIES_URL = File.join( 'https://api.bls.gov', 'publicAPI/v2/timeseries/data/CUUSA210SA0' ) private_constant :DEFAULT_CPI_SERIES_URL attr_reader :url, :bls_token private :url, :bls_token def initialize @url = URI(ENV['CPI_SERIES_URL'] || DEFAULT_CPI_SERIES_URL) @bls_token = ENV.fetch('BLS_TOKEN') end def cpi resp = fetch_raw_response return nil unless resp['Results']['series'] last_cpi_value(resp['Results']['series'].first['data']) end private def last_cpi_value(data) data .sort { |a, b| a['year'] <=> b['year'] } .then { |d| d.last['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::Get.new(url) .tap { |r| r['Authorization'] = "token #{bls_token}" } end end if $PROGRAM_NAME == __FILE__ puts CPIFetcher.new.cpi exit 0 end