WordPress se ha convertido en el sistema de gestión de contenidos (CMS) más utilizado debido en gran medida a su interfaz de programación de aplicaciones (API). La API REST de WordPress permite a WordPress «hablar» con otras aplicaciones escritas en varios lenguajes, incluido Python.

Python es un lenguaje de programación extensible con diversos usos y una sintaxis legible para el ser humano, lo que lo convierte en una poderosa herramienta para gestionar a distancia el contenido de WordPress.

Aquí tienes algunos casos de uso de la API REST de WordPress para tus aplicaciones y cómo puedes utilizar Python para darles soporte:

  • Utiliza plantillas predefinidas para que tu aplicación convierta rápidamente los datos brutos en publicaciones con formato y explicaciones.
  • Construye una aplicación de back-office en Django y Python que muestre ofertas por tiempo limitado a tus clientes cada vez que se produzca un descuento o evento de venta específico.
  • Integra scripts de Python para que se ejecuten dentro de tu sitio de WordPress

Este tutorial te ayudará a crear una sencilla aplicación de consola en Python que se comunica con la API REST de WordPress y ejecuta operaciones en ella. También está disponible el código completo del proyecto.

Instalación y configuración de WordPress

En primer lugar, vamos a instalar y ejecutar un sitio web de WordPress localmente en tu máquina de desarrollo. Esta es una forma excelente de empezar con WordPress, ya que no tienes que crear una cuenta ni comprar un nombre de dominio para el alojamiento web.

Antes de instalar WordPress localmente, es necesario que algunos componentes se ejecuten en tu ordenador, como el servidor web Apache, una base de datos local y el lenguaje PHP en el que está escrito WordPress.

Afortunadamente, podemos utilizar DevKinsta, una suite de desarrollo local de WordPress gratuita disponible para los principales sistemas operativos (no tienes que ser cliente de Kinsta para utilizarla).

DevKinsta está disponible para Windows, Mac y Linux, e instala WordPress y todas sus dependencias en tu máquina local.

Antes de instalar DevKinsta, debes tener Docker funcionando localmente, así que descarga e instala el Docker Engine si aún no lo has hecho.

Después de instalar Docker Desktop, puedes descargar automáticamente el paquete que se adapte a tu sistema operativo.

Página de instalación de DevKinsta.
Página de instalación de DevKinsta.

Cuando ejecutas el instalador de DevKinsta, Docker comienza a inicializarse inmediatamente:

DevKinsta inicia Docker localmente.
DevKinsta inicia Docker localmente.

A continuación, elige Nuevo sitio WordPress en el menú Crear nuevo sitio:

Menú Crear nuevo sitio de DevKinsta.
Menú Crear nuevo sitio de DevKinsta.

Ahora el instalador de DevKinsta te pide que crees las credenciales de la cuenta de administrador de WordPress:

DevKinsta mostrando el formulario de Nuevo Sitio WordPress..
DevKinsta mostrando el formulario de Nuevo Sitio WordPress.

Una vez instalado, DevKinsta es una aplicación independiente. Ahora puedes acceder tanto al sitio de WordPress (mediante el botón Abrir sitio) como al panel de administración de WordPress (botón WP Admin).

Panel de Control del sitio de DevKinsta.
Panel de Control del sitio de DevKinsta.

A continuación, tienes que activar el SSL y el HTTPS para tu sitio web. Esto mejora la seguridad de tu sitio web a través de un certificado SSL.

Opción "SSL y HTTPS" de DevKinsta.
Opción «SSL y HTTPS» de DevKinsta.

Ahora ve a la aplicación de DevKinsta y haz clic en el botón Abrir sitio. Una nueva pestaña del navegador mostrará la página de inicio de tu sitio de WordPress:

Página de inicio de WordPress.
Página de inicio de WordPress.

Este es tu blog de WordPress, donde puedes empezar a escribir. Pero para que Python pueda acceder y utilizar la API REST de WordPress, primero debemos configurar el Admin de WordPress.

