Pour commencer, qu’est-ce que l’API Rest de WordPress et à quoi elle sert ?
L’API REST de WordPress, c’est la baguette magique pour les devs qui veulent piloter leur site sans se frotter à l’interface habituelle. Avec cette API, t’as le pouvoir de faire à peu près tout ce que tu veux, et ce, de façon programmée.
En clair ? Tu peux concocter des articles, les retoucher, les balancer à la corbeille, orchestrer les commentaires, gérer la troupe des utilisateurs, et même tweaker les paramètres de ton site, le tout en maniant les classiques requêtes HTTP.
Imagine que tu veuilles automatiser la publication d’articles, synchroniser du contenu entre plusieurs sites, ou même créer une appli qui se base sur ton site WordPress. L’API REST rend tout ça possible, et ce, de manière super fluide et flexible. Tu envoies des requêtes à des URL spécifiques de ton site, et hop, tu reçois des réponses en JSON, un format facile à manier, même dans tes scripts.
C’est un outil puissant qui ouvre des portes à une personnalisation et une automatisation de malade, transformant ton site WordPress en véritable plateforme dynamique. Tu commences à voir le potentiel ?
Le code Python pour t’authentifier et poster ton article
On va faire simple et efficace, et on commence tout de suite !
import requests from requests.auth import HTTPBasicAuth
D’abord, on importe le module requests
. C’est lui qui va nous permettre de faire des requêtes HTTP super facilement. HTTPBasicAuth
est un helper de requests
pour gérer l’authentification avec un nom d’utilisateur et un mot de passe, juste ce qu’il nous faut pour parler à WordPress.
# Remplacez par l'URL de votre site WordPress, votre nom d'utilisateur et votre mot de passe url = 'https://ton.fr/wp-json/wp/v2/posts' username = 'ton identifiant' password = 'ton mot de passe'
Ici, on prépare le terrain. url
c’est l’adresse où on va envoyer notre requête pour créer un post. Ça pointe directement sur l’API REST de WordPress. Change username
et password
par tes propres infos pour que ça marche avec ton site.
# Post data post_data = { 'title': 'Titre article', 'content': 'Ton contenu.', 'status': 'publish' }
post_data
, c’est le contenu de ton article. Tu mets le titre dans title
, le corps de l’article dans content
, et status
à ‘publish’ pour le publier directement. Si tu veux juste le mettre en brouillon, tu mettrais ‘draft’.
# Make a POST request to create a new post response = requests.post( url, auth=HTTPBasicAuth(username, password), json=post_data )
C’est là que la magie opère. On envoie une requête POST à WordPress avec nos données. L’authentification est gérée par HTTPBasicAuth
qui prend nos identifiants.
# Check the response if response.status_code == 201: print("Post successfully published!") print("Post URL:", response.json()['link']) else: print("Failed to publish the post. Status code:", response.status_code) print("Error message:", response.text)
Enfin, on vérifie la réponse de l’API. Si le code de statut HTTP est 201, c’est que tout s’est bien passé et l’article est publié. On peut même récupérer l’URL du post publié. Si ça foire, on affiche le code d’erreur et le message pour comprendre le souci.
Le code complet :
import requests from requests.auth import HTTPBasicAuth # Remplacez par l'URL de votre site WordPress, votre nom d'utilisateur et votre mot de passe url = 'https://tonsite.fr/wp-json/wp/v2/posts' username = 'ton identifiant' password = 'ton mot de passe' # Post data post_data = { 'title': 'Titre article', 'content': 'Ton contenu.', 'status': 'publish' } # Make a POST request to create a new post response = requests.post( url, auth=HTTPBasicAuth(username, password), json=post_data ) # Check the response if response.status_code == 201: print("Post successfully published!") print("Post URL:", response.json()['link']) else: print("Failed to publish the post. Status code:", response.status_code) print("Error message:", response.text)
Erreur « Failed to publish the post. Status code: 401 »
Failed to publish the post. Status code: 401 Error message: {"code":"rest_cannot_create","message":"D\u00e9sol\u00e9, vous n\u2019avez pas l\u2019autorisation de cr\u00e9er des contenus sous cet identifiant.","data":{"status":401}}
Ce fameux code d’erreur 401, un classique ! Ça veut dire « Non autorisé ». Ton script Python essaie de publier un article, mais WordPress lui dit : « Eh, minute papillon, qui t’es pour faire ça ? ».
La fonction PHP pour corriger l’erreur 401
Tu vas devoir intégrer cette fonction dans le functions.php de ton thème enfant ou te créer un plugin avec cette fonction. Car n’oublies pas que si tu ajoutes ça dans le thème de base, ton code disparaitra lors de la prochaine mise à jour.
add_filter('determine_current_user', function ($user) { if (!empty($_SERVER['PHP_AUTH_USER']) && !empty($_SERVER['PHP_AUTH_PW'])) { $username = $_SERVER['PHP_AUTH_USER']; $password = $_SERVER['PHP_AUTH_PW']; $user = wp_authenticate($username, $password); if (is_wp_error($user)) { return null; } wp_set_current_user($user->ID); return $user->ID; } return $user; });
Explication de la fonction
Activation du filtre avec add_filter
: C’est la clé de voûte qui te permet de jongler avec les données avant que WordPress ne mette son nez dedans. On utilise ici determine_current_user
pour trouver l’identifiant de l’utilisateur actif.
Contrôle des identifiants : On vérifie que les variables $_SERVER['PHP_AUTH_USER']
et $_SERVER['PHP_AUTH_PW']
ne sont pas vides. Elles contiennent les infos indispensables d’authentification HTTP Basic envoyées par ton script Python.
Authentification à la rescousse : On lance wp_authenticate
pour valider le couple nom d’utilisateur/mot de passe. Si ça matche, c’est tout bon.
Quand ça coince, gestion des erreurs : Si wp_authenticate
te renvoie une erreur, vérifie avec is_wp_error($user)
, on met tout en pause et on renvoie null
.
Définir qui tient les rênes : Si tout est ok, on active wp_set_current_user
pour confirmer officiellement l’identité de l’utilisateur avec son ID. Cet ID, on le renvoie pour que WordPress sache qui dirige la danse.
Pourquoi ajouter ce code dans functions.php
?
Le fichier functions.php
dans ton thème WordPress, c’est le centre de commandement pour tes customisations. En y glissant des morceaux de code comme celui-là, tu fais évoluer le comportement de ton site pour le rendre plus flexible ou plus blindé, selon ce que tu cherches à faire.
Le hic, c’est que de base, WordPress n’est pas fan de l’authentification HTTP Basic pour son API REST quand les appels viennent de l’extérieur. Donc même si tu envoies les bons identifiants via ta requête, WordPress fait la sourde oreille et bloque l’entrée. Le snippet de code que tu rajoutes va régler ce souci en forçant WordPress à reconnaître et à accepter les identifiants envoyés par ton script Python.
Aller plus loin en ajoutant une image à la une avec un media intégré dans le contenu
import requests from requests.auth import HTTPBasicAuth # Remplacez par l'URL de votre site WordPress, votre nom d'utilisateur et votre mot de passe url = 'https://tonsite.fr/wp-json/wp/v2/posts' media_url = 'https://tonsite.fr/wp-json/wp/v2/media' # URL pour l'upload de médias username = 'ton identifiant' password = 'ton mot de passe' # Préparation de l'image à uploader media_data = { 'file': open('image.webp', 'rb'), # Assurez-vous que le chemin vers votre image est correct 'caption': 'Optional caption here' } # Upload de l'image media_response = requests.post( media_url, auth=HTTPBasicAuth(username, password), files=media_data ) # Vérification de la réponse de l'upload d'image if media_response.status_code == 201: media_id = media_response.json()['id'] print("Image successfully uploaded!") print("Media ID:", media_id) # Données de l'article avec image intégrée post_data = { 'title': 'Titre article', 'content': 'Ton contenu. <img src="{}" alt="Description">'.format(media_response.json()['source_url']), 'status': 'publish', 'featured_media': media_id # Définir l'image uploadée comme image à la une } # Création de l'article response = requests.post( url, auth=HTTPBasicAuth(username, password), json=post_data ) # Vérification de la réponse de création d'article if response.status_code == 201: print("Post successfully published!") print("Post URL:", response.json()['link']) else: print("Failed to publish the post. Status code:", response.status_code) print("Error message:", response.text) else: print("Failed to upload image. Status code:", media_response.status_code) print("Error message:", media_response.text
Explications du processus :
- Préparation de l’image à uploader : Avant tout, tu prépares ton image. Tu ouvres le fichier en mode lecture binaire (
'rb'
), ce qui est crucial pour que l’image soit lue correctement lors de l’envoi. - Upload de l’image : Ensuite, on envoie l’image au serveur WordPress. Note bien qu’on utilise l’URL dédiée aux médias (
media_url
). On passe aussi l’authentification HTTP Basic pour s’assurer que l’opération se fait en toute sécurité. - Vérification de la réponse de l’upload d’image : On checke si l’image a bien été uploadée. Si
media_response.status_code
est 201, c’est que tout est bon. L’ID de l’image uploadée (media_id
) est récupéré pour être utilisé par la suite. - Intégration de l’image dans l’article : L’image est maintenant sur le serveur, alors on peut l’intégrer dans l’article. On utilise
format()
pour insérer l’URL de l’image directement dans le HTML du contenu de l’article. De plus, on associe cette image comme « image à la une » du post en passant son ID dansfeatured_media
.
Pour ajouter la meta description
# post_data['meta'] = {'_aioseop_description': 'Ta meta.'} # Pour All in One SEO Pack # post_data['yoast_meta'] = {'yoast_wpseo_metadesc': 'Ta meta.'} # Pour Yoast SEO # post_data['meta'] = {'rank_math_description': 'Ta meta.'} # Pour Rank Math SEO
Intégration dans le code
# Données de l'article avec image intégrée post_data = { 'title': 'Ton titre', 'content': 'Ton contenu. <img src="{}" alt="Description">'.format(media_response.json()['source_url']), 'status': 'publish', 'featured_media': media_id, # Définir l'image uploadée comme image à la une 'meta': { '_aioseop_description': 'Ta meta.' } }