API avec PySide
Créer une interface graphique simple avec PySide pour consommer une API REST.

Si vous n'avez jamais utilisé PySide, consultez d'abord le tuto :
- Découvrir PySide pour apprendre les bases des widgets et des layouts.
Mission :
Créer un programme Python avec une interface graphique (utilisant PySide6)
qui permet à l'utilisateur de choisir un pays et une année,
puis affiche les jours fériés correspondants.
L'interface va inclure des menus déroulants (QComboBox) pour le choix interactif, et un bouton pour charger les données depuis l'API.
Nous utilisons l'API publique : https://date.nager.at/Api/
Endpoints utilisés :
- Liste des pays disponibles :
https://date.nager.at/api/v3/AvailableCountries - Jours fériés pour un pays/année :
https://date.nager.at/api/v3/publicholidays/{année}/{code-pays}
Prérequis :
- Python installé (version 3.6+).
- PySide6 doit être installé. Si ce n'est pas le cas :
pip install PySide6 - Installez la bibliothèque
requestspour effectuer les requêtes HTTP :pip install requests
Étapes
1. Créer un dossier tp-api-rest-python-gui dans le dossier de vos Documents.
2. Ouvrir un Terminal et se placer dans ce dossier.
3. Crée un fichier nommé jours_feries_gui_pyside.py.
4. Ouvrir jours_feries_gui_pyside.py avec Visual Studio Code et écrire le code suivant pour importer les modules nécessaires
import sys
import requests
from PySide6.QtWidgets import (QApplication, QWidget, QVBoxLayout, QLabel,
QComboBox, QPushButton, QTextEdit, QMessageBox)
from PySide6.QtCore import Qt
from datetime import datetime
sys: nécessaire pour gérer les arguments de l'application et le code de sortie.PySide6.QtWidgets: contient tous les éléments graphiques (Fenêtre, Boutons, Layouts...).PySide6.QtCore: contient des constantes de base (commeQt.AlignCenter).requests: pour faire les appels à l'API.datetime: pour récupérer l'année en cours.
5. Récupérer la liste des pays disponibles avec une fonction charger_pays()
def charger_pays():
url = "https://date.nager.at/api/v3/AvailableCountries"
try:
reponse = requests.get(url)
reponse.raise_for_status()
return reponse.json()
except Exception as e:
print(f"Erreur lors du chargement des pays : {e}")
return []
Le rôle de la fonction charger_pays() est de récupérer la liste des pays au format JSON.
- L’endpoint
/AvailableCountriesrenvoie une liste de dictionnaires :[
{"countryCode": "FR", "name": "France"},
{"countryCode": "DE", "name": "Germany"},
...
] raise_for_status(): Lève une exception si le serveur renvoie une erreur (404, 500...).
6. Récupérer la liste des jours fériés avec une fonction charger_jours_feries()
Contrairement à Tkinter où on utilise des StringVar, ici nous accéderons directement aux widgets via les variables globales (ou attributs de classe) pour lire leur valeur.
def charger_jours_feries():
# Récupération des valeurs actuelles des widgets
annee = combo_annee.currentText()
code_pays = combo_pays.currentText()
# Récupération du nom du pays via le dictionnaire
nom_pays = dict_pays.get(code_pays, code_pays)
if not annee or not code_pays:
zone_texte.setText("Veuillez sélectionner une année et un pays.")
return
Si l’utilisateur n’a rien sélectionné → on écrit un message d'avertissement dans la zone de texte.
En Python, la fonction charger_jours_feries()
peut accéder directement à la variable annee_var et pays_var
sans qu’il soit nécessaire de la lui passer en paramètre,
car annee_var et pays_var sont définies dans la même portée globale que la fonction :
- La variable
annee_varest créée dans le même bloc de code que la fonctioncharger_jours_feries(), donc elle est visible et accessible à l’intérieur de cette fonction. - En Python, les fonctions peuvent accéder aux variables définies dans leur environnement extérieur (portée englobante), ce qui évite de devoir passer explicitement ces variables en argument.
- Cela simplifie le code et évite de devoir modifier la signature de la fonction pour transmettre des widgets ou autres objets déjà accessibles.
Ainsi, dans ce cas, charger_jours_feries() utilise directement annee_var.get() et pays_var.get() pour récupérer les valeurs sélectionnées, sans que ces variables aient besoin d’être des paramètres de la fonction.
C’est une pratique courante en programmation Python avec des interfaces graphiques,
où les widgets sont souvent créés dans un même scope et utilisés dans des fonctions de rappel (callbacks) sans passage explicite d’arguments.
url = f"https://date.nager.at/api/v3/publicholidays/{annee}/{code_pays}"
Construction dynamique de l'URL.
try:
reponse = requests.get(url)
reponse.raise_for_status()
jours = reponse.json()
# Affichage dans le QTextEdit
zone_texte.clear() # Vide la zone de texte (équivalent de delete(1.0, END))
zone_texte.append(f"Jours fériés pour {annee} en {nom_pays} :\n")
for jour in jours:
date = jour["date"]
nom = jour["localName"]
nom_officiel = jour["name"]
zone_texte.append(f"{date} → {nom:30} ({nom_officiel})")
except Exception as e:
zone_texte.setText(f"Erreur : {e}")
7. Créer l’interface utilisateur (Application et Fenêtre)
En PySide, tout commence par QApplication. On utilise aussi un QVBoxLayout pour empiler les widgets.
# Création de l'application (obligatoire)
app = QApplication(sys.argv)
# Création de la fenêtre principale
fenetre = QWidget()
fenetre.setWindowTitle("Jours Fériés - API Explorer (PySide)")
fenetre.resize(600, 500)
# Création du layout principal (vertical)
layout = QVBoxLayout()
fenetre.setLayout(layout)
8. Charger les données et créer les menus déroulants (QComboBox)
En PySide, le menu déroulant est QComboBox.
# 1. Récupérer les données
liste_pays = charger_pays()
# Créer un dictionnaire {Code: Nom} pour l'affichage ultérieur
dict_pays = {p["countryCode"]: p["name"] for p in liste_pays}
codes_pays = list(dict_pays.keys())
# 2. Préparer les années
annee_actuelle = datetime.now().year
annees = [str(annee_actuelle + i) for i in range(0, 6)] # Année actuelle + 5 suivantes
# 3. Créer le Widget Année
label_annee = QLabel("Année :")
layout.addWidget(label_annee)
combo_annee = QComboBox()
combo_annee.addItems(annees)
combo_annee.setEditable(False) # Empêche la saisie manuelle
layout.addWidget(combo_annee)
# 4. Créer le Widget Pays
label_pays = QLabel("Pays :")
layout.addWidget(label_pays)
combo_pays = QComboBox()
# On trie les codes pays par ordre alphabétique
combo_pays.addItems(sorted(codes_pays))
combo_pays.setEditable(False)
# Sélectionner la France par défaut si elle existe
if "FR" in codes_pays:
index_fr = sorted(codes_pays).index("FR")
combo_pays.setCurrentIndex(index_fr)
layout.addWidget(combo_pays)
addItems(): Remplit le menu déroulant avec une liste de chaînes de caractères.setCurrentIndex(): Permet de définir une sélection par défaut (ex: France).
9. Ajouter le bouton et la zone de texte (QTextEdit)
# Bouton
bouton_charger = QPushButton("Charger les jours fériés")
# Connexion du signal 'clicked' à notre fonction
bouton_charger.clicked.connect(charger_jours_feries)
layout.addWidget(bouton_charger)
# Zone de texte (QTextEdit possède nativement des barres de défilement)
zone_texte = QTextEdit()
zone_texte.setReadOnly(True) # L'utilisateur ne peut que lire, pas écrire
layout.addWidget(zone_texte)
QPushButton: Le bouton standard.clicked.connect(...): C'est le mécanisme des Signaux et Slots de Qt.QTextEdit: Zone de texte multiligne. Contrairement à Tkinter où il fautScrolledText, ici le défilement est automatique.
10. Afficher la fenêtre et lancer la boucle principale
fenetre.show()
# Lancement de la boucle d'événements
sys.exit(app.exec())
show(): Rend la fenêtre visible.app.exec(): Lance la boucle infinie qui gère les clics et les événements.
Corrigé
Une solution
Vous devez être connecté pour voir le contenu.
Lancer le programme
Pour exécuter le programme, il suffit de saisir dans le Terminal :
python jours_feries_gui_pyside.py
ou
python3 jours_feries_gui_pyside.py
ou
py jours_feries_gui_pyside.py
Si l'erreur ModuleNotFoundError: No module named 'PySide6' s'affiche
Pour résoudre l'erreur,
il suffit d'installer le module PySide6 dans votre environnement Python,
avec la commande :
pip install PySide6
Si l'erreur ModuleNotFoundError: No module named 'requests's'affiche
Pour résoudre l'erreur,
il suffit d'installer le module requests dans votre environnement Python,
avec la commande :
pip install requests