Skip to main content

API client for Enemera energy data API with enhanced functionality and enums

Project description

Enemera API Client

PyPI version Python License: MIT

A comprehensive Python client for the Enemera energy data API, providing secure access to European electricity market data with enhanced functionality, robust security features, and type-safe interfaces.

Key Features

  • 🔐 Enhanced Security: JWT token validation, secure session management, and credential protection
  • 📊 Multiple Output Formats: Native support for pandas DataFrames, Polars DataFrames, CSV, and Excel exports
  • 🔒 Type Safety: Comprehensive enums for markets, areas, and trading purposes with validation
  • 🌍 Timezone Handling: Automatic UTC to CET timezone conversion for European energy markets
  • ⚡ Robust Error Handling: Detailed exception hierarchy with retry logic and rate limiting
  • 🎯 Flexible Data Access: Generic curve access via unified client or specialized country-specific clients
  • 📦 Optional Dependencies: Install only what you need for your specific use case
  • 🛡️ Secure by Default: Built-in API key validation and secure HTTP session management

Supported Markets

Italy (IPEX)

  • Prices: Day-ahead (MGP) and intraday markets (MI1-MI7)
  • XBID Results: Cross-border intraday trading data with price statistics
  • Exchange Volumes: Trading volumes by market and purpose (BUY/SELL)
  • Ancillary Services: MSD, MB, MBa, MBs market data with detailed metrics
  • Load Data: Actual and forecast consumption by bidding zone
  • Generation: Actual and forecast generation by technology type
  • Commercial Flows: Inter-zonal power flows and capacity limits
  • Imbalance Data: System imbalance volumes, prices, and settlement data
  • DAM Demand: Day-ahead market actual and forecasted demand

Spain (OMIE)

  • Prices: Day-ahead (MD) and intraday market prices
  • XBID Results: Cross-border intraday trading data

Installation

Basic Installation

pip install enemera

With Optional Dependencies

# For pandas support
pip install enemera[pandas]

# For polars support  
pip install enemera[polars]

# For Excel export with openpyxl
pip install enemera[excel]

# For Excel export with xlsxwriter
pip install enemera[excel-xlsxwriter]

# Install everything
pip install enemera[all]

# Development dependencies
pip install enemera[dev]

Quick Start

Authentication

The client supports JWT-based API key authentication with built-in validation:

from enemera import EnemeraClient

# Initialize with API key (recommended)
client = EnemeraClient(api_key="your-jwt-api-key")

# Or set via environment variable ENEMERA_API_KEY
import os
os.environ['ENEMERA_API_KEY'] = "your-jwt-api-key"
client = EnemeraClient()

Basic Usage

from enemera import EnemeraClient, Curve
from datetime import date

client = EnemeraClient(api_key="your-jwt-api-key")

# Get Italian day-ahead prices
response = client.get(
    curve=Curve.ITALY_PRICES,
    market="MGP",
    date_from=date(2024, 1, 1),
    date_to=date(2024, 1, 7),
    area="NORD"
)

# Convert to pandas DataFrame
df = response.to_pandas()
print(df.head())

Using Type-Safe Enums

from enemera import EnemeraClient, Curve, Market, Area, Purpose

client = EnemeraClient(api_key="your-jwt-api-key")

# Type-safe market and area specification
response = client.get(
    curve=Curve.ITALY_PRICES,
    market=Market.MGP,
    area=Area.NORD,
    date_from="2024-01-01",
    date_to="2024-01-07"
)

Direct DataFrame Access

# Get data directly as pandas DataFrame with UTC timestamps
df = client.get_pandas(
    curve=Curve.ITALY_PRICES,
    market=Market.MGP,
    area=Area.NORD,
    date_from="2024-01-01",
    date_to="2024-01-07"
)

# Get data with CET timezone conversion
df_cet = client.get_pandas_cet(
    curve=Curve.ITALY_LOAD_ACTUAL,
    date_from="2024-01-01",
    date_to="2024-01-07",
    area=Area.NORD
)

Security Features

JWT Token Validation

The client automatically validates JWT tokens with comprehensive checks:

from enemera.security import validate_api_key, get_token_info

# Validate API key format and content
try:
    validated_key = validate_api_key("your-jwt-token")
    print("API key is valid")
    
    # Get token information (for debugging)
    token_info = get_token_info(validated_key)
    print(f"Token expires at: {token_info['expires_at']}")
    
except AuthenticationError as e:
    print(f"Invalid API key: {e}")

