Skip to main content

How to Get Real-Time Oil Prices in Python (Complete Tutorial)

14 min read

Learn how to fetch real-time oil prices in Python using the official OilPriceAPI SDK. Includes 15+ working code examples for WTI, Brent, natural gas, and more. Perfect for trading bots, data analysis, and energy applications.

Why Use Python for Oil Price Data?

Python has become the go-to language for commodity trading, financial analysis, and data science. When you need to fetch real-time oil prices for a trading bot, build energy market dashboards, or backtest trading strategies, Python's rich ecosystem makes it the obvious choice.

Here's why Python dominates energy data analysis:

  • pandas: Perfect for time-series analysis of historical oil prices
  • matplotlib/plotly: Visualize price trends and trading signals
  • numpy/scipy: Calculate correlations, volatility, and statistical models
  • requests: Simple HTTP client for REST APIs
  • asyncio: Build high-performance async trading bots

In this tutorial, I'll show you three methods to get oil prices in Python, from beginner-friendly to advanced. We'll start with the official OilPriceAPI SDK (easiest), then cover direct REST API calls (more control), and finally pandas integration for data analysis.

What You'll Build

  • ✓ Fetch current WTI, Brent, and natural gas prices
  • ✓ Get historical price data for backtesting
  • ✓ Calculate WTI-Brent spread for arbitrage opportunities
  • ✓ Build a simple price alert system
  • ✓ Analyze trends with pandas DataFrames
  • ✓ Handle errors and rate limits properly

Let's start with the easiest method: the official Python SDK.

Method 1: Official Python SDK (Recommended)

The fastest way to get oil prices in Python is using the official OilPriceAPI SDK. It handles authentication, error handling, and retry logic automatically. Perfect for most use cases.

Step 1: Installation

Install the SDK using pip:

pip install oilpriceapi

Or if you're using Poetry:

poetry add oilpriceapi

Step 2: Get Your API Key

Sign up at oilpriceapi.com to get your free API key (100 API requests included). Copy it from your dashboard.

Security Tip: Never hardcode API keys in your code. Use environment variables or a secrets manager.

Step 3: Fetch Current Prices

Here's the simplest example - fetching the current Brent crude price:

from oilpriceapi import Client

# Initialize client with your API key
client = Client(api_key="your_api_key_here")

# Fetch current Brent crude price
price_data = client.get_latest_price(by_code="BRENT_CRUDE_USD")

print(f"Brent Crude: \\$\{price_data['price']\}")
print(f"As of: {price_data['created_at']}")

# Output:
# Brent Crude: $82.30
# As of: 2025-01-15T14:35:22Z

That's it! Three lines of code to get live oil prices. Let's explore more examples.

Example 2: Multiple Commodities

Fetch prices for multiple commodities in a single script:

from oilpriceapi import Client

client = Client(api_key="your_api_key_here")

# List of commodities to fetch
commodities = [
    "BRENT_CRUDE_USD",
    "WTI_USD",
    "NATURAL_GAS_USD",
    "GASOLINE_USD",
    "DIESEL_USD"
]

print("Current Energy Prices:")
print("-" * 40)

for code in commodities:
    price_data = client.get_latest_price(by_code=code)
    name = price_data['name']
    price = price_data['price']
    print(f"{name:25} $"+f"{price:>7.2f}")

# Output:
# Current Energy Prices:
# ----------------------------------------
# Brent Crude Oil          $  82.30
# WTI Crude Oil            $  78.45
# Natural Gas              $   3.12
# RBOB Gasoline            $   2.34
# Ultra Low Sulfur Diesel  $   2.89

Example 3: Historical Data

Get historical prices for backtesting trading strategies:

from oilpriceapi import Client
from datetime import datetime, timedelta

client = Client(api_key="your_api_key_here")

# Get WTI prices for the past 30 days
end_date = datetime.now()
start_date = end_date - timedelta(days=30)

historical_data = client.get_historical_prices(
    by_code="WTI_USD",
    start_date=start_date.isoformat(),
    end_date=end_date.isoformat()
)

print(f"WTI Prices - Last 30 Days:")
print(f"Total data points: {len(historical_data['data'])}")
print(f"First price: \\$\{historical_data['data'][0]['price']\}")
print(f"Last price: \\$\{historical_data['data'][-1]['price']\}")