Ahora haz clic en el botón WP Admin en la aplicación DevKinsta, y luego proporciona tu usuario y contraseña para acceder al panel de control de WordPress:

Formulario de acceso a WordPress.
Formulario de acceso a WordPress.

Una vez que hayas iniciado la sesión, verás el Panel de control de WordPress:

Página del panel de control de WordPress.
Página del panel de control de WordPress.

WordPress utiliza la autenticación por cookies como método estándar. Pero si quieres controlarlo mediante la API REST, debes autenticarte con una técnica que te permita acceder a la API REST de WordPress.

Para ello, utilizarás contraseñas de aplicación. Se trata de cadenas de 24 caracteres de longitud que WordPress genera y asocia a un perfil de usuario que tiene permiso para gestionar su sitio web.

Para utilizar las Contraseñas de Aplicación, haz clic en el menú Plugin del Panel de Control, y luego busca el plugin con el mismo nombre. A continuación, instala y activa el plugin de Application Passwords:

Plugin Application Passwords para WordPress.
Plugin Application Passwords para WordPress.

Para comenzar a crear tu contraseña de aplicación, empieza por expandir el menú Usuarios y hacer clic en Todos los usuarios:

Menú Usuarios expandido.
Menú Usuarios expandido.

Ahora, haz clic en Editar debajo de tu nombre de usuario administrador:

Interfaz WP-Admin de WordPress.
Interfaz WP-Admin de WordPress.

Desplázate hacia abajo en la página Editar usuario y encuentra la sección Contraseñas de aplicación. Aquí, proporciona un nombre para la Contraseña de la Aplicación, que utilizarás más tarde para autenticar las peticiones de tu aplicación Python y consumir la API REST:

Página de Application Passwords
Página de Application Passwords

Haz clic en Añadir nueva contraseña de aplicación para que WordPress pueda generar una contraseña aleatoria de 24 caracteres para ti:

Página de la nueva contraseña de la aplicación.
Página de la nueva contraseña de la aplicación.

A continuación, copia esta contraseña y guárdala en un lugar seguro para utilizarla más tarde. Recuerda que no podrás recuperar esta contraseña una vez que cierres esta página.

Por último, debes configurar los enlaces permanentes. WordPress te permite crear una estructura de URL personalizada para tus enlaces permanentes y archivos. Vamos a cambiarlo para que se pueda acceder a una entrada de WordPress titulada, por ejemplo, «Tu primer sitio web de WordPress» a través de la intuitiva URL https://your-website.local:port/your-first-wordpress-website/. Este enfoque aporta varias ventajas, como la mejora de la usabilidad y la estética.

Para configurar los enlaces permanentes, despliega la sección Ajustes y haz clic en el menú Enlaces permanentes. Aquí, cambia la Ajustes comunes por el Nombre de la entrada:

Changing WordPress permalink settings.

Configurar la estructura de enlaces permanentes utilizando la estructura de Nombre de la entrada también es necesario porque nos permitirá recuperar las publicaciones más adelante en nuestro código Python utilizando el formato JSON. De lo contrario, se producirá un error de decodificación JSON.

Cómo controlar WordPress desde Python

WordPress está escrito en PHP, pero tiene una API REST que permite a otros lenguajes de programación, sitios y aplicaciones consumir su contenido. La exposición del contenido de WordPress en la arquitectura REST hace que esté disponible en formato JSON. Por tanto, otros servicios pueden integrarse con WordPress y realizar operaciones de Crear, Leer, Actualizar y Borrar (CRUD) sin necesidad de una instalación local de WordPress.

A continuación, construirás una sencilla aplicación en Python para ver cómo puedes utilizar la API REST de WordPress para crear, recuperar, actualizar y eliminar entradas.

Crea un nuevo directorio para tu nuevo y sencillo proyecto de Python y llámalo algo así como PythonWordPress:

../PythonWordPress