Secure Session Management

# Enable secure session (default)
client = EnemeraClient(api_key="your-key", use_secure_session=True)

# Legacy mode (for backward compatibility)
client = EnemeraClient(api_key="your-key", use_secure_session=False)

Data Export

CSV Export

response = client.get(curve=Curve.ITALY_PRICES, market="MGP", ...)
response.to_csv("prices.csv", index=True)

Excel Export

response = client.get(curve=Curve.ITALY_PRICES, market="MGP", ...)
response.to_excel("prices.xlsx", sheet_name="Prices", index=True)

Polars DataFrame

response = client.get(curve=Curve.ITALY_PRICES, market="MGP", ...)
df_polars = response.to_polars()

Country-Specific Clients

For specialized access, use dedicated client classes:

Italy Clients

from enemera.api import (
    ItalyPricesClient, 
    ItalyLoadActualClient, 
    ItalyGenerationClient,
    ItalyImbalanceDataClient,
    ItalyXbidResultsClient
)

# Italian electricity prices
italy_prices = ItalyPricesClient(api_key="your-key")
prices = italy_prices.get(
    market="MGP",
    date_from="2024-01-01",
    date_to="2024-01-07",
    area="NORD"
)

# Load data
italy_load = ItalyLoadActualClient(api_key="your-key")
load_data = italy_load.get(
    date_from="2024-01-01",
    date_to="2024-01-07",
    area="NORD"
)

# Generation data by technology
italy_gen = ItalyGenerationClient(api_key="your-key")
generation = italy_gen.get(
    generation_type="WIND",
    date_from="2024-01-01",
    date_to="2024-01-07",
    area="NORD"
)

# Imbalance data
italy_imb = ItalyImbalanceDataClient(api_key="your-key")
imbalance = italy_imb.get(
    date_from="2024-01-01",
    date_to="2024-01-07",
    area="NORD"
)

Spain Clients

from enemera.api import SpainPricesClient, SpainXbidResultsClient

# Spanish electricity prices
spain_prices = SpainPricesClient(api_key="your-key")
prices = spain_prices.get(
    market="MD",
    date_from="2024-01-01",
    date_to="2024-01-07"
)

# Spanish XBID results
spain_xbid = SpainXbidResultsClient(api_key="your-key")
xbid_data = spain_xbid.get(
    date_from="2024-01-01",
    date_to="2024-01-07"
)

Available Data Curves

Curve Description Parameters
ITALY_PRICES Day-ahead and intraday prices market, area
ITALY_XBID_RESULTS Cross-border intraday results area
ITALY_EXCHANGE_VOLUMES Trading volumes by purpose market, area, purpose
ITALY_ANCILLARY_SERVICES Ancillary services market data market, market_segment, area
ITALY_DAM_DEMAND_ACT Actual day-ahead demand area
ITALY_DAM_DEMAND_FCS Forecasted day-ahead demand area
ITALY_LOAD_ACTUAL Actual electricity consumption area
ITALY_LOAD_FORECAST Forecasted consumption area
ITALY_GENERATION Actual generation by technology generation_type, area
ITALY_GENERATION_FORECAST Forecasted generation generation_type, area
ITALY_COMMERCIAL_FLOWS Inter-zonal power flows market, area_from, area_to
ITALY_COMMERCIAL_FLOW_LIMITS Flow capacity limits market, area_from, area_to
ITALY_IMBALANCE_DATA System imbalance data area
SPAIN_PRICES Day-ahead and intraday prices market
SPAIN_XBID_RESULTS Cross-border intraday results -

Enums Reference

Markets

from enemera import Market

# Italian markets
Market.MGP    # Day-Ahead Market (Mercato del Giorno Prima)
Market.MI1    # Intraday Market 1
Market.MI2    # Intraday Market 2
Market.MI3    # Intraday Market 3
Market.MI4    # Intraday Market 4
Market.MI5    # Intraday Market 5
Market.MI6    # Intraday Market 6
Market.MI7    # Intraday Market 7
Market.MSD    # Ancillary Services Market
Market.MB     # Balancing Market
Market.MBa    # Balancing Market - altri servizi
Market.MBs    # Balancing Market - secondary reserve

Areas (Italy)

from enemera import Area

# Primary bidding zones
Area.NORD     # North zone
Area.CNOR     # Center-North zone
Area.CSUD     # Center-South zone
Area.SUD      # South zone
Area.SICI     # Sicily
Area.SARD     # Sardinia
Area.CALA     # Calabria