# Calculate simple statistics
prices = [d['price'] for d in historical_data['data']]
avg_price = sum(prices) / len(prices)
min_price = min(prices)
max_price = max(prices)

print(f"\nStatistics:")
print(f"Average: \\$\{avg_price:.2f\}")
print(f"Min: \\$\{min_price:.2f\}")
print(f"Max: \\$\{max_price:.2f\}")
print(f"Range: \\$\{max_price - min_price:.2f\}")

Example 4: Error Handling

Production code should handle errors gracefully:

from oilpriceapi import Client
from oilpriceapi.exceptions import (
    OilPriceAPIError,
    AuthenticationError,
    RateLimitError
)

client = Client(api_key="your_api_key_here")

try:
    price_data = client.get_latest_price(by_code="BRENT_CRUDE_USD")
    print(f"Brent: \\$\{price_data['price']\}")

except AuthenticationError:
    print("Error: Invalid API key. Check your credentials.")

except RateLimitError as e:
    print(f"Error: Rate limit exceeded. Try again in {e.retry_after} seconds.")

except OilPriceAPIError as e:
    print(f"API Error: {e}")

except Exception as e:
    print(f"Unexpected error: {e}")

Example 5: Using Environment Variables

Store your API key securely using environment variables:

# .env file
OIL_PRICE_API_KEY=your_api_key_here

# Python code
import os
from dotenv import load_dotenv
from oilpriceapi import Client

# Load environment variables
load_dotenv()

# Initialize client from environment
client = Client(api_key=os.getenv("OIL_PRICE_API_KEY"))

# Fetch prices
price_data = client.get_latest_price(by_code="WTI_USD")
print(f"WTI: \\$\{price_data['price']\}")

Install python-dotenv first:

pip install python-dotenv

SDK Advantages

  • ✓ Automatic authentication header management
  • ✓ Built-in retry logic with exponential backoff
  • ✓ Type hints for better IDE autocomplete
  • ✓ Clean Pythonic API
  • ✓ Error handling with custom exceptions
  • ✓ Maintained and updated regularly

Method 2: Direct REST API with Requests

If you prefer more control or want to avoid dependencies, you can call the REST API directly using Python's requests library.

Step 1: Install Requests

pip install requests

Step 2: Make API Calls

Here's a simple example fetching current Brent prices:

import requests

API_KEY = "your_api_key_here"
BASE_URL = "https://api.oilpriceapi.com/v1"

# Set up headers
headers = {
    "Authorization": f"Token {API_KEY}",
    "Content-Type": "application/json"
}

# Fetch latest Brent price
response = requests.get(
    f"{BASE_URL}/prices/latest",
    headers=headers,
    params={"by_code": "BRENT_CRUDE_USD"}
)

# Check for errors
response.raise_for_status()

# Parse JSON response
data = response.json()
price_info = data['data']

print(f"Brent Crude: \\$\{price_info['price']\}")
print(f"Updated: {price_info['created_at']}")

Example 6: Historical Data with Requests

import requests
from datetime import datetime, timedelta

API_KEY = "your_api_key_here"
BASE_URL = "https://api.oilpriceapi.com/v1"

headers = {
    "Authorization": f"Token {API_KEY}",
    "Content-Type": "application/json"
}

# Calculate date range
end_date = datetime.now()
start_date = end_date - timedelta(days=90)

# Fetch 90 days of WTI data
response = requests.get(
    f"{BASE_URL}/prices/historical",
    headers=headers,
    params={
        "by_code": "WTI_USD",
        "start_date": start_date.strftime("%Y-%m-%d"),
        "end_date": end_date.strftime("%Y-%m-%d")
    }
)

response.raise_for_status()
data = response.json()

print(f"Retrieved {len(data['data'])} data points")

# Calculate 30-day moving average
prices = [d['price'] for d in data['data']]
moving_avg_30 = sum(prices[-30:]) / 30

print(f"30-day moving average: \\$\{moving_avg_30:.2f\}")
print(f"Current price: \\$\{prices[-1]:.2f\}")

if prices[-1] > moving_avg_30:
    print("Signal: Price above MA30 - BULLISH")