Ahora, crearás un entorno virtual para tu proyecto, lo que te permitirá mantener un conjunto independiente de paquetes Python instalados, aislándolos de los directorios de tu sistema y evitando conflictos de versiones. Crea un entorno virtual ejecutando el comando venv:

python3 -m venv .venv

Ahora, ejecuta un comando para activar el entorno virtual .venv. Este comando varía según el sistema operativo:

  • Windows .venvScriptsactivate
  • Mac/Linux .venv/bin/activate

A continuación, guarda la configuración relacionada con tu cuenta de WordPress. Para separar la configuración de la aplicación de tu código Python, crea un archivo .env en el directorio de tu proyecto, y añade estas variables de entorno al archivo:

WEBSITE_URL="<>"

API_USERNAME="<>"

API_PASSWORD="<>"

Afortunadamente, leer los datos anteriores de una aplicación Python es fácil. Puedes instalar el paquete Python-dotenv para que tu aplicación pueda leer la configuración desde el archivo .env:

pip install python-dotenv

A continuación, instala aiohttp, un cliente/servidor HTTP asíncrono para Python:

pip install aiohttp

Ahora añade un archivo llamado app.py con el siguiente código:

import asyncio

menu_options = {

1: 'List Posts',

2: 'Retrieve a Post'

}

def print_menu():

for key in menu_options.keys():

print (key, '--', menu_options[key] )

async def main():

while(True):

print_menu()

option = input_number('Enter your choice: ')

#Check what choice was entered and act accordingly

if option == 1:

print('Listing posts...')

elif option == 2:

print('Retrieving a post...')

else:

print('Invalid option. Please enter a number between 1 and 5.')

def input_number(prompt):

while True:

try:

value = int(input(prompt))

except ValueError:

print('Wrong input. Please enter a number ...')

continue

if value < 0:

print("Sorry, your response must not be negative.")

else:

break

return value

def input_text(prompt):

while True:

text = input(prompt)

if len(text) == 0:

print("Text is required.")

continue

else:

break

return text

if __name__=='__main__':

asyncio.run(main())

El código anterior muestra un menú de consola y te pide que introduzcas un número para elegir una opción. A continuación, ampliarás este proyecto e implementarás el código que te permite listar todas las entradas y recuperar una entrada específica utilizando su id de entrada.

Obtener entradas en código

Para interactuar con la API REST de WordPress, debes crear un nuevo archivo Python. Crea un archivo llamado wordpress_api_helper.py con el siguiente contenido:

import aiohttp

import base64

import os

import json

from dotenv import load_dotenv

load_dotenv()

user=os.getenv("API_USERNAME")

password=os.getenv("API_PASSWORD")

async def get_all_posts():

async with aiohttp.ClientSession(os.getenv("WEBSITE_URL")) as session:

async with session.get("/wp-json/wp/v2/posts") as response:

print("Status:", response.status)

text = await response.text()

wp_posts = json.loads(text)

sorted_wp_posts = sorted(wp_posts, key=lambda p: p['id'])

print("=====================================")

for wp_post in sorted_wp_posts:

print("id:", wp_post['id'])

print("title:", wp_post['title']['rendered'])

print("=====================================")

async def get_post(id):

async with aiohttp.ClientSession(os.getenv("WEBSITE_URL")) as session:

async with session.get(f"/wp-json/wp/v2/posts/{id}") as response:

print("Status:", response.status)

text = await response.text()

wp_post = json.loads(text)

print("=====================================")

print("Post")

print("     id:", wp_post['id'])

print("     title:", wp_post['title']['rendered'])

print("     content:", wp_post['content']['rendered'])

print("=====================================")

Fíjate en el uso de la biblioteca aiohttp de arriba. Los lenguajes modernos proporcionan sintaxis y herramientas que permiten la programación asíncrona. Esto aumenta la capacidad de respuesta de la aplicación al permitir que el programa realice tareas junto con operaciones como peticiones web, operaciones de base de datos y E/S de disco. Python ofrece asyncio como base para su marco de programación asíncrona, y la biblioteca aiohttp está construida sobre asyncio para aportar acceso asíncrono a las operaciones Cliente/Servidor HTTP realizadas en Python.