# Macrozones (for imbalance pricing)
Area.NORTH    # North macrozone (alias for NORD)
Area.SOUTH    # South macrozone

# Virtual zones
Area.BRNN     # Brindisi
Area.FOGN     # Foggia
Area.MONT     # Montalto
Area.PRGP     # Priolo Gargallo
Area.ROSN     # Rossano

# Foreign virtual zones
Area.AUST     # Austria
Area.CORS     # Corsica
Area.COAC     # Corsica AC
Area.COAD     # Corsica DC
Area.FRAN     # France
Area.GREC     # Greece
Area.SLOV     # Slovenia
Area.SVIZ     # Switzerland
Area.MALT     # Malta

Trading Purpose

from enemera import Purpose

Purpose.BUY   # Buy orders/volumes
Purpose.SELL  # Sell orders/volumes

Error Handling

The client provides comprehensive error handling with detailed exception types:

from enemera import (
    EnemeraClient,
    AuthenticationError,
    RateLimitError,
    APIError,
    ValidationError,
    ConnectionError,
    TimeoutError,
    DependencyError
)

client = EnemeraClient(api_key="your-key")

try:
    response = client.get(curve=Curve.ITALY_PRICES, market="MGP", ...)
except AuthenticationError as e:
    print(f"Authentication failed: {e}")
except RateLimitError as e:
    print(f"Rate limit exceeded. Retry after {e.retry_after} seconds")
except ValidationError as e:
    print(f"Invalid parameters: {e}")
except APIError as e:
    print(f"API error {e.status_code}: {e.detail}")
except ConnectionError as e:
    print(f"Connection failed: {e}")
except DependencyError as e:
    print(f"Missing dependency: {e.install_command}")

Configuration

Environment Variables

export ENEMERA_API_KEY="your-jwt-api-key"
export ENEMERA_BASE_URL="https://api.enemera.com"  # Optional, defaults to official API
export ENEMERA_TIMEOUT="30"  # Optional, request timeout in seconds

Logging Configuration

from enemera.utils.logging import configure_logging, get_logger

# Configure global logging level
configure_logging(level="debug")

# Get a custom logger for your application
logger = get_logger("my_energy_app", level="info")
logger.info("Starting energy data analysis")

Advanced Usage

Date Handling

from datetime import datetime, date

# Multiple date formats supported
client.get(
    curve=Curve.ITALY_PRICES,
    market="MGP",
    date_from="2024-01-01",        # ISO string
    date_to=date(2024, 1, 7),      # Date object
    # date_to=datetime(2024, 1, 7), # Datetime object
    area="NORD"
)

Timezone Conversion

# Get data with UTC timestamps (default)
df_utc = response.to_pandas()

# Get data with CET timestamps (common for European energy markets)
df_cet = response.to_pandas_cet()

# Get naive datetime (no timezone info) - useful for Excel export
df_naive = response.to_pandas(naive_datetime=True)

Working with Exchange Volumes

from enemera import Purpose

# Get buy volumes for MGP market
buy_volumes = client.get(
    curve=Curve.ITALY_EXCHANGE_VOLUMES,
    market=Market.MGP,
    purpose=Purpose.BUY,
    date_from="2024-01-01",
    date_to="2024-01-07",
    area=Area.NORD
)

# Get all volumes (both buy and sell)
all_volumes = client.get(
    curve=Curve.ITALY_EXCHANGE_VOLUMES,
    market=Market.MGP,
    date_from="2024-01-01",
    date_to="2024-01-07",
    area=Area.NORD
)

Working with Generation Data

# Get wind generation data
wind_gen = client.get(
    curve=Curve.ITALY_GENERATION,
    generation_type="WIND",
    date_from="2024-01-01",
    date_to="2024-01-07",
    area=Area.NORD
)

# Get solar generation forecast
solar_forecast = client.get(
    curve=Curve.ITALY_GENERATION_FORECAST,
    generation_type="SOLAR",
    date_from="2024-01-01",
    date_to="2024-01-07",
    area=Area.NORD
)

Working with Commercial Flows

# Get flows between specific zones
flows = client.get(
    curve=Curve.ITALY_COMMERCIAL_FLOWS,
    market=Market.MGP,
    area_from=Area.NORD,
    area_to=Area.CNOR,
    date_from="2024-01-01",
    date_to="2024-01-07"
)