else:
    print("Signal: Price below MA30 - BEARISH")

Example 7: Robust Error Handling

import requests
from requests.exceptions import RequestException
import time

def fetch_oil_price(commodity_code, max_retries=3):
    """
    Fetch oil price with retry logic.

    Args:
        commodity_code: Commodity code (e.g., "WTI_USD")
        max_retries: Maximum number of retry attempts

    Returns:
        Price data or None if failed
    """
    API_KEY = "your_api_key_here"
    BASE_URL = "https://api.oilpriceapi.com/v1"

    headers = {
        "Authorization": f"Token {API_KEY}",
        "Content-Type": "application/json"
    }

    for attempt in range(max_retries):
        try:
            response = requests.get(
                f"{BASE_URL}/prices/latest",
                headers=headers,
                params={"by_code": commodity_code},
                timeout=10  # 10 second timeout
            )

            # Handle rate limiting (429)
            if response.status_code == 429:
                retry_after = int(response.headers.get('Retry-After', 60))
                print(f"Rate limited. Waiting {retry_after}s...")
                time.sleep(retry_after)
                continue

            # Raise exception for 4xx/5xx errors
            response.raise_for_status()

            # Success
            return response.json()['data']

        except RequestException as e:
            print(f"Attempt {attempt + 1} failed: {e}")
            if attempt < max_retries - 1:
                wait_time = 2 ** attempt  # Exponential backoff
                print(f"Retrying in {wait_time}s...")
                time.sleep(wait_time)
            else:
                print("Max retries exceeded")
                return None

    return None

# Usage
price_data = fetch_oil_price("BRENT_CRUDE_USD")
if price_data:
    print(f"Brent: \\$\{price_data['price']\}")
else:
    print("Failed to fetch price")

When to use direct REST API:

  • • You want minimal dependencies
  • • You're already using requests for other APIs
  • • You need custom retry or caching logic
  • • You're integrating with non-Python systems

Method 3: pandas + API for Analysis

For data analysis, combine the API with pandas DataFrames. This is perfect for backtesting trading strategies, calculating correlations, and visualizing trends.

Installation

pip install oilpriceapi pandas matplotlib

Example 8: DataFrame Analysis

from oilpriceapi import Client
import pandas as pd
from datetime import datetime, timedelta

client = Client(api_key="your_api_key_here")

# Fetch 1 year of WTI data
end_date = datetime.now()
start_date = end_date - timedelta(days=365)

historical_data = client.get_historical_prices(
    by_code="WTI_USD",
    start_date=start_date.isoformat(),
    end_date=end_date.isoformat()
)

# Convert to DataFrame
df = pd.DataFrame(historical_data['data'])
df['created_at'] = pd.to_datetime(df['created_at'])
df = df.set_index('created_at')
df = df.sort_index()

# Calculate metrics
df['MA_7'] = df['price'].rolling(window=7).mean()
df['MA_30'] = df['price'].rolling(window=30).mean()
df['daily_return'] = df['price'].pct_change()
df['volatility_30d'] = df['daily_return'].rolling(window=30).std()

print("WTI Analysis - Past Year")
print("=" * 50)
print(f"Current Price: \\$\{df['price'].iloc[-1]:.2f\}")
print(f"7-day MA: \\$\{df['MA_7'].iloc[-1]:.2f\}")
print(f"30-day MA: \\$\{df['MA_30'].iloc[-1]:.2f\}")
print(f"30-day Volatility: {df['volatility_30d'].iloc[-1]:.2%}")
print(f"Year High: \\$\{df['price'].max():.2f\}")
print(f"Year Low: \\$\{df['price'].min():.2f\}")
print(f"YTD Return: {((df['price'].iloc[-1] / df['price'].iloc[0]) - 1):.2%}")

Example 9: WTI-Brent Spread Analysis

from oilpriceapi import Client
import pandas as pd
from datetime import datetime, timedelta

client = Client(api_key="your_api_key_here")

# Fetch data for both commodities
end_date = datetime.now()
start_date = end_date - timedelta(days=180)

wti_data = client.get_historical_prices(
    by_code="WTI_USD",
    start_date=start_date.isoformat(),
    end_date=end_date.isoformat()
)

