Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions .github/workflows/ci-cd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,10 @@
uses: actions/setup-python@v6
with:
python-version: |
3.9
3.10
3.11
3.12
3.13
3.14
- name: Install extra dependencies
run: |
python -m pip install --upgrade pip
Expand Down Expand Up @@ -56,7 +55,7 @@
- name: Set up Python version
uses: actions/setup-python@v6
with:
python-version: '3.13'
python-version: '3.14'
- name: Build package
run: |
python -m pip install --upgrade build
Expand Down
1 change: 1 addition & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ repos:
rev: v2.9.0
hooks:
- id: pip-audit
language_version: python3.12
args: [.]
- repo: https://github.com/compilerla/conventional-pre-commit
rev: v4.3.0
Expand Down
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,13 @@ All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [0.2.7] - October, 2026
### Features
* Added support for AROME-IFS model. See #73
* Added support for Python 3.14 / remove 3.9, 3.10. See #75
### Bugs
* Changed the subset parameter longitude from "lon" to "long" to fix an error raised when using get_coverage. See #72

## [0.2.6] - February, 2026
### Features
* Added the ability to retrieve observations from a single station at a time.
Expand Down
12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,12 @@ Create an account on [the Météo-France API portal](https://portail-api.meteofr

Meteole allows you to retrieve forecasts for a wide range of weather indicators. Here's how to get started:

| Characteristics | AROME | AROME-PE | ARPEGE | ARPEGE-PE | AROME INSTANTANE | PIAF |
|------------------|----------------------------|----------------------------|-----------------------------|--------------------------------| -------------------------------| -------------------------------|
| Resolution | 1.3 km | 2.8 km | 10 km | 10 km | 1.3 km | 1.3 km |
| Update Frequency | Every 3 hours | Every 6 hours | Every 6 hours | Every 6 hours | Every 1 hour | Every 10 minutes |
| Forecast Range | Every hour, up to 51 hours | Every hour, up to 51 hours | Every hour, up to 114 hours | Every hour up to 48 hours, then every 3 hours up to 114 hours | Every 15 minutes, up to 360 minutes | Every 5 minutes, up to 195 minutes |
| Numbers of scenarios | 1 | 25 | 1 | 35 | 1 | 1 |
| Characteristics | AROME | AROME-IFS | AROME-PE | ARPEGE | ARPEGE-PE | AROME INSTANTANE | PIAF |
|------------------|----------------------------|----------------------------|----------------------------|-----------------------------|--------------------------------| -------------------------------| -------------------------------|
| Resolution | 1.3 km | 2.8 km | 2.8 km | 10 km | 10 km | 1.3 km | 1.3 km |
| Update Frequency | Every 3 hours | Every 6 hours | Every 6 hours | Every 6 hours | Every 6 hours | Every 1 hour | Every 10 minutes |
| Forecast Range | Every hour, up to 51 hours | Every hour, up to 51 hours | Every hour, up to 51 hours | Every hour, up to 114 hours | Every hour up to 48 hours, then every 3 hours up to 114 hours | Every 15 minutes, up to 360 minutes | Every 5 minutes, up to 195 minutes |
| Numbers of scenarios | 1 | 1 | 25 | 1 | 35 | 1 | 1 |

The AromePE and ArpegePE models are ensemble models. Instead of making a single forecast of the most likely weather, a set (or ensemble) of forecasts is produced. This set of forecasts aims to give an indication of the range of possible future states of the atmosphere ([from Wikipedia](https://en.wikipedia.org/wiki/Ensemble_forecasting)). It provides several scenarios of the possible weather parameters instead of one for the standard determinist models.

Expand Down
12 changes: 6 additions & 6 deletions docs/pages/how_to.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,12 +49,12 @@ client.get_vignette()

Meteole allows you to retrieve forecasts for a wide range of weather indicators. Here's how to get started with AROME, AROME-PE, AROME INSTANTANE, ARPEGE or PIAF:

| Characteristics | AROME | AROME-PE | ARPEGE | ARPEGE-PE | AROME INSTANTANE | PIAF |
|------------------|----------------------------|----------------------------|-----------------------------|--------------------------------| -------------------------------| -------------------------------|
| Resolution | 1.3 km | 2.8 km | 10 km | 10 km | 1.3 km | 1.3 km |
| Update Frequency | Every 3 hours | Every 6 hours | Every 6 hours | Every 6 hours | Every 1 hour | Every 10 minutes |
| Forecast Range | Every hour, up to 51 hours | Every hour, up to 51 hours | Every hour, up to 114 hours | Every hour up to 48 hours, then every 3 hours up to 114 hours | Every 15 minutes, up to 360 minutes | Every 5 minutes, up to 195 minutes |
| Numbers of scenarios | 1 | 25 | 1 | 35 | 1 | 1 |
| Characteristics | AROME | AROME-IFS | AROME-PE | ARPEGE | ARPEGE-PE | AROME INSTANTANE | PIAF |
|------------------|----------------------------|----------------------------|----------------------------|-----------------------------|--------------------------------| -------------------------------| -------------------------------|
| Resolution | 1.3 km | 2.8 km | 2.8 km | 10 km | 10 km | 1.3 km | 1.3 km |
| Update Frequency | Every 3 hours | Every 6 hours | Every 6 hours | Every 6 hours | Every 6 hours | Every 1 hour | Every 10 minutes |
| Forecast Range | Every hour, up to 51 hours | Every hour, up to 51 hours | Every hour, up to 51 hours | Every hour, up to 114 hours | Every hour up to 48 hours, then every 3 hours up to 114 hours | Every 15 minutes, up to 360 minutes | Every 5 minutes, up to 195 minutes |
| Numbers of scenarios | 1 | 1 | 25 | 1 | 35 | 1 | 1 |

The AromePE and ArpegePE models are ensemble models. Instead of making a single forecast of the most likely weather, a set (or ensemble) of forecasts is produced. This set of forecasts aims to give an indication of the range of possible future states of the atmosphere ([from Wikipedia](https://en.wikipedia.org/wiki/Ensemble_forecasting)). It provides several scenarios of the possible weather parameters instead of one for the standard determinist models.

Expand Down
7 changes: 4 additions & 3 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"

[project]
name = "meteole"
version = "0.2.6"
version = "0.2.7"
requires-python = ">3.8.0"
description = "A Python client library for forecast model APIs (e.g., Météo-France)."
readme = "README.md"
Expand All @@ -23,11 +23,10 @@ classifiers = [
"Programming Language :: Python",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3 :: Only",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"Programming Language :: Python :: 3.14",
"License :: OSI Approved :: Apache Software License",
]

Expand All @@ -39,6 +38,8 @@ dependencies = [
"xarray>=2024.5.0",
"xmltodict>=0.13.0",
"matplotlib>=3.8.4",
"urllib3>=2.8.0",
"pillow>=12.3.0",
]

[project.urls]
Expand Down
4 changes: 4 additions & 0 deletions src/meteole/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,23 @@

from meteole._arome import AromeForecast
from meteole._arome_ensemble import AromePEForecast
from meteole._arome_ifs import AromeIFSForecast
from meteole._arome_instantane import AromePIForecast
from meteole._arpege import ArpegeForecast
from meteole._arpege_ensemble import ArpegePEForecast
from meteole._dpclim import DPClim
from meteole._piaf import PiafForecast
from meteole._vigilance import Vigilance

__all__ = [
"AromeForecast",
"AromeIFSForecast",
"AromePIForecast",
"ArpegeForecast",
"PiafForecast",
"Vigilance",
"AromePEForecast",
"ArpegePEForecast",
"DPClim",
]

Expand Down
53 changes: 53 additions & 0 deletions src/meteole/_arome_ifs.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
from __future__ import annotations

import logging
from typing import final

from meteole.clients import BaseClient, MeteoFranceClient
from meteole.forecast import WeatherForecast

logger = logging.getLogger(__name__)

AVAILABLE_AROME_IFS_TERRITORY: list[str] = [
"FRANCE",
"NCALED",
"INDIEN",
"POLYN",
"GUYANE",
"ANTIL",
]


@final
class AromeIFSForecast(WeatherForecast):
"""Access the AROME numerical weather forecast data from Meteo-France API.

Doc:
- https://portail-api.meteofrance.fr/web/fr/api/arome

Attributes:
territory: Covered area (e.g., FRANCE, ANTIL, ...).
precision: Precision value of the forecast.
capabilities: DataFrame containing details on all available coverage ids.
"""

# Model constants
MODEL_NAME: str = "arome"
BASE_ENTRY_POINT: str = "wcs/MF-NWP-HIGHRES-AROMEIFS"
MODEL_TYPE: str = "DETER"
ENSEMBLE_NUMBERS: int = 1
DEFAULT_TERRITORY: str = "FRANCE"
DEFAULT_PRECISION: float = 0.025
CLIENT_CLASS: type[BaseClient] = MeteoFranceClient

def _validate_parameters(self) -> None:
"""Check the territory and the precision parameters.

Raise:
ValueError: At least, one parameter is not good.
"""
if self.precision not in [0.025]:
raise ValueError("Parameter `precision` must be in (0.025). It is inferred from argument `territory`")

if self.territory not in AVAILABLE_AROME_IFS_TERRITORY:
raise ValueError(f"Parameter `territory` must be in {AVAILABLE_AROME_IFS_TERRITORY}")
10 changes: 5 additions & 5 deletions src/meteole/forecast.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,8 @@ def __init__(
self,
client: BaseClient | None = None,
*,
territory: str = DEFAULT_TERRITORY,
precision: float = DEFAULT_PRECISION,
territory: str | None = None,
precision: float | None = None,
**kwargs: Any,
):
"""Initialize attributes.
Expand All @@ -75,8 +75,8 @@ def __init__(
application_id: The Application ID for authentication. Defaults to None.
"""

self.territory = territory # "FRANCE", "ANTIL", or others (see API doc)
self.precision = precision
self.territory = territory or type(self).DEFAULT_TERRITORY # "FRANCE", "ANTIL", or others (see API doc)
self.precision = precision or type(self).DEFAULT_PRECISION
self._validate_parameters()

self._capabilities: pd.DataFrame | None = None
Expand Down Expand Up @@ -806,7 +806,7 @@ def _get_coverage_file(
*([f"height({height})"] if height is not None else []),
f"time({forecast_horizon_in_seconds})",
f"lat({lat[0]},{lat[1]})",
f"lon({lon[0]},{lon[1]})",
f"long({lon[0]},{lon[1]})",
]

params = {
Expand Down
5 changes: 3 additions & 2 deletions tox.ini
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
[tox]
min_version = 4.0
env_list =
py314
py313
py312
py311
py310
py39
[testenv]
description = run unit tests
deps =
Expand Down
Loading