# ElprisenLigeNu Python API Client A Python library for accessing Danish electricity spot prices from the [ElprisenLigeNu.dk](https://www.elprisenligenu.dk) API. [![Python Version](https://img.shields.io/badge/python-3.12%2B-blue.svg)](https://python.org) [![License](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE) ## Overview ElprisenLigeNu provides real-time and historical Danish electricity spot prices for the two Danish price zones: - **DK1** (West of Great Belt - Jutland and Funen) - **DK2** (East of Great Belt - Zealand and Bornholm) This library provides a simple Python interface to fetch hourly electricity prices with automatic timezone handling and type-safe data models. ## Features - πŸ”Œ Simple API for fetching electricity prices - πŸ‡©πŸ‡° Support for both Danish price zones (DK1/DK2) - ⏰ Automatic timezone handling (Europe/Copenhagen) - πŸ“Š Type-safe data models using Pydantic - πŸ’° Prices in both DKK and EUR with exchange rates - πŸ• Hourly granularity with start/end timestamps ## Installation ```bash pip install elprisenligenu ``` Or using uv: ```bash uv add elprisenligenu ``` ## Quick Start ```python from datetime import datetime from elprisenligenu import API # Initialize the API client api = API() # Get today's prices for Copenhagen area (DK2) prices = api.get_daily_prices(zone="DK2") # Get prices for Aarhus area (DK1) prices = api.get_daily_prices(zone="DK1") # Get prices for a specific date from datetime import datetime from zoneinfo import ZoneInfo date = datetime(2024, 10, 29, tzinfo=ZoneInfo("Europe/Copenhagen")) prices = api.get_daily_prices(zone="DK2", date=date) # Work with the price data for hour_data in prices: print(f"Time: {hour_data.time_start} - {hour_data.time_end}") print(f"Price: {hour_data.DKK_per_kWh:.4f} DKK/kWh") print(f"Price: {hour_data.EUR_per_kWh:.4f} EUR/kWh") print(f"Exchange rate: {hour_data.EXR:.4f}") print("---") ``` ## API Reference ### API Class ```python from elprisenligenu import API api = API() ``` #### Methods ##### `get_daily_prices(zone="DK1", date=datetime.now())` Fetch hourly electricity prices for a specific day and zone. **Parameters:** - `zone` (str): Price zone, either "DK1" or "DK2". Default: "DK1" - `date` (datetime): Date to fetch prices for. Must be timezone-aware. Default: current date **Returns:** - `list[HourData]`: List of hourly price data objects **Raises:** - `ValueError`: If zone is not "DK1" or "DK2", or if date is not timezone-aware - `TypeError`: If date is not a datetime object - `requests.HTTPError`: If the API request fails ### HourData Model The `HourData` class represents electricity price data for a single hour: ```python from elprisenligenu.dto import HourData class HourData: DKK_per_kWh: float # Price in Danish Kroner per kWh EUR_per_kWh: float # Price in Euros per kWh EXR: float # Exchange rate EUR to DKK time_start: datetime # Hour start time time_end: datetime # Hour end time ``` ## Examples ### Find the cheapest and most expensive hours ```python from elprisenligenu import API api = API() prices = api.get_daily_prices(zone="DK2") # Find cheapest hour cheapest = min(prices, key=lambda x: x.DKK_per_kWh) print(f"Cheapest: {cheapest.DKK_per_kWh:.4f} DKK/kWh at {cheapest.time_start.hour}:00") # Find most expensive hour expensive = max(prices, key=lambda x: x.DKK_per_kWh) print(f"Most expensive: {expensive.DKK_per_kWh:.4f} DKK/kWh at {expensive.time_start.hour}:00") ``` ### Calculate daily average price ```python from elprisenligenu import API api = API() prices = api.get_daily_prices(zone="DK1") average_price = sum(hour.DKK_per_kWh for hour in prices) / len(prices) print(f"Average price today: {average_price:.4f} DKK/kWh") ``` ### Get price data for multiple days ```python from datetime import datetime, timedelta from zoneinfo import ZoneInfo from elprisenligenu import API api = API() timezone = ZoneInfo("Europe/Copenhagen") # Get prices for the last 7 days for i in range(7): date = datetime.now(timezone) - timedelta(days=i) try: prices = api.get_daily_prices(zone="DK2", date=date) avg_price = sum(hour.DKK_per_kWh for hour in prices) / len(prices) print(f"{date.strftime('%Y-%m-%d')}: {avg_price:.4f} DKK/kWh") except Exception as e: print(f"Failed to get data for {date.strftime('%Y-%m-%d')}: {e}") ``` ## Price Zones Denmark is divided into two electricity price zones: - **DK1 (West)**: Jutland and Funen (west of the Great Belt) - Major cities: Aarhus, Aalborg, Odense, Esbjerg - **DK2 (East)**: Zealand, Lolland, Falster, and Bornholm (east of the Great Belt) - Major cities: Copenhagen, Roskilde, HelsingΓΈr ## Data Source This library uses the free API provided by [ElprisenLigeNu.dk](https://www.elprisenligenu.dk). The electricity prices are: - Spot prices from the Nord Pool electricity market - Provided without VAT or additional fees - Updated daily (tomorrow's prices available from 13:00 the day before) - Historical data available from November 1, 2022 - Originally sourced from [ENTSO-E](https://transparency.entsoe.eu/) in EUR, converted to DKK ## Development ### Requirements - Python 3.12+ - Dependencies: `pydantic>=2.12.3`, `requests>=2.32.5` ### Setup ```bash # Clone the repository git clone https://github.com/yourusername/elprisenligenu.git cd elprisenligenu # Install with development dependencies uv sync --dev # Run tests (unit tests only) uv run pytest tests/unit/ # Run all tests including integration tests (requires internet) uv run pytest # Run tests with coverage uv run pytest --cov=src --cov-report=html # Type checking uv run mypy . # Linting uv run ruff check . # Formatting uv run ruff format . ``` ### Test Structure The test suite is organized into: - **Unit Tests** (`tests/unit/`): Fast tests that mock external dependencies - `test_hour_data.py`: Tests for the HourData model - `test_api.py`: Tests for the API class with mocked HTTP requests - **Integration Tests** (`tests/test_integration.py`): Tests that make real API calls - Marked with `@pytest.mark.integration` - Can be skipped with `pytest -m "not integration"` ### Running Specific Tests ```bash # Run only unit tests uv run pytest tests/unit/ # Run only integration tests (requires internet) uv run pytest -m integration # Run tests matching a pattern uv run pytest -k "test_hour_data" # Run with verbose output uv run pytest -v # Run with coverage report uv run pytest --cov=src --cov-report=term-missing ``` ## License This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details. ## Attribution When using this library in public projects, please consider attributing the data source: > Electricity prices provided by [ElprisenLigeNu.dk](https://www.elprisenligenu.dk) ## Support - πŸ› [Report issues](https://github.com/yourusername/elprisenligenu/issues) - πŸ“§ Contact: [schnitzelen@gmail.com](mailto:schnitzelen@gmail.com) - 🌐 ElprisenLigeNu.dk: [hej@beneficial.no](mailto:hej@beneficial.no) ## Related Projects - [ElprisenLigeNu.dk](https://www.elprisenligenu.dk) - The source website - [API Documentation](https://www.elprisenligenu.dk/elpris-api) - Official API docs