brent_data = client.get_historical_prices(
    by_code="BRENT_CRUDE_USD",
    start_date=start_date.isoformat(),
    end_date=end_date.isoformat()
)

# Create DataFrames
wti_df = pd.DataFrame(wti_data['data'])
wti_df['created_at'] = pd.to_datetime(wti_df['created_at'])
wti_df = wti_df.set_index('created_at')[['price']].rename(columns={'price': 'wti'})

brent_df = pd.DataFrame(brent_data['data'])
brent_df['created_at'] = pd.to_datetime(brent_df['created_at'])
brent_df = brent_df.set_index('created_at')[['price']].rename(columns={'price': 'brent'})

# Merge and calculate spread
df = wti_df.join(brent_df, how='inner')
df['spread'] = df['brent'] - df['wti']
df['spread_ma'] = df['spread'].rolling(window=30).mean()

# Analysis
print("WTI-Brent Spread Analysis")
print("=" * 50)
print(f"Current Spread: \\$\{df['spread'].iloc[-1]:.2f\}")
print(f"30-day Avg Spread: \\$\{df['spread_ma'].iloc[-1]:.2f\}")
print(f"Spread Range: \$\{df['spread'].min():.2f\} to \\$\{df['spread'].max():.2f\}")
print(f"Spread Std Dev: \\$\{df['spread'].std():.2f\}")

# Trading signal
current_spread = df['spread'].iloc[-1]
avg_spread = df['spread_ma'].iloc[-1]

if current_spread > avg_spread + df['spread'].std():
    print("\nSignal: WIDE SPREAD - Consider WTI long / Brent short")
elif current_spread < avg_spread - df['spread'].std():
    print("\nSignal: NARROW SPREAD - Consider WTI short / Brent long")
else:
    print("\nSignal: NEUTRAL - Spread within normal range")

Example 10: Correlation Analysis

from oilpriceapi import Client
import pandas as pd
from datetime import datetime, timedelta

client = Client(api_key="your_api_key_here")

# Fetch multiple commodities
commodities = ["WTI_USD", "BRENT_CRUDE_USD", "NATURAL_GAS_USD"]
end_date = datetime.now()
start_date = end_date - timedelta(days=365)

dfs = []
for code in commodities:
    data = client.get_historical_prices(
        by_code=code,
        start_date=start_date.isoformat(),
        end_date=end_date.isoformat()
    )
    df = pd.DataFrame(data['data'])
    df['created_at'] = pd.to_datetime(df['created_at'])
    df = df.set_index('created_at')[['price']].rename(columns={'price': code})
    dfs.append(df)

# Merge all DataFrames
df = pd.concat(dfs, axis=1).dropna()

# Calculate daily returns
returns = df.pct_change().dropna()

# Correlation matrix
correlation = returns.corr()

print("Correlation Matrix (Daily Returns)")
print("=" * 50)
print(correlation)

print("\nKey Insights:")
print(f"WTI vs Brent correlation: {correlation.loc['WTI_USD', 'BRENT_CRUDE_USD']:.3f}")
print(f"WTI vs Natural Gas: {correlation.loc['WTI_USD', 'NATURAL_GAS_USD']:.3f}")
print(f"Brent vs Natural Gas: {correlation.loc['BRENT_CRUDE_USD', 'NATURAL_GAS_USD']:.3f}")

Example 11: Visualization

from oilpriceapi import Client
import pandas as pd
import matplotlib.pyplot as plt
from datetime import datetime, timedelta

client = Client(api_key="your_api_key_here")

# Fetch 6 months of data
end_date = datetime.now()
start_date = end_date - timedelta(days=180)

wti_data = client.get_historical_prices(
    by_code="WTI_USD",
    start_date=start_date.isoformat(),
    end_date=end_date.isoformat()
)

# Create DataFrame
df = pd.DataFrame(wti_data['data'])
df['created_at'] = pd.to_datetime(df['created_at'])
df = df.set_index('created_at')
df = df.sort_index()

# Calculate moving averages
df['MA_7'] = df['price'].rolling(window=7).mean()
df['MA_30'] = df['price'].rolling(window=30).mean()

