ote-cr-price-fetcher 0.1.1
A Python package to fetch electricity prices from OTE-CR (Czech electricity market operator)
License: MIT
Requires Python: >=3.10
Keywords: czech, electricity, energy, market, ote-cr, prices

# OTE-CR Price Fetcher

A Python package to fetch electricity prices from OTE-CR (Czech electricity market operator). This package provides an async interface to retrieve day-ahead electricity prices with automatic retry logic and proper error handling.

## Installation

### Using UV (Recommended)

[UV](https://github.com/astral-sh/uv) is an extremely fast Python package installer. Install the package with:

```bash
uv add ote-cr-price-fetcher
```

Or add it to an existing project:

```bash
uv pip install ote-cr-price-fetcher
```

### Using pip

```bash
pip install ote-cr-price-fetcher
```

### Installing from Source

If you want to install from source for development:

**Using UV:**
```bash
git clone https://github.com/michaelkrasa/ote-cr-price-fetcher.git
cd ote-cr-price-fetcher
uv sync
```

**Using pip:**
```bash
git clone https://github.com/michaelkrasa/ote-cr-price-fetcher.git
cd ote-cr-price-fetcher
pip install -e .
```

## Requirements

- Python 3.10 or higher
- httpx >= 0.25.0
- backoff >= 2.2.0

## Usage

### Basic Usage

```python
import asyncio
import datetime
from ote_cr_price_fetcher import PriceFetcher, PriceDataNotAvailableError

async def main():
    # Create a fetcher instance
    fetcher = PriceFetcher()
    
    # Fetch prices for today (15-minute intervals, default)
    try:
        prices = await fetcher.fetch_prices_for_date(datetime.date.today())
        print(f"Found {len(prices)} price points (15-minute intervals)")
        # Prices are in 15-minute intervals (96 values per day)
        for i, price in enumerate(prices):
            hour = i // 4  # Convert 15-min index to hour
            minute = (i % 4) * 15
            print(f"{hour:02d}:{minute:02d} - {price:.2f} EUR/kWh")
    except PriceDataNotAvailableError as e:
        print(f"Prices not available: {e}")
    
    # Fetch prices in hourly format
    try:
        hourly_prices = await fetcher.fetch_prices_for_date(datetime.date.today(), hourly=True)
        print(f"Found {len(hourly_prices)} hourly price points")
        for hour, price in enumerate(hourly_prices):
            print(f"{hour:02d}:00 - {price:.2f} EUR/kWh")
    except PriceDataNotAvailableError as e:
        print(f"Prices not available: {e}")

asyncio.run(main())
```

### Configuration

You can customize the fetcher behavior by passing configuration parameters:

```python
fetcher = PriceFetcher(
    price_url="https://custom-url.com/api?date=",  # Custom API URL
    timeout=15.0,                                  # Request timeout in seconds
    connect_timeout=90.0,                          # Connection timeout in seconds
    max_retry_time=180,                            # Max retry time in seconds
)
```

### Error Handling

The package raises `PriceDataNotAvailableError` when price data is not yet available (e.g., for future dates or when prices haven't been published yet):

```python
from ote_cr_price_fetcher import PriceDataNotAvailableError

try:
    prices = await fetcher.fetch_prices_for_date(datetime.date.today() + datetime.timedelta(days=1))
except PriceDataNotAvailableError as e:
    print(f"Prices not yet published: {e}")
    # Prices are typically available around 3 PM
```

## API Reference

### `PriceFetcher`
Initialize the PriceFetcher with optional configuration.

**Parameters:**
- `price_url` (str, optional): Base URL for fetching prices. Defaults to OTE-CR URL.
- `timeout` (float, optional): Request timeout in seconds. Defaults to 10.0.
- `connect_timeout` (float, optional): Connection timeout in seconds. Defaults to 60.0.
- `max_retry_time` (int, optional): Maximum time in seconds for retry attempts. Defaults to 120.

#### `fetch_prices_for_date(date: datetime.date, hourly: bool = False) -> list[float]`

Fetch electricity prices for a specific date.

**Parameters:**
- `date` (datetime.date): The date to fetch prices for.
- `hourly` (bool): If True, return hourly averages (24 values). If False, return 15-minute intervals (96 values). Defaults to False.

**Returns:**
- `list[float]`: A list of electricity prices. 96 values for 15-minute intervals, 24 for hourly averages.

**Raises:**
- `PriceDataNotAvailableError`: If price data is not yet available for the date.
- `httpx.RequestError`: If the HTTP request fails.
- `httpx.HTTPStatusError`: If the HTTP response indicates an error.

### `PriceDataNotAvailableError`

Exception raised when price data is not yet available for the requested date.


## License

MIT License - see LICENSE file for details.

## Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

## Testing

To run all tests:

```bash
uv run python tests/run_tests.py
```

This will run both the PriceFetcher integration tests and the PriceUtils unit tests.

## Support

For issues and questions, please open an issue on [GitHub](https://github.com/michaelkrasa/ote-cr-price-fetcher/issues).