Ruby Integration Guide
Integrate OilPriceAPI into your Ruby applications for real-time crude oil prices, Brent oil data, natural gas pricing, and energy commodity market information. Build solutions for commodities trading platforms, logistics applications, and fleet management systems.
Requirements
- Ruby 2.7 or higher
- Bundler (recommended)
Installation
Add to your Gemfile:
gem 'httparty'
# or
gem 'faraday'
Then run:
bundle install
Quick Start
Using Net::HTTP (No Dependencies)
require 'net/http'
require 'json'
require 'uri'
api_key = ENV['OILPRICE_API_KEY']
uri = URI('https://api.oilpriceapi.com/v1/prices/latest?by_code=WTI_USD')
request = Net::HTTP::Get.new(uri)
request['Authorization'] = "Token #{api_key}"
response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
http.request(request)
end
data = JSON.parse(response.body)
puts "WTI Price: #{data['data']['WTI_USD']['formatted']}"
Using HTTParty
require 'httparty'
class OilPriceClient
include HTTParty
base_uri 'https://api.oilpriceapi.com/v1'
def initialize(api_key = nil)
@api_key = api_key || ENV['OILPRICE_API_KEY']
end
def latest_prices(codes)
codes = codes.join(',') if codes.is_a?(Array)
self.class.get('/prices/latest', {
query: { by_code: codes },
headers: { 'Authorization' => "Token #{@api_key}" }
})
end
end
client = OilPriceClient.new
response = client.latest_prices('WTI_USD')
puts response['data']['WTI_USD']['formatted']
Complete API Client Class
require 'net/http'
require 'json'
require 'uri'
class OilPriceAPI
BASE_URL = 'https://api.oilpriceapi.com/v1'.freeze
class APIError < StandardError; end
class AuthenticationError < APIError; end
class RateLimitError < APIError; end
def initialize(api_key: nil)
@api_key = api_key || ENV['OILPRICE_API_KEY']
raise ArgumentError, 'API key is required' if @api_key.nil? || @api_key.empty?
end
def latest_prices(codes)
codes = codes.join(',') if codes.is_a?(Array)
request('/prices/latest', by_code: codes)
end
def historical_prices(code, days: 7)
request("/prices/past_#{days}_days", by_code: code)
end
def commodities
request('/commodities')
end
private
def request(endpoint, params = {})
uri = URI("#{BASE_URL}#{endpoint}")
uri.query = URI.encode_www_form(params) unless params.empty?
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
http.open_timeout = 10
http.read_timeout = 30
req = Net::HTTP::Get.new(uri)
req['Authorization'] = "Token #{@api_key}"
req['Content-Type'] = 'application/json'
req['Accept'] = 'application/json'
response = http.request(req)
handle_response(response)
end
def handle_response(response)
case response.code.to_i
when 200
JSON.parse(response.body)
when 401
raise AuthenticationError, 'Invalid API key'
when 403
raise APIError, 'Access forbidden'
when 429
raise RateLimitError, 'Rate limit exceeded'
else
raise APIError, "API error: HTTP #{response.code}"
end
end
end
Usage Examples
Fetch Multiple Commodities
client = OilPriceAPI.new
# Get multiple oil prices
commodities = %w[WTI_USD BRENT_CRUDE_USD NATURAL_GAS_USD]
prices = client.latest_prices(commodities)
prices['data'].each do |code, data|
puts "#{code}: #{data['formatted']}"
end
Historical Price Analysis
client = OilPriceAPI.new
# Get past week of WTI prices
history = client.historical_prices('WTI_USD', days: 7)
puts "WTI Price History:"
history['data'].each do |point|
date = Time.parse(point['created_at']).strftime('%Y-%m-%d')
puts " #{date}: $#{point['price']}"
end
# Calculate statistics
prices = history['data'].map { |p| p['price'] }
avg = prices.sum / prices.length
min = prices.min
max = prices.max
puts "\nStatistics:"
puts " Average: $#{avg.round(2)}"
puts " Range: $#{min} - $#{max}"
Rails Integration
# config/initializers/oilpriceapi.rb
Rails.application.config.oilpriceapi = OilPriceAPI.new(
api_key: Rails.application.credentials.dig(:oilpriceapi, :api_key)
)
# app/services/oil_price_service.rb
class OilPriceService
def initialize
@client = Rails.application.config.oilpriceapi
end
def current_prices(codes)
cache_key = "oil_prices_#{codes.sort.join('_')}"
Rails.cache.fetch(cache_key, expires_in: 5.minutes) do
@client.latest_prices(codes)
end
end
def price_history(code, days: 7)
cache_key = "oil_history_#{code}_#{days}"
Rails.cache.fetch(cache_key, expires_in: 15.minutes) do
@client.historical_prices(code, days: days)
end
end
end
# app/controllers/prices_controller.rb
class PricesController < ApplicationController
def index
service = OilPriceService.new
@prices = service.current_prices(%w[WTI_USD BRENT_CRUDE_USD])
end
end
Sinatra Example
require 'sinatra'
require 'json'
configure do
set :oil_client, OilPriceAPI.new
end
get '/api/prices' do
content_type :json
codes = params[:codes]&.split(',') || ['WTI_USD']
prices = settings.oil_client.latest_prices(codes)
prices.to_json
rescue OilPriceAPI::APIError => e
status 500
{ error: e.message }.to_json
end
get '/api/history/:code' do
content_type :json
days = (params[:days] || 7).to_i
history = settings.oil_client.historical_prices(params[:code], days: days)
history.to_json
rescue OilPriceAPI::APIError => e
status 500
{ error: e.message }.to_json
end
Concurrent Requests
require 'concurrent'
client = OilPriceAPI.new
commodities = %w[WTI_USD BRENT_CRUDE_USD NATURAL_GAS_USD HEATING_OIL_USD]
# Fetch all prices concurrently
futures = commodities.map do |code|
Concurrent::Future.execute do
{ code => client.latest_prices(code) }
end
end
# Collect results
results = futures.map(&:value).reduce({}, :merge)
results.each do |code, response|
if response['data'] && response['data'][code]
puts "#{code}: #{response['data'][code]['formatted']}"
end
end
Error Handling
def fetch_with_retry(client, codes, max_retries: 3)
retries = 0
begin
client.latest_prices(codes)
rescue OilPriceAPI::RateLimitError => e
retries += 1
if retries <= max_retries
backoff = 2**retries
puts "Rate limited, waiting #{backoff}s (attempt #{retries}/#{max_retries})"
sleep(backoff)
retry
end
raise
rescue OilPriceAPI::AuthenticationError
raise # Don't retry auth errors
rescue OilPriceAPI::APIError => e
retries += 1
if retries <= max_retries
puts "API error, retrying (attempt #{retries}/#{max_retries}): #{e.message}"
sleep(1)
retry
end
raise
end
end
# Usage
begin
prices = fetch_with_retry(client, 'WTI_USD')
puts prices['data']['WTI_USD']['formatted']
rescue OilPriceAPI::APIError => e
puts "Failed after retries: #{e.message}"
end
Best Practices
Environment Configuration
# Using dotenv gem
require 'dotenv'
Dotenv.load
# .env file
# OILPRICE_API_KEY=opa_live_your_key_here
client = OilPriceAPI.new # Reads from ENV automatically
Thread-Safe Client
class OilPriceAPI
# Make the client thread-safe for concurrent Rails requests
def initialize(api_key: nil)
@api_key = api_key || ENV['OILPRICE_API_KEY']
@mutex = Mutex.new
end
def latest_prices(codes)
@mutex.synchronize do
# ... request logic
end
end
end
Response Caching with Redis
require 'redis'
class CachedOilPriceClient
def initialize(client:, redis: Redis.new, ttl: 300)
@client = client
@redis = redis
@ttl = ttl
end
def latest_prices(codes)
codes = codes.join(',') if codes.is_a?(Array)
cache_key = "oil_prices:#{codes}"
cached = @redis.get(cache_key)
return JSON.parse(cached) if cached
response = @client.latest_prices(codes)
@redis.setex(cache_key, @ttl, response.to_json)
response
end
end
Common Commodity Codes
| Code | Description |
|---|---|
WTI_USD | West Texas Intermediate Crude Oil |
BRENT_CRUDE_USD | Brent Crude Oil |
NATURAL_GAS_USD | Natural Gas (Henry Hub) |
HEATING_OIL_USD | Heating Oil No. 2 |
DIESEL_USD | Ultra Low Sulfur Diesel |
Frequently Asked Questions
Is there an official SDK for Ruby?
Currently, OilPriceAPI provides code examples and integration patterns for Ruby. The examples above can be used directly in your project with Net::HTTP or HTTParty.
How do I handle rate limiting in Ruby?
Implement exponential backoff when you receive 429 (Too Many Requests) responses. Use sleep() with increasing delays between retries:
backoff = 2**attempt
sleep(backoff)
What's the recommended error handling approach?
Always check HTTP status codes before parsing responses. Handle network timeouts and implement proper retry logic for transient failures. Use custom exception classes like RateLimitError and AuthenticationError that inherit from a base APIError class.
Can I use async/concurrent requests?
Yes, Ruby supports concurrent requests through the concurrent-ruby gem. Use Concurrent::Future to fetch multiple commodity prices in parallel. For Rails applications, consider using ActiveJob with Sidekiq for background processing of API requests.
Related Resources
- Zapier Integration - No-code automation alternative
- Make Integration - Visual workflow automation
- Power BI Integration - Business intelligence dashboards
- Commodities Trading API - Trading platform integration
- Fleet Management API - Fleet cost tracking
- Logistics Fuel API - Supply chain applications
- PHP Developer Guide - Alternative language guide
- Go Developer Guide - High-performance alternative
- Authentication Guide - API key management
- API Reference - Complete endpoint documentation
- Rate Limiting - Usage limits and best practices