# Plot
plt.figure(figsize=(12, 6))
plt.plot(df.index, df['price'], label='WTI Price', linewidth=1)
plt.plot(df.index, df['MA_7'], label='7-day MA', linewidth=1.5)
plt.plot(df.index, df['MA_30'], label='30-day MA', linewidth=1.5)

plt.title('WTI Crude Oil Price - 6 Month Trend', fontsize=16)
plt.xlabel('Date', fontsize=12)
plt.ylabel('Price (USD)', fontsize=12)
plt.legend()
plt.grid(True, alpha=0.3)
plt.tight_layout()

# Save to file
plt.savefig('wti_price_chart.png', dpi=300)
print("Chart saved as wti_price_chart.png")

Real-World Use Cases

Let's look at complete, production-ready examples you can use as starting points for real projects.

Use Case 1: Trading Bot (Moving Average Crossover)

from oilpriceapi import Client
import pandas as pd
from datetime import datetime, timedelta
import time

def check_trading_signal():
    """
    Simple moving average crossover strategy for WTI.
    Returns 'BUY', 'SELL', or 'HOLD'.
    """
    client = Client(api_key="your_api_key_here")

    # Get 90 days of data
    end_date = datetime.now()
    start_date = end_date - timedelta(days=90)

    data = client.get_historical_prices(
        by_code="WTI_USD",
        start_date=start_date.isoformat(),
        end_date=end_date.isoformat()
    )

    # Convert to DataFrame
    df = pd.DataFrame(data['data'])
    df['created_at'] = pd.to_datetime(df['created_at'])
    df = df.set_index('created_at').sort_index()

    # Calculate moving averages
    df['MA_short'] = df['price'].rolling(window=10).mean()
    df['MA_long'] = df['price'].rolling(window=30).mean()

    # Get latest values
    current_price = df['price'].iloc[-1]
    ma_short_current = df['MA_short'].iloc[-1]
    ma_long_current = df['MA_long'].iloc[-1]

    ma_short_prev = df['MA_short'].iloc[-2]
    ma_long_prev = df['MA_long'].iloc[-2]

    # Generate signal
    signal = 'HOLD'

    # Bullish crossover
    if ma_short_prev < ma_long_prev and ma_short_current > ma_long_current:
        signal = 'BUY'

    # Bearish crossover
    elif ma_short_prev > ma_long_prev and ma_short_current < ma_long_current:
        signal = 'SELL'

    return {
        'signal': signal,
        'price': current_price,
        'ma_short': ma_short_current,
        'ma_long': ma_long_current,
        'timestamp': datetime.now().isoformat()
    }

# Run bot every hour
while True:
    result = check_trading_signal()

    print(f"[{result['timestamp']}]")
    print(f"WTI: \${result['price']:.2f}")
    print(f"MA(10): ${result['ma_short']:.2f}, MA(30): \${result['ma_long']:.2f}")
    print(f"SIGNAL: {result['signal']}")
    print("-" * 50)

    if result['signal'] != 'HOLD':
        # Send alert (email, SMS, Discord, etc.)
        print(f"ALERT: {result['signal']} signal generated!")

    # Wait 1 hour
    time.sleep(3600)

Use Case 2: Price Alert System

from oilpriceapi import Client
import time
import smtplib
from email.mime.text import MIMEText

class PriceAlertSystem:
    def __init__(self, api_key, email_config):
        self.client = Client(api_key=api_key)
        self.email_config = email_config
        self.alerts = []

    def add_alert(self, commodity, condition, threshold):
        """
        Add price alert.

        Args:
            commodity: e.g., "BRENT_CRUDE_USD"
            condition: "above" or "below"
            threshold: Price threshold
        """
        self.alerts.append({
            'commodity': commodity,
            'condition': condition,
            'threshold': threshold,
            'triggered': False
        })

    def send_email(self, subject, body):
        """Send email notification."""
        msg = MIMEText(body)
        msg['Subject'] = subject
        msg['From'] = self.email_config['from']
        msg['To'] = self.email_config['to']

        with smtplib.SMTP(self.email_config['smtp_server'], 587) as server:
            server.starttls()
            server.login(
                self.email_config['username'],
                self.email_config['password']
            )
            server.send_message(msg)

    def check_alerts(self):
        """Check all alerts and send notifications."""
        for alert in self.alerts:
            if alert['triggered']:
                continue

            # Fetch current price
            price_data = self.client.get_latest_price(
                by_code=alert['commodity']
            )
            current_price = price_data['price']

            # Check condition
            triggered = False
            if alert['condition'] == 'above' and current_price > alert['threshold']:
                triggered = True
            elif alert['condition'] == 'below' and current_price < alert['threshold']:
                triggered = True

            if triggered:
                alert['triggered'] = True

                # Send notification
                subject = f"Price Alert: {alert['commodity']}"
                body = f"""
Price Alert Triggered!

Commodity: {alert['commodity']}
Condition: {alert['condition']} ${alert['threshold']}
Current Price: ${current_price}

This is an automated alert from your Oil Price Monitor.
                """

                self.send_email(subject, body.strip())
                print(f"Alert sent for {alert['commodity']}")

    def run(self, interval=300):
        """Run alert system (check every 5 minutes by default)."""
        print("Price Alert System started...")
        while True:
            self.check_alerts()
            time.sleep(interval)

