Files
elprisenligenu/README.md
Brian Bjarke Jensen 1676fd10c9
Python Code Quality / python-code-quality (push) Successful in 15s
Test Python Package / test (push) Failing after 16s
initial commit
2025-10-30 00:00:02 +01:00

274 lines
7.1 KiB
Markdown

# 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: [[email protected]](mailto:[email protected])
- 🌐 ElprisenLigeNu.dk: [[email protected]](mailto:[email protected])
## Related Projects
- [ElprisenLigeNu.dk](https://www.elprisenligenu.dk) - The source website
- [API Documentation](https://www.elprisenligenu.dk/elpris-api) - Official API docs