La función ClientSession anterior se ejecuta de forma asíncrona y devuelve un objeto session, que nuestro programa utiliza para realizar una operación HTTP GET contra el punto final /wp-json/wp/v2/posts. La única diferencia entre una solicitud para recuperar todos los puestos y una solicitud para uno en concreto es que esta última solicitud pasa un parámetro post id en la ruta URL: /wp-json/wp/v2/posts/{id}.

Ahora, abre el archivo app.py y añade la sentencia import:

from wordpress_api_helper import get_all_posts, get_post

A continuación, modifica la función main para llamar a las funciones get_all_posts y get_post:

if option == 1:

print('Listing posts...')

await get_all_posts()

elif option == 2:

print('Retrieving a post...')

id = input_number('Enter the post id: ')

await get_post(id)

A continuación, ejecuta la aplicación:

python app.py

Entonces verás el menú de la aplicación:

Menú de la aplicación Python.
Menú de la aplicación Python.

Ahora prueba la opción 1 para ver la lista de entradas que recupera tu aplicación Python, y la opción 2 para seleccionar una entrada:

La aplicación Python muestra la lista de posts y un único post seleccionado por el usuario.
La aplicación Python muestra la lista de posts y un único post seleccionado por el usuario.

Crear entradas en código

Para crear una entrada de WordPress en Python, empieza por abrir el archivo wordpress_api_helper.py y añade la función create_post:

async def create_post(title, content):

async with aiohttp.ClientSession(os.getenv("WEBSITE_URL")) as session:

async with session.post(

f"/wp-json/wp/v2/posts?content={content}&title={title}&status=publish"

, auth=aiohttp.BasicAuth(user, password)) as response:

print("Status:", response.status)

text = await response.text()

wp_post = json.loads(text)

post_id = wp_post['id']

print(f'New post created with id: {post_id}')

Este código llama a la función post en el objeto session, pasando el parámetro auth junto a la URL del punto final de la API REST. El objeto auth contiene ahora el usuario de WordPress y la contraseña que creaste con las contraseñas de la aplicación. Ahora, abre el archivo app.py y añade código para importar create_post y el menú:

from wordpress_api_helper import get_all_posts, get_post, create_post

menu_options = {

1: 'List Posts',

2: 'Retrieve a Post',

3: 'Create a Post'

}

A continuación, añade una tercera opción de menú:

elif option == 3:

print('Creating a post...')

title = input_text('Enter the post title: ')

content = input_text('Enter the post content: ')

await create_post(title, f"{content}")

A continuación, ejecuta la aplicación y prueba la opción 3, pasando un título y un contenido para crear una nueva entrada en WordPress:

Aplicación Python mostrando el post de WordPress recién creado.
Aplicación Python mostrando el post de WordPress recién creado.

Si vuelves a elegir la opción 1, te devolverá el id y el título de la entrada recién añadida:

La aplicación Python devuelve el título y el id del nuevo post.
La aplicación Python devuelve el título y el id del nuevo post.

También puedes abrir tu sitio web de WordPress para ver la nueva entrada:

Imagen del navegador del nuevo post de WordPress.
Imagen del navegador del nuevo post de WordPress.

Actualizar entradas en código

Abre el archivo wordpress_api_helper.py y añade la función update_post:

async def update_post(id, title, content):

async with aiohttp.ClientSession(os.getenv("WEBSITE_URL")) as session:

async with session.post(

f"/wp-json/wp/v2/posts/{id}?content={content}&title={title}&status=publish"

, auth=aiohttp.BasicAuth(user, password)) as response:

print("Status:", response.status)

text = await response.text()

wp_post = json.loads(text)

post_id = wp_post['id']