# Usage
email_config = {
    'from': '[email protected]',
    'to': '[email protected]',
    'smtp_server': 'smtp.gmail.com',
    'username': '[email protected]',
    'password': 'your_app_password'
}

alert_system = PriceAlertSystem(
    api_key="your_api_key_here",
    email_config=email_config
)

# Add alerts
alert_system.add_alert("BRENT_CRUDE_USD", "above", 85.00)
alert_system.add_alert("WTI_USD", "below", 75.00)
alert_system.add_alert("NATURAL_GAS_USD", "above", 4.00)

# Start monitoring
alert_system.run()

Use Case 3: Data Analysis Notebook

Perfect for Jupyter notebooks and exploratory analysis:

# Jupyter Notebook Example
from oilpriceapi import Client
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from datetime import datetime, timedelta

# Configure plotting
sns.set_style("darkgrid")
plt.rcParams['figure.figsize'] = (14, 8)

# Initialize client
client = Client(api_key="your_api_key_here")

# Fetch 2 years of data
end_date = datetime.now()
start_date = end_date - timedelta(days=730)

# Get WTI and Brent data
wti = client.get_historical_prices(
    by_code="WTI_USD",
    start_date=start_date.isoformat(),
    end_date=end_date.isoformat()
)

brent = client.get_historical_prices(
    by_code="BRENT_CRUDE_USD",
    start_date=start_date.isoformat(),
    end_date=end_date.isoformat()
)

# Create DataFrames
df_wti = pd.DataFrame(wti['data'])
df_wti['date'] = pd.to_datetime(df_wti['created_at'])
df_wti = df_wti.set_index('date')[['price']].rename(columns={'price': 'WTI'})

df_brent = pd.DataFrame(brent['data'])
df_brent['date'] = pd.to_datetime(df_brent['created_at'])
df_brent = df_brent.set_index('date')[['price']].rename(columns={'price': 'Brent'})

# Merge
df = df_wti.join(df_brent).dropna()

# Calculate spread
df['Spread'] = df['Brent'] - df['WTI']

# Plot 1: Price comparison
fig, axes = plt.subplots(2, 2, figsize=(16, 10))

# Prices over time
axes[0, 0].plot(df.index, df['WTI'], label='WTI', linewidth=1.5)
axes[0, 0].plot(df.index, df['Brent'], label='Brent', linewidth=1.5)
axes[0, 0].set_title('WTI vs Brent - 2 Year History', fontsize=14)
axes[0, 0].legend()
axes[0, 0].grid(True, alpha=0.3)

# Spread over time
axes[0, 1].plot(df.index, df['Spread'], color='green', linewidth=1.5)
axes[0, 1].axhline(df['Spread'].mean(), color='red', linestyle='--', label='Mean')
axes[0, 1].set_title('Brent-WTI Spread', fontsize=14)
axes[0, 1].legend()
axes[0, 1].grid(True, alpha=0.3)

# Distribution histogram
axes[1, 0].hist(df['WTI'], bins=50, alpha=0.6, label='WTI')
axes[1, 0].hist(df['Brent'], bins=50, alpha=0.6, label='Brent')
axes[1, 0].set_title('Price Distribution', fontsize=14)
axes[1, 0].legend()
axes[1, 0].grid(True, alpha=0.3)

