Serveur REST permettant de télécharger dynamiquement des fichiers GRIB météorologiques avec support multi-jours et paramètres personnalisables. Ce serveur résout les problèmes de CORS et compile automatiquement les prévisions sur plusieurs jours.
- ✅ Retourne de vrais fichiers GRIB2 (pas de JSON)
- ✅ Support multi-jours (jusqu'à 16 jours de prévisions)
- ✅ Pas de problème CORS (headers configurés)
- ✅ API REST simple avec paramètres personnalisables
- ✅ Multiple sources : NOMADS (NOAA) et ECMWF
- ✅ Self-hostable avec Docker
# Installation des dépendances
pip install -r requirements.txt
# Lancement du serveur
python grib_server.pyLe projet utilise un build multi-stage pour optimiser les temps de compilation :
# 1. Builder l'image wgrib2 (UNE SEULE FOIS, prend ~10 minutes)
./build-wgrib2.sh
# 2. Builder et lancer le serveur (rapide après la première fois)
docker-compose up -d# Rebuild rapide (quelques secondes seulement)
docker-compose up --build -dLe serveur wgrib2 est séparé de l'application, donc les modifications du code Python se compilent très rapidement sans recompiler wgrib2.
# Construction de l'image wgrib2 (une fois)
docker build -f Dockerfile.wgrib2 -t docker-registry.betrue.fr/wgrib2:latest .
# Construction de l'application
docker build -t grib-server .
# Lancement
docker run -p 8000:8000 grib-serverLe serveur écoute par défaut sur http://localhost:8000
GET /- Documentation de l'APIGET /models- Liste des modèles disponiblesGET /variables- Liste des variables disponiblesGET /grib- Télécharger des fichiers GRIB
# Télécharger 5 jours de prévisions GFS pour l'Europe
curl -O "http://localhost:8000/grib?model=gfs_0p25&days=5&toplat=60&bottomlat=35&leftlon=-10&rightlon=30&vars=UGRD,VGRD,TMP,PRMSL"| Paramètre | Type | Description | Défaut | Exemple |
|---|---|---|---|---|
model |
string | Modèle météo | gfs_0p25 | gfs_0p25, nam, hrrr |
days |
integer | Nombre de jours (1-16) | 3 | 5 |
toplat |
float | Latitude nord (-90 à 90) | 90 | 50 |
bottomlat |
float | Latitude sud (-90 à 90) | -90 | 40 |
leftlon |
float | Longitude ouest (-180 à 180) | -180 | -10 |
rightlon |
float | Longitude est (-180 à 180) | 180 | 10 |
vars |
string | Variables (virgules) | UGRD,VGRD,TMP | UGRD,VGRD,TMP,PRMSL |
UGRD: Composante U du vent (m/s)VGRD: Composante V du vent (m/s)TMP: Température (K)PRMSL: Pression au niveau de la mer (Pa)RH: Humidité relative (%)APCP: Précipitations accumulées (kg/m²)TCDC: Couverture nuageuse totale (%)GUST: Rafales de vent (m/s)
gfs_0p25: GFS résolution 0.25° (global)gfs_0p50: GFS résolution 0.50° (global)nam: North American Mesoscalerap: Rapid Refreshhrrr: High Resolution Rapid Refresh (3km)icon: ICON (DWD Allemagne)arpege: Arpege (Météo France)
// Télécharger un fichier GRIB depuis le navigateur
async function downloadGRIB() {
const response = await fetch('http://localhost:8000/grib?' + new URLSearchParams({
model: 'gfs_0p25',
days: 10,
toplat: 50,
bottomlat: 40,
leftlon: -5,
rightlon: 10,
vars: 'UGRD,VGRD,TMP'
}));
if (response.ok) {
const blob = await response.blob();
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = 'forecast.grib2';
a.click();
}
}import requests
# Télécharger un fichier GRIB
params = {
'model': 'gfs_0p25',
'days': 7,
'toplat': 55,
'bottomlat': 45,
'leftlon': 0,
'rightlon': 15,
'vars': 'UGRD,VGRD,TMP,PRMSL'
}
response = requests.get('http://localhost:8000/grib', params=params)
if response.status_code == 200:
with open('forecast.grib2', 'wb') as f:
f.write(response.content)
print("Fichier GRIB téléchargé avec succès!")# Télécharger pour une zone spécifique
curl -o "atlantic_5days.grib2" \
"http://localhost:8000/grib?model=gfs_0p25&days=5&toplat=60&bottomlat=30&leftlon=-80&rightlon=-10&vars=UGRD,VGRD,PRMSL,GUST"
# Télécharger global 10 jours
curl -o "global_10days.grib2" \
"http://localhost:8000/grib?model=gfs_0p50&days=10&toplat=90&bottomlat=-90&leftlon=-180&rightlon=180&vars=TMP,RH,PRMSL"Le serveur convertit automatiquement les fichiers ECMWF au format NCEP/NOMADS standard :
- Suppression de la Section 2 (Local Use Section) contenant les métadonnées ECMWF
- Changement du centre d'origine : ECMWF (98) → NCEP (7)
- Modification de la version des tables locales : 34 → 1
- Conservation des codes GRIB2 standards : Les fichiers restent compatibles avec tous les outils
Les variables sont automatiquement reconnues :
10u→UGRD(Composante U du vent)10v→VGRD(Composante V du vent)2t→TMP(Température)msl→PRMSL(Pression)
Cette conversion garantit la compatibilité avec :
- wgrib2
- eccodes (grib_ls, grib_dump)
- Python pygrib
- Toute application GRIB2 standard
Le serveur agit comme un proxy intelligent qui :
- Reçoit la requête avec les paramètres souhaités
- Compile les données depuis plusieurs sources (NOMADS, ECMWF)
- Convertit les fichiers ECMWF au format NCEP standard
- Agrège les prévisions multi-jours en un seul fichier
- Retourne un fichier GRIB2 natif binaire
- Résout les problèmes de CORS pour utilisation web
- NOMADS (NOAA) : Données GFS, NAM, RAP, HRRR
- ECMWF Open Data : Modèles ECMWF haute résolution (optionnel)
- Extensible : Facile d'ajouter d'autres sources
- Timeout de 30 secondes par requête HTTP
- Support de requêtes parallèles
- Cache possible via volume Docker
- Compilation à la volée des données multi-jours
- Les données NOMADS sont disponibles avec un délai de 3-6 heures
- ECMWF nécessite l'installation du package
ecmwf-opendata - La taille des fichiers peut être importante pour de grandes zones/durées
Pour ajouter un nouveau modèle ou source :
- Ajouter le modèle dans l'enum
WeatherModel - Implémenter la fonction de récupération
- Ajouter le mapping des variables si nécessaire
MIT - Utilisation libre
Pour toute question ou problème, créez une issue sur le repository.