Python API Guide
Overview
This guide covers using ISO-DART programmatically from Python scripts and applications.
Installation
# Option 1: Use as a library (recommended)
import sys
sys.path.append('/path/to/ISO-DART')
from lib.iso.caiso import CAISOClient, Market
from lib.iso.miso import MISOClient, MISOConfig
# ... etc
# Option 2: Install as package (future)
# pip install isodart
Basic Usage Pattern
All ISO clients follow a similar pattern:
from datetime import date
# 1. Import the client
from lib.iso.caiso import CAISOClient, Market
# 2. Create client instance
client = CAISOClient()
# 3. Download data
success = client.get_lmp(
market=Market.DAM,
start_date=date(2024, 1, 1),
end_date=date(2024, 1, 31)
)
# 4. Clean up
client.cleanup()
CAISO Client
Basic LMP Download
from datetime import date
from lib.iso.caiso import CAISOClient, Market
# Initialize client
client = CAISOClient()
# Download Day-Ahead LMP
client.get_lmp(
market=Market.DAM,
start_date=date(2024, 1, 1),
end_date=date(2024, 1, 31)
)
# Download Real-Time LMP
client.get_lmp(
market=Market.RTM,
start_date=date(2024, 1, 1),
end_date=date(2024, 1, 7)
)
client.cleanup()
Available Markets
from lib.iso.caiso import Market
Market.DAM # Day-Ahead Market
Market.HASP # Hour-Ahead Scheduling Process
Market.RTM # Real-Time Market
Market.RTPD # Real-Time Pre-Dispatch
Market.RUC # Residual Unit Commitment
Market.TWO_DA # Two Day-Ahead
Market.SEVEN_DA # Seven Day-Ahead
Load Forecasts
# Day-Ahead forecast
client.get_load_forecast(
market=Market.DAM,
start_date=date(2024, 1, 1),
end_date=date(2024, 1, 31)
)
# 7-Day forecast
client.get_load_forecast(
market=Market.SEVEN_DA,
start_date=date(2024, 1, 1),
end_date=date(2024, 1, 31)
)
Renewable Generation
# Wind and solar summary
client.get_wind_solar_summary(
start_date=date(2024, 1, 1),
end_date=date(2024, 1, 31)
)
Ancillary Services
# AS prices
client.get_ancillary_services_prices(
market=Market.DAM,
start_date=date(2024, 1, 1),
end_date=date(2024, 1, 31)
)
# AS requirements
client.get_ancillary_services_requirements(
market=Market.DAM,
start_date=date(2024, 1, 1),
end_date=date(2024, 1, 31),
anc_type='ALL', # or 'RU', 'RD', 'SR', 'NR'
anc_region='ALL'
)
Custom Configuration
from pathlib import Path
from lib.iso.caiso import CAISOClient, CAISOConfig
# Custom config
config = CAISOConfig(
data_dir=Path('my_data/CAISO'),
max_retries=5,
timeout=60,
retry_delay=10
)
client = CAISOClient(config=config)
MISO Client
Setup with API Keys
from lib.iso.miso import MISOClient, MISOConfig
# Load from config file
config = MISOConfig.from_ini_file()
client = MISOClient(config)
# Or specify directly
config = MISOConfig(
pricing_api_key='your-pricing-key',
lgi_api_key='your-lgi-key'
)
client = MISOClient(config)
LMP Data
from datetime import date
# Day-Ahead ExAnte LMP
data = client.get_lmp(
lmp_type='da_exante',
start_date=date(2024, 1, 1),
duration=30,
node='ALTW.WELLS1' # Optional: specific node
)
# Save to CSV
if data:
client.save_to_csv(data, 'miso_lmp.csv')
Available LMP Types
'da_exante' # Day-Ahead ExAnte
'da_expost' # Day-Ahead ExPost
'rt_exante' # Real-Time ExAnte
'rt_expost' # Real-Time ExPost
Load and Generation
# Actual load
load_data = client.get_demand(
demand_type='rt_actual',
start_date=date(2024, 1, 1),
duration=30,
time_resolution='daily'
)
# Fuel mix
fuel_data = client.get_fuel_mix(
start_date=date(2024, 1, 1),
duration=30
)
# Generation by fuel type
gen_data = client.get_generation(
gen_type='rt_fuel_type',
start_date=date(2024, 1, 1),
duration=30
)
Working with MISO Data
# Download and process
data = client.get_lmp('da_exante', date(2024, 1, 1), 7)
if data:
# Data is a dict: {date: [records]}
print(f"Downloaded data for {len(data)} dates")
# Save to CSV
client.save_to_csv(data, 'output.csv')
# Or process directly
import pandas as pd
all_records = []
for date_key, records in data.items():
for record in records:
record['query_date'] = date_key
all_records.append(record)
df = pd.DataFrame(all_records)
print(df.head())
NYISO Client
Basic Usage
from lib.iso.nyiso import NYISOClient, NYISOMarket
client = NYISOClient()
# LBMP data
client.get_lbmp(
market=NYISOMarket.DAM,
level='zonal', # or 'generator'
start_date=date(2024, 1, 1),
duration=30
)
# Load data
client.get_load_data(
load_type='actual',
start_date=date(2024, 1, 1),
duration=30
)
# Fuel mix
client.get_fuel_mix(
start_date=date(2024, 1, 1),
duration=30
)
client.cleanup()
SPP Client
LMP Data
from lib.iso.spp import SPPClient, SPPMarket
client = SPPClient()
# LMP by settlement location
client.get_lmp(
market=SPPMarket.DAM,
start_date=date(2024, 1, 1),
end_date=date(2024, 1, 31),
by_location=True # False for by bus
)
# Market clearing prices
client.get_mcp(
market=SPPMarket.RTBM,
start_date=date(2024, 1, 1),
end_date=date(2024, 1, 31)
)
client.cleanup()
Load and Resource Forecasts
# Short-term load forecast
client.get_load_forecast(
start_date=date(2024, 1, 1),
end_date=date(2024, 1, 31),
forecast_type='stlf'
)
# Medium-term resource (wind + solar) forecast
client.get_resource_forecast(
start_date=date(2024, 1, 1),
end_date=date(2024, 1, 31),
forecast_type='mtrf'
)
BPA Client
Historical Data
from lib.iso.bpa import BPAClient
client = BPAClient()
# Wind generation and total load
client.get_wind_gen_total_load(
year=2024,
start_date=date(2024, 1, 1),
end_date=date(2024, 1, 31)
)
# Operating reserves
client.get_reserves_deployed(
year=2024,
start_date=date(2024, 1, 1),
end_date=date(2024, 1, 31)
)
# Outages
client.get_outages(
year=2024,
start_date=date(2024, 1, 1),
end_date=date(2024, 1, 31)
)
client.cleanup()
PJM Client
Setup
from lib.iso.pjm import PJMClient, PJMConfig
# Load from config
config = PJMConfig.from_ini_file()
client = PJMClient(config)
# Or specify directly
config = PJMConfig(api_key='your-api-key')
client = PJMClient(config)
LMP Data
# Day-ahead hourly LMP
client.get_lmp(
lmp_type='da_hourly',
start_date=date(2024, 1, 1),
duration=7,
pnode_id=51288 # Optional: specific node
)
# Real-time 5-minute LMP
client.get_lmp(
lmp_type='rt_5min',
start_date=date(2024, 1, 1),
duration=1 # Use shorter duration for 5-min data
)
client.cleanup()
ISO-NE Client
Basic Usage
from lib.iso.isone import ISONEClient
client = ISONEClient()
# Day-ahead hourly LMP
paths = client.get_hourly_lmp(
start_date=date(2024, 1, 1),
end_date_exclusive=date(2024, 2, 1),
market='da',
report='final'
)
# 5-minute regulation prices
paths = client.get_5min_regulation_prices(
start_date=date(2024, 1, 1),
end_date_exclusive=date(2024, 2, 1)
)
Weather Client
Download Weather Data
from lib.weather.client import WeatherClient
client = WeatherClient()
# Download weather data (interactive station selection)
client.download_weather_data(
state='CA',
start_date=date(2024, 1, 1),
duration=30,
interactive=True
)
# Download solar data
client.download_solar_data(year=2024)
Advanced Patterns
Multi-ISO Download
from datetime import date
from lib.iso.caiso import CAISOClient, Market as CAISOMarket
from lib.iso.miso import MISOClient, MISOConfig
from lib.iso.nyiso import NYISOClient, NYISOMarket
start = date(2024, 1, 1)
end = date(2024, 1, 31)
# CAISO
caiso = CAISOClient()
caiso.get_lmp(CAISOMarket.DAM, start, end)
caiso.cleanup()
# MISO
miso_config = MISOConfig.from_ini_file()
miso = MISOClient(miso_config)
miso.get_lmp('da_exante', start, 30)
# NYISO
nyiso = NYISOClient()
nyiso.get_lbmp(NYISOMarket.DAM, 'zonal', start, 30)
nyiso.cleanup()
print("Downloaded data from all three ISOs")
Error Handling
from datetime import date
from lib.iso.caiso import CAISOClient, Market
import logging
# Setup logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
client = CAISOClient()
try:
success = client.get_lmp(
market=Market.DAM,
start_date=date(2024, 1, 1),
end_date=date(2024, 1, 31)
)
if success:
logger.info("Download successful")
else:
logger.error("Download failed")
except Exception as e:
logger.error(f"Error: {e}", exc_info=True)
finally:
client.cleanup()
Async/Parallel Downloads
from concurrent.futures import ThreadPoolExecutor
from datetime import date
from lib.iso.caiso import CAISOClient, Market
def download_market(market, start, end):
"""Download data for a specific market."""
client = CAISOClient()
try:
result = client.get_lmp(market, start, end)
return market, result
finally:
client.cleanup()
# Download multiple markets in parallel
markets = [Market.DAM, Market.HASP, Market.RTM]
start = date(2024, 1, 1)
end = date(2024, 1, 31)
with ThreadPoolExecutor(max_workers=3) as executor:
futures = [
executor.submit(download_market, m, start, end)
for m in markets
]
results = [f.result() for f in futures]
for market, success in results:
print(f"{market.value}: {'✓' if success else '✗'}")
Data Processing Pipeline
import pandas as pd
from datetime import date
from pathlib import Path
from lib.iso.caiso import CAISOClient, Market
def download_and_process(start_date, end_date):
"""Download data and perform basic processing."""
# Download
client = CAISOClient()
success = client.get_lmp(Market.DAM, start_date, end_date)
client.cleanup()
if not success:
return None
# Load the most recent file
data_dir = Path('data/CAISO')
files = sorted(data_dir.glob('*PRC_LMP*.csv'))
if not files:
return None
# Process
df = pd.read_csv(files[-1])
# Add datetime column
df['datetime'] = pd.to_datetime(df['OPR_DATE'])
# Calculate statistics
stats = {
'mean_price': df['VALUE'].mean(),
'max_price': df['VALUE'].max(),
'min_price': df['VALUE'].min(),
'date_range': f"{df['OPR_DATE'].min()} to {df['OPR_DATE'].max()}"
}
return df, stats
# Use it
df, stats = download_and_process(date(2024, 1, 1), date(2024, 1, 7))
if df is not None:
print(f"Mean price: ${stats['mean_price']:.2f}/MWh")
Custom Retry Logic
import time
from datetime import date
from lib.iso.caiso import CAISOClient, Market
def download_with_retry(client, market, start, end, max_retries=5):
"""Download with custom retry logic."""
for attempt in range(max_retries):
try:
success = client.get_lmp(market, start, end)
if success:
return True
print(f"Attempt {attempt + 1} failed, retrying...")
time.sleep(30 * (attempt + 1)) # Exponential backoff
except Exception as e:
print(f"Error on attempt {attempt + 1}: {e}")
if attempt < max_retries - 1:
time.sleep(30 * (attempt + 1))
return False
# Use it
client = CAISOClient()
success = download_with_retry(
client, Market.DAM,
date(2024, 1, 1), date(2024, 1, 31)
)
client.cleanup()
Best Practices
1. Always Clean Up
# Use try-finally
client = CAISOClient()
try:
client.get_lmp(Market.DAM, start, end)
finally:
client.cleanup()
# Or use context manager pattern (if implemented)
# with CAISOClient() as client:
# client.get_lmp(Market.DAM, start, end)
2. Check Return Values
success = client.get_lmp(Market.DAM, start, end)
if not success:
print("Download failed - check logs")
# Handle failure
3. Use Appropriate Date Ranges
from datetime import date, timedelta
# Don't download future dates
today = date.today()
safe_date = today - timedelta(days=2)
# Don't use excessively large ranges at once
# Break into chunks for better reliability
4. Configure Logging
import logging
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
handlers=[
logging.FileHandler('isodart.log'),
logging.StreamHandler()
]
)
Type Hints
ISO-DART v2.0 includes type hints for better IDE support:
from datetime import date
from lib.iso.caiso import CAISOClient, Market
# IDE will provide autocomplete and type checking
client: CAISOClient = CAISOClient()
market: Market = Market.DAM
start: date = date(2024, 1, 1)
success: bool = client.get_lmp(market, start, start)
Next Steps
See Command Line Usage Guide for CLI usage
See configuration for advanced config
See Analysis Examples for complete examples