# Scatter plot
axes[1, 1].scatter(df['WTI'], df['Brent'], alpha=0.5, s=10)
axes[1, 1].set_xlabel('WTI Price')
axes[1, 1].set_ylabel('Brent Price')
axes[1, 1].set_title('WTI vs Brent Correlation', fontsize=14)
axes[1, 1].grid(True, alpha=0.3)

plt.tight_layout()
plt.show()

# Print statistics
print("Summary Statistics")
print("=" * 60)
print(df.describe())
print("\nCorrelation:", df['WTI'].corr(df['Brent']))

Best Practices

1. Caching to Reduce API Calls

Oil prices don't change every second. Cache responses for 1-5 minutes:

from functools import lru_cache
import time

@lru_cache(maxsize=128)
def get_cached_price(commodity_code, cache_key):
    """Cache price for 5 minutes."""
    client = Client(api_key="your_api_key_here")
    return client.get_latest_price(by_code=commodity_code)

# Use cache key based on timestamp (changes every 5 min)
cache_key = int(time.time() // 300)
price = get_cached_price("WTI_USD", cache_key)

2. Respect Rate Limits

Implement exponential backoff when hitting rate limits:

import time
from oilpriceapi.exceptions import RateLimitError

def fetch_with_backoff(client, commodity_code, max_retries=5):
    for attempt in range(max_retries):
        try:
            return client.get_latest_price(by_code=commodity_code)
        except RateLimitError as e:
            if attempt == max_retries - 1:
                raise
            wait_time = 2 ** attempt  # 1, 2, 4, 8, 16 seconds
            print(f"Rate limited. Waiting {wait_time}s...")
            time.sleep(wait_time)

3. Use Async for Multiple Commodities

Fetch multiple commodities concurrently with asyncio:

from oilpriceapi import AsyncClient
import asyncio

async def fetch_multiple_prices():
    client = AsyncClient(api_key="your_api_key_here")

    commodities = ["WTI_USD", "BRENT_CRUDE_USD", "NATURAL_GAS_USD"]

    # Fetch all concurrently
    tasks = [
        client.get_latest_price(by_code=code)
        for code in commodities
    ]

    results = await asyncio.gather(*tasks)

    for result in results:
        print(f"{result['name']}: \${result['price']}")

# Run async function
asyncio.run(fetch_multiple_prices())

4. Logging for Production

Always log API calls in production:

import logging
from oilpriceapi import Client

# Configure logging
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(levelname)s - %(message)s'
)
logger = logging.getLogger(__name__)

client = Client(api_key="your_api_key_here")

try:
    logger.info("Fetching WTI price...")
    price_data = client.get_latest_price(by_code="WTI_USD")
    logger.info(f"WTI price: ${price_data['price']}")
except Exception as e:
    logger.error(f"Failed to fetch price: {e}", exc_info=True)

Frequently Asked Questions

Q: How do I get oil prices in Python?

A: Install the oilpriceapi package with pip install oilpriceapi, sign up for a free API key at oilpriceapi.com, then use client.get_latest_price(by_code="WTI_USD") to fetch current prices.

Q: Is there a free Python oil price API?

A: Yes. OilPriceAPI offers 100 free API requests with every account (no credit card required). The U.S. Energy Information Administration (EIA) also provides free daily oil price data, though it's delayed by 1-2 days.

Q: Can I use pandas to analyze oil price data?

A: Absolutely. Fetch historical data using the API, convert the JSON response to a pandas DataFrame with pd.DataFrame(data['data']), and analyze with standard pandas methods like rolling averages, correlations, and visualizations.

Q: How do I build a Python trading bot for oil?

A: Use the OilPriceAPI SDK to fetch real-time prices, implement your trading logic (e.g., moving average crossover), and execute trades via your broker's API. Start with paper trading to test your strategy before using real money.

Start Building with Python Today

You now have everything you need to fetch and analyze oil prices in Python. Whether you're building a trading bot, creating data visualizations, or backtesting strategies, the OilPriceAPI SDK makes it simple and reliable.

Ready to Get Started?

Install the SDK and get your free API key. 100 API requests included, no credit card required.

pip install oilpriceapi

100 free API requests • 100+ commodities • Real-time prices • Type hints included