print(f'New post created with id: {post_id}')

A continuación, abre el archivo app.py y añade el código para importar update_post y el menú:

from wordpress_api_helper import get_all_posts, get_post, create_post, update_post

menu_options = {

1: 'List Posts',

2: 'Retrieve a Post',

3: 'Create a Post',

4: 'Update a Post'

}

A continuación, añade una cuarta opción de menú:

elif option == 4:

print('Updating a post...')

id = input_number('Enter the post id: ')

title = input_text('Enter the post title: ')

content = input_text('Enter the post content: ')

await update_post(id, title, f"{content}")

A continuación, ejecuta la aplicación y prueba la opción 4, pasando un id de entrada, un título y un contenido para actualizar una entrada existente.

Aplicación Python mostrando el menú actualizado.
Aplicación Python mostrando el menú actualizado.

Si eliges la opción 2 y pasas el id de la entrada actualizada, te devolverá los detalles de la nueva entrada añadida:

Aplicación Python mostrando la entrada actualizada.
Aplicación Python mostrando la entrada actualizada.

Borrar entradas en código

Puedes pasar el id de la entrada a la API REST para eliminar una entrada.

Abre el archivo wordpress_api_helper.py y añade la función delete_post:

async def delete_post(id):

async with aiohttp.ClientSession(os.getenv("WEBSITE_URL")) as session:

async with session.delete(

f"/wp-json/wp/v2/posts/{id}"

, auth=aiohttp.BasicAuth(user, password)) as response:

print("Status:", response.status)

text = await response.text()

wp_post = json.loads(text)

post_id = wp_post['id']

print(f'Post with id {post_id} deleted successfully.')

Ahora abre el archivo app.py y añade el código para importar delete_post y el menú:

from wordpress_api_helper import get_all_posts, get_post, create_post, update_post, delete_post

menu_options = {

1: 'List Posts',

2: 'Retrieve a Post',

3: 'Create a Post',

4: 'Update a Post',

5: 'Delete a Post',

}

A continuación, añade una quinta opción de menú:

elif option == 5:

print('Deleting a post...')

id = input_number('Enter the post id: ')

await delete_post(id)

Ahora ejecuta la aplicación y prueba la opción 5, pasando un id para eliminar la entrada existente en WordPress:

La aplicación Python muestra la eliminación del post seleccionado.
La aplicación Python muestra la eliminación del post seleccionado.

Nota: El post eliminado puede seguir apareciendo si ejecutas la opción Lista de Entradas:

La aplicación Python muestra la lista de publicaciones originales.
La aplicación Python muestra la lista de publicaciones originales.

La aplicación Python muestra la lista de publicaciones originales.

Para confirmar que has eliminado la publicación, espera unos segundos y vuelve a probar la opción Listar publicaciones. ¡Y ya está!

Resumen

Gracias a la API REST de WordPress y a las librerías cliente HTTP de Python, las aplicaciones de Python y WordPress pueden asociarse y hablar entre sí. La ventaja de la API REST es que te permite manejar WordPress de forma remota desde una aplicación de Python, donde el potente lenguaje de Python permite la creación automatizada de contenido que siga la estructura y frecuencia que desees.

DevKinsta hace que crear y desarrollar un sitio local de WordPress sea rápido y fácil. Proporciona un entorno local para el desarrollo de temas y plugins de WordPress y ofrece un modelo de despliegue simplificado gracias a su modelo de instalación autónomo basado en Docker.

¿Cuál es tu experiencia trabajando con Python y WordPress?

Cuando estés preparado para ampliar esa experiencia, puedes leer La guía completa de los fundamentos de API REST de WordPress para explorar otras posibilidades.

Salman Ravoof

Salman Ravoof is a self-taught web developer, writer, creator, and a huge admirer of Free and Open Source Software (FOSS). Besides tech, he's excited by science, philosophy, photography, arts, cats, and food. Learn more about him on his website, and connect with Salman on Twitter.