11 — Météo via API

Niveau requis : 9 (HTTP, requests, JSON, gestion d'erreurs réseau) / Difficulté : 4/5 / Durée estimée : 3–4 h

Objectif

Un outil météo en ligne de commande : on lui donne un nom de ville, il affiche la météo actuelle et les prévisions des prochains jours, en interrogeant une vraie API publiqueOpen-Meteo, gratuite et sans clé d'inscription.

python weather.py Nice
Meteo a Nice (43.70, 7.27)
Actuellement : 27.4 degC, vent 11 km/h
  sam. 05/07 : 24-29 degC, ensoleille
  dim. 06/07 : 23-28 degC, peu nuageux
  lun. 07/07 : 24-27 degC, averses

Premier programme qui dépend du monde extérieur : le réseau peut être lent, coupé, l'API peut répondre n'importe quoi, la ville peut ne pas exister. La moitié du travail de ce projet, c'est gérer ce qui échoue. C'est ça, la programmation réseau réelle.

Notions utilisées

Cahier des charges

Étapes de construction

  1. Explore l'API sans écrire de programme : dans le REPL, import requests puis appelle l'URL de géocodage avec params={"name": "Nice", "count": 1}. Regarde r.status_code, puis r.json(). Note le chemin vers lat/lon (data["results"][0]["latitude"]). Cette exploration AVANT de coder est la méthode normale face à toute API.
  2. Écris geocode(city) qui retourne (lat, lon, name) — sans gestion d'erreurs pour l'instant — et un main() minimal qui l'appelle avec sys.argv[1] et affiche le résultat. Programme qui tourne.
  3. Même démarche pour les prévisions : explore la réponse de /v1/forecast dans le REPL, puis écris fetch_forecast(lat, lon) et affiche brut la partie current. Tu as une météo qui marche (par beau temps réseau).
  4. Écris l'affichage propre : format_report(), dict WEATHER_CODES pour les descriptions, boucle sur les listes parallèles de daily (dates, min, max, codes — elles vont ensemble par indice : zip() est ton ami).
  5. Blindage 1 — l'utilisateur : ville manquante en argument, ville introuvable (results absent ou vide dans la réponse de géocodage). Messages clairs, sys.exit(1). Teste avec Xyzzyville.
  6. Blindage 2 — le réseau : timeout=10 sur chaque appel, raise_for_status(), et un try/except requests.exceptions.RequestException au niveau de main(). Teste réellement : coupe le Wi-Fi et lance ; mets timeout=0.001 temporairement pour provoquer un vrai Timeout. Un except jamais déclenché sous tes yeux est un except non testé.
  7. Finition : en-tête avec nom de ville et coordonnées, arrondis, alignement des colonnes des prévisions. Déroule le scénario complet sur 3 villes dont une avec espaces et une inexistante.

Extensions possibles

  1. Option --days 7 pour choisir le nombre de jours (paramètre forecast_days de l'API).
  2. Cache local : sauvegarder la dernière réponse par ville dans un JSON avec horodatage, et l'utiliser si elle a moins de 15 minutes (économise l'API, et affiche quelque chose hors ligne — en le signalant honnêtement).
  3. Comparer deux villes côte à côte (python weather.py Nice Paris).
  4. Emoji météo par code (attention à l'encodage du terminal Windows — c'est une extension, pas une exigence).

Erreurs fréquentes sur ce projet

Critères de réussite

Commit conseillé

git add projects/mini-projects/11-meteo-api/
git commit -m "project: add weather CLI using Open-Meteo API"

Puis entrée de journal + git push.