# Get flow limits
flow_limits = client.get(
    curve=Curve.ITALY_COMMERCIAL_FLOW_LIMITS,
    market=Market.MGP,
    area_from=Area.NORD,
    area_to=Area.CNOR,
    date_from="2024-01-01",
    date_to="2024-01-07"
)

Response Models

The client returns structured response objects with the following key models:

  • PriceData: Electricity prices with market, zone, and price information
  • IPEXXbidRecapResponse: XBID trading statistics with price ranges and volumes
  • IpexQuantityResponse: Exchange volumes by market, zone, and purpose
  • IPEXAncillaryServicesResponse: Ancillary services market data
  • GenerationData: Generation data by area and technology type
  • LoadData: Load data by area
  • ItalyImbalanceDataResponse: Comprehensive imbalance data with prices and volumes
  • IPEXFlowResponse: Commercial flows between bidding zones
  • SpainPriceResponse: Spanish market prices
  • SpainXbidResultsResponse: Spanish XBID trading results

All models inherit from BaseTimeSeriesResponse and include UTC timestamps.

Requirements

Core Dependencies

  • Python ≥ 3.7
  • requests ≥ 2.25.0
  • pydantic ≥ 2.0.0
  • python-dateutil ≥ 2.8.0

Optional Dependencies

  • pandas ≥ 1.0.0 (for DataFrame support)
  • polars ≥ 0.7.0 (for Polars DataFrame support)
  • openpyxl ≥ 3.0.0 (for Excel export with .xlsx format)
  • xlsxwriter ≥ 3.0.0 (alternative Excel writer with advanced formatting)

API Documentation

For detailed API documentation, available endpoints, and data schemas, visit the Enemera API documentation.

Migration Guide

From v0.1.x to v0.2.0

  1. API Key Format: Ensure you're using JWT tokens instead of simple API keys
  2. Security Features: The client now validates JWT tokens by default
  3. New Clients: Several new specialized clients have been added for different data types
  4. Enhanced Error Handling: More specific exception types are now available

Contributing

Contributions are welcome! Please follow these guidelines:

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

For major changes, please open an issue first to discuss what you would like to change.

Development Setup

git clone https://github.com/fracasamax/enemera-api-client.git
cd enemera-api-client
pip install -e .[dev]

Running Tests

pytest

Code Formatting

black enemera/
isort enemera/
flake8 enemera/

License

This project is licensed under the MIT License - see the LICENSE file for details.

Support

Changelog

v0.2.0 - Enhanced Security & Functionality

  • Enhanced Security: JWT token validation and secure session management
  • New Clients: Added specialized clients for generation, load, flows, and imbalance data
  • Improved Error Handling: Comprehensive exception hierarchy with detailed error information
  • Better Type Safety: Enhanced enum validation and parameter checking
  • Advanced Logging: Structured logging with credential protection
  • Configuration Management: Secure configuration loading from environment and files
  • Timezone Utilities: Enhanced timezone handling for European energy markets
  • Response Models: Detailed response models for all data types
  • Optional Dependencies: Flexible installation with optional features

v0.1.x - Initial Release

  • Basic API client functionality
  • Core data access for Italian and Spanish markets
  • DataFrame export capabilities

Disclaimer: This is an unofficial client library. Enemera and associated trademarks are property of their respective owners.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

enemera-0.2.0.tar.gz (36.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

enemera-0.2.0-py3-none-any.whl (39.0 kB view details)

Uploaded Python 3

File details

Details for the file enemera-0.2.0.tar.gz.

File metadata

  • Download URL: enemera-0.2.0.tar.gz
  • Upload date:
  • Size: 36.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.0

File hashes

Hashes for enemera-0.2.0.tar.gz
Algorithm Hash digest
SHA256 188ecda4e6b8823800f7105e3715c0564533f8912c5455da71b6de80ed1b8f3d
MD5 45175879bf46798c4a502b361fd29e56
BLAKE2b-256 6efd8947879ec5dfa6e7f3375ab774a51f16062be93c8a4e1b3cb090fed29488

See more details on using hashes here.

File details

Details for the file enemera-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: enemera-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 39.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.0

File hashes

Hashes for enemera-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 831555d2fbf03187e4fe12e601bbcea466a073c152e5d880562dbd771ffc9aed
MD5 97814bff11e0ac3eda8d1d7c81d3f9fd
BLAKE2b-256 ebd51a3b5a6ea66e1974927525e978715de1595915064863ec7beee11eb4a892

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page