Para las agencias modernas, un sistema de informes coherente y de alta calidad es esencial para mantener la confianza de los clientes y fidelizarlos a largo plazo. Un informe claro e informativo te permite controlar las tendencias de ventas, demostrar la eficacia de las campañas, calcular el retorno de la inversión (ROI) y mucho más.

Sin embargo, para una agencia que gestiona docenas o incluso cientos de sitios, la generación de estos informes periódicos puede convertirse en un gran cuello de botella, comprometiendo la escalabilidad de tus operaciones.

Por eso es fundamental optimizar y automatizar la recuperación de datos. Así se recupera la eficiencia y tu equipo puede dedicarse a actividades de mayor valor, como desarrollar nuevos proyectos.

En este artículo, aprenderás a aprovechar la API de Kinsta para obtener automáticamente los datos de tu alojamiento y generar informes estratégicos con el poder de la IA.

¿Estás preparado para ampliar tu sistema de informes? Sigue leyendo.

Acceso a las Analíticas de Kinsta a través de MyKinsta y la API de Kinsta

Los clientes de Kinsta tienen acceso a una gran cantidad de datos a través del panel de control de alojamiento MyKinsta. Puedes acceder a los datos de tu plan en la sección Analíticas de tu panel de control.

Vista general de la sección Analíticas de MyKinsta.
Vista general de la sección Analíticas de MyKinsta.

La página de Analíticas está dividida en varias pestañas, cada una centrada en un aspecto específico de la actividad de tu sitio:

  • Uso del plan: Muestra el consumo de recursos de tu plan, tanto de forma acumulada como desglosado por cada sitio web.
  • Solicitudes más frecuentes: Te permite identificar las solicitudes más habituales de tu sitio, clasificadas por ancho de banda y visitas.
  • Caché: Proporciona un desglose del uso de la caché, incluyendo el desglose de la caché, los componentes de la caché del servidor y las omisiones (bypasses) de la caché del servidor.
  • CDN y edge: Ofrece datos sobre el consumo de ancho de banda de la CDN y el ancho de banda de la caché edge, además de listas de los archivos más solicitados desde la caché de la CDN.
  • Dispersión: Muestra el porcentaje de visitas desde escritorio, tableta y móvil.
  • Rendimiento: Incluye varias métricas de rendimiento, como el tiempo medio de respuesta PHP MySQL, el rendimiento PHP, el límite de hilos PHP, etc.
  • Respuesta: Proporciona estadísticas sobre los códigos de respuesta, incluido un desglose detallado de los códigos de error.
  • Geo & IP: Muestra listas de los principales países, principales ciudades y principales IP de clientes desde los que se originan las solicitudes a tu sitio.

Puedes acceder a estas mismas analíticas a nivel de sitio navegando a Sitios > nombre de sitio > Analíticas.

Analíticas del sitio en MyKinsta.
Analíticas del sitio en MyKinsta.

Las Analíticas de Kinsta ofrecen un impresionante conjunto de datos; con solo echar un vistazo al panel de control de MyKinsta, tendrás una idea muy clara del consumo de recursos, la eficiencia y el rendimiento de tu sitio. Sabrás exactamente de dónde provienen la mayoría de las solicitudes y cuáles consumen más recursos.

Junto con nuestra herramienta APM de Kinsta, las analíticas de Kinsta te permiten optimizar el rendimiento de tus sitios de WordPress.

Lo que no todo el mundo sabe es que también se puede acceder a los datos de las analíticas de Kinsta a través de la API de Kinsta. Esto te permite recuperar datos mediante programación y crear métricas de alojamiento, que luego puedes usar para generar informes automáticos y compartirlos con tus clientes.

Vamos a ver los endpoints de la API de Kinsta.

El endpoint de Analítica de la API de Kinsta

Con el endpoint de Analítica de la API de Kinsta, puedes acceder a datos sin procesar sobre el uso de recursos y el estado de tu sitio web.

  • Uso de visitas, uso de ancho de banda del servidor y uso de ancho de banda de la CDN: estas métricas registran el uso de tus recursos en relación con tu plan de alojamiento durante el periodo de facturación actual.
  • Visitas: Proporciona el número total de visitas a un entorno determinado dentro de un periodo de tiempo especificado.
  • Espacio en disco: Proporciona el espacio total en disco utilizado por un entorno determinado durante un periodo de tiempo especificado.
  • Ancho de banda del servidor: Proporciona el ancho de banda consumido por un entorno determinado durante un periodo de tiempo especificado.
  • Ancho de banda CDN: Proporciona el ancho de banda CDN consumido por un entorno determinado durante un periodo de tiempo especificado.
  • Principales países: Proporciona una lista de los principales países desde los que se originan las peticiones al sitio en un periodo de tiempo especificado.
  • Principales ciudades: muestra una lista de las principales ciudades desde las que se han recibido solicitudes en tu sitio durante un periodo de tiempo determinado.
  • Principales IPs de Clientes: Proporciona una lista de las principales direcciones IP de clientes desde las que se originaron solicitudes al sitio durante un periodo de tiempo especificado.
  • Dispersión de Visitas: Proporciona datos sobre la distribución de las visitas entre ordenadores de sobremesa, tabletas y dispositivos móviles durante un periodo de tiempo especificado.
  • Desglose de códigos de respuesta: Proporciona un desglose de los códigos de estado HTTP devueltos por el servidor en un periodo de tiempo especificado.

A continuación te mostramos algunos ejemplos de cómo usar el endpoint analytics.

Visitas

La siguiente solicitud proporciona el número total de visitas a tu sitio y el número de direcciones IP únicas que han accedido a él en los últimos 30 días:

https://api.kinsta.com/v2/sites/environments/{KINSTA_ENV_ID}/analytics/visits?time_span=30_days&company_id={KINSTA_COMPANY_ID}

La respuesta tendrá la siguiente estructura:

{
	"analytics": {
		"analytics_response": {
			"key": "uniqueip",
			"data": [
				{
					"name": "uniqueip",
					"total": 1000,
					"dataset": [
						{
							"key": "2025-10-28T00:00:00.000Z",
							"value": "1000"
						},
						{
							"key": "2025-10-28T00:00:00.000Z",
							"value": "900"
						},
						{
							"key": "2025-10-28T00:00:00.000Z",
							"value": "820"
						},
						...
					]
				}
			]
		}
	}
}

Ancho de banda

El siguiente ejemplo muestra cómo consultar la API de Kinsta para recuperar el uso de ancho de banda del servidor durante los últimos 30 días:

https://api.kinsta.com/v2/sites/environments/{KINSTA_ENV_ID}/analytics/bandwidth?time_span=30_days&company_id={KINSTA_COMPANY_ID}

La respuesta del servidor Kinsta proporciona el uso diario de ancho de banda de los últimos 30 días:

{
	"analytics": {
		"analytics_response": {
			"key": "bandwidth",
			"data": [
				{
					"name": "bandwidth",
					"total": 1000,
					"dataset": [
						{
							"key": "2026-03-11T00:00:00.000Z",
							"value": "37347250"
						},
						{
							"key": "2026-03-12T00:00:00.000Z",
							"value": "9276458"
						},
						...
					]
				}
			]
		}
	}
}

Ancho de banda CDN

En este otro ejemplo, consultamos la API de Kinsta para averiguar el uso del ancho de banda de la CDN durante los últimos 7 días:

https://api.kinsta.com/v2/sites/environments/{KINSTA_ENV_ID}/analytics/cdn-bandwidth?time_span=7_days&company_id={KINSTA_COMPANY_ID}

El servidor proporcionará los siguientes datos:

{
	"analytics": {
		"analytics_response": {
			"key": "cdn-bandwidth",
			"data": [
				{
					"name": "cdn-bandwidth",
					"total": 1000,
					"dataset": [
						{
							"key": "2026-04-02T00:00:00.000Z",
							"value": "753447"
						},
						{
							"key": "2026-04-03T00:00:00.000Z",
							"value": "16911"
						},
						...
					]
				}
			]
		}
	}
}

Puedes probarlo tú mismo introduciendo tu clave API de Kinsta (bearer token), el ID de entorno y el ID de empresa en el API playground.

Prueba la API de Kinsta en el API playground.
Prueba la API de Kinsta en el API playground.

Ahora que ya sabes cómo acceder a los datos analíticos de tu sitio en Kinsta, puedes utilizarlos para automatizar tus operaciones. Esto también incluye la automatización del sistema de informes.

En las siguientes secciones te mostraremos cómo automatizar el sistema de informes de tu agencia utilizando la API de Kinsta. Crearemos un script en Python y utilizaremos GitHub Actions para automatizar la construcción y la ejecución. Esto transformará los datos sin procesar que devuelve la API en tablas y gráficos, y consultará a la IA de Google para generar un informe final.

Es hora de ponerse manos a la obra.

Construye un sistema automatizado de informes utilizando la API de Kinsta y la IA de Google

Nuestro objetivo es crear un informe automatizado que se genere a intervalos específicos. El sistema consultará la API de Kinsta para recuperar datos sobre visitas, ancho de banda del servidor y ancho de banda de la CDN. Estos datos se utilizarán para crear gráficos y tablas en un archivo PDF. Como parte de este proceso, los datos se enviarán a la API Gemini para producir un análisis de los datos extraídos, que luego se incluirá en el informe.

Vista previa del informe automatizado generado con GitHub Actions y la API Kinsta.
Vista previa del informe automatizado generado con GitHub Actions y la API Kinsta.

Configurar el proyecto en GitHub

En la página principal de GitHub, haz clic en el botón verde New para crear un nuevo proyecto. Una vez que tengas un proyecto vacío, ve a Settings > Secrets and variables > Actions y añade los secretos que se muestran en la siguiente imagen

Secretos de repositorio para GitHub Actions
Secretos de repositorio para GitHub Actions

Almacenar tus claves API e IDs en los Secretos de GitHub los mantiene inaccesibles para cualquiera y ayuda a garantizar que tu código permanece seguro.

GEMINI_API_KEY

Puedes generar una clave API de Google AI en el panel de control de Google AI Studio. Consulta la documentación de Google AI para obtener más información.

CLAVE DE LA API KINSTA

A continuación, sigue las instrucciones de nuestro artículo para generar una clave API Kinsta.

KINSTA_COMPANY_ID, KINSTA_ENV_ID, KINSTA_SITE_ID

Puedes encontrar el ID del sitio, el ID del entorno y el ID de la empresa en Sitios > nombre del sitio > Información en tu panel de MyKinsta.

Información del sitio en MyKinsta.
Información del sitio en MyKinsta.

Ahora pasemos a los archivos del proyecto.

Bibliotecas necesarias y configuración de GitHub Actions

En el directorio raíz de tu proyecto GitHub, crea un archivo llamado requirements.txt y añade lo siguiente:

google-genai
requests
matplotlib
fpdf2

Este archivo enumera los componentes necesarios para tu proyecto.

  • google-genai: Esta es la biblioteca de Google para interactuar con los modelos Gemini.
  • requests: Una biblioteca para realizar peticiones HTTP. En este proyecto, se utilizará para enviar peticiones HTTP a la API de Kinsta.
  • matplotlib: Una biblioteca de Python para crear gráficos y visualizar datos.
  • fpdf2: Es una biblioteca que te permite generar archivos PDF.

A continuación, crea un archivo llamado .github/workflows/generate_report.yml con el siguiente código:

name: Generate Kinsta Analytics Report

on:
  push:
    branches: [main]
  workflow_dispatch:

jobs:
  build-and-run:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout Repository
        uses: actions/checkout@v4

      - name: Set up Python
        uses: actions/setup-python@v5
        with:
          python-version: '3.12'

      - name: Install dependencies
        run: |
          python -m pip install --upgrade pip
          pip install -r requirements.txt

      - name: Run Report Script
        env:
          KINSTA_API_KEY: ${{ secrets.KINSTA_API_KEY }}
          KINSTA_ENV_ID: ${{ secrets.KINSTA_ENV_ID }}
          KINSTA_SITE_ID: ${{ secrets.KINSTA_SITE_ID }}
          KINSTA_COMPANY_ID: ${{ secrets.KINSTA_COMPANY_ID }}
          GEMINI_API_KEY: ${{ secrets.GEMINI_API_KEY }}
        run: python main.py

      - name: Upload Report
        uses: actions/upload-artifact@v4
        with:
          name: Kinsta-Advanced-Report
          path: "*.pdf"

GitHub usa este archivo para ejecutar automáticamente tu código a través de GitHub Actions. Analicemos esto más de cerca:

name: Generate Kinsta Analytics Report

on:
  push:
    branches: [main]
  workflow_dispatch:
  • name: El nombre de tu proyecto tal y como aparece en la pestaña Actions de GitHub.
  • on: Determina cuándo activar el flujo de trabajo.
  • push: El flujo de trabajo se ejecuta cada vez que envías un cambio de código a la rama principal.
  • workflow_dispatch: Te permite ejecutar el flujo de trabajo manualmente.
jobs:
  build-and-run:
    runs-on: ubuntu-latest
  • jobs: El inicio de las tareas a realizar.
  • build-and-run: Un nombre arbitrario que identifica una secuencia específica de acciones.
  • runs-on: Especifica el sistema en el que debe ejecutarse el flujo de trabajo.
  • ubuntu-latest: Establece la última versión de Ubuntu Linux.
steps:
      - name: Checkout Repository
        uses: actions/checkout@v4

      - name: Set up Python
        uses: actions/setup-python@v5
        with:
          python-version: '3.12'
  • steps: La secuencia de operaciones a realizar.
  • name: El nombre de la operación a realizar
  • uses: El módulo preconfigurado de GitHub (Acción)
     - name: Install dependencies
        run: |
          python -m pip install --upgrade pip
          pip install -r requirements.txt
  • python -m pip install --upgrade pip: Actualiza pip (el gestor de paquetes de Python) a la última versión disponible.
  • pip install -r requisitos.txt: Lee el archivo requirements.txt e instala los paquetes que aparecen en él.
     - name: Run Report Script
        env:
          KINSTA_API_KEY: ${{ secrets.KINSTA_API_KEY }}
          KINSTA_ENV_ID: ${{ secrets.KINSTA_ENV_ID }}
          KINSTA_SITE_ID: ${{ secrets.KINSTA_SITE_ID }}
          KINSTA_COMPANY_ID: ${{ secrets.KINSTA_COMPANY_ID }}
          GEMINI_API_KEY: ${{ secrets.GEMINI_API_KEY }}
        run: python main.py
  • env: Recupera los valores de las variables de entorno de GitHub Secrets.
  • run: python main.py: Lanza el intérprete de Python y ejecuta el archivo main.py.
      - name: Upload Report
        uses: actions/upload-artifact@v4
        with:
          name: Kinsta-Advanced-Report
          path: "*.pdf"
  • uses: actions/upload-artifact@v4: Utiliza la GitHub Action para gestionar artefactos, que son archivos o carpetas generados durante la ejecución del script.
  • with: Establece los parámetros de configuración.

La configuración de tu proyecto de automatización está completa. Ahora es el momento de crear los scripts de Python.

Consultar la API Kinsta mediante programación

Una vez que hayas completado la configuración, navega hasta el directorio raíz de tu proyecto de GitHub y crea un nuevo archivo llamado kinsta_utils.py con el siguiente código:

import requests
import os

KINSTA_API_KEY = os.getenv("KINSTA_API_KEY")
KINSTA_SITE_ID = os.getenv("KINSTA_SITE_ID")
KINSTA_ENV_ID = os.getenv("KINSTA_ENV_ID")
KINSTA_COMPANY_ID = os.getenv("KINSTA_COMPANY_ID")
BASE_URL = f"https://api.kinsta.com/v2/sites/environments/{KINSTA_ENV_ID}/analytics"

def get_headers():
    return {"Authorization": f"Bearer {KINSTA_API_KEY}"}
  • Las dos primeras sentencias import cargan la biblioteca estándar para realizar peticiones HTTP y el módulo para interactuar con el sistema operativo (os).
  • Las cuatro líneas siguientes (os.getenv) recuperan tus credenciales de GitHub Secrets.
  • BASE_URL define el endpoint principal de la API Kinsta utilizado por el script.
  • La función get_headers genera la cabecera de autorización, que incluirá la clave de la API de Kinsta.

A continuación, crea una función de ayuda que convierta los datos brutos devueltos por la API en megabytes.

def format_bytes_to_mb(bytes_value):
    """Converts raw bytes from API to human-readable Megabytes."""

    try:
        # Standard conversion to MB
        # return round(int(bytes_value) / (1024 * 1024), 2)

        # Decimal standard (used in MyKinsta dashboard) 
        return round(int(bytes_value) / 1_000_000, 2)

    except (ValueError, TypeError):
        return 0
  • Este código ofrece dos opciones. La primera utiliza el estándar binario (1024 x 1024), y la segunda utiliza el estándar decimal. Dividir por 1_000_000 garantiza que el número de tu informe PDF coincide con el número que verían tus clientes en las Analíticas de MyKinsta.

La siguiente función consulta la API de Kinsta y devuelve un conjunto de datos sin procesar:

def fetch_kinsta_metric(endpoint, start_date, end_date):

    url = f"{BASE_URL}/{endpoint}"

    params = {
        "company_id": KINSTA_COMPANY_ID,
        "from": f"{start_date}T00:00:00.000Z",
        "to": f"{end_date}T23:59:59.000Z"
    }

    try:
        response = requests.get(url, headers=get_headers(), params=params)
        if response.status_code == 200:
            data_node = response.json()['analytics']['analytics_response']['data'][0]
            total = data_node.get('total', 0)
            dataset = data_node.get('dataset', [])[:7]
            return total, dataset

    except Exception as e:
        print(f"Error fetching {endpoint}: {e}")

    return 0, []
  • La función fetch_kinsta_metric toma tres argumentos: endpoint, start_date y end_date. Estos se usan para construir la URL de la solicitud. El endpoint puede ser visits, bandwidth o cdn-bandwidth.
  • El array params almacena los parámetros de la solicitud.
  • La respuesta de Kinsta es un objeto JSON anidado (data_node) que proporciona los valores agregados para el periodo (total) y una lista de valores diarios (dataset).

La última función del archivo kinsta_utils.py recupera el nombre del sitio.

def fetch_site_name():
    url = f"https://api.kinsta.com/v2/sites/{KINSTA_SITE_ID}"
    
    try:
        response = requests.get(url, headers=get_headers())
        if response.status_code == 200:
            data = response.json()
            site_data = data.get('site', {})
            
            site_label = site_data.get('display_name', 'Unknown Site')
            
            env_label = "Unknown Env"
            envs = site_data.get('environments', [])
            for env in envs:
                if env.get('id') == KINSTA_ENV_ID:
                    env_label = env.get('display_name')
                    break
            
            return f"{site_label} ({env_label})"
        else:
            print(f"Kinsta API Error: {response.status_code} - {response.text}")
    except Exception as e:
        print(f"Error fetching site name: {e}")
        
    return "Unknown Site"

Este código debería ser bastante claro. Consulta la Referencia de la API para obtener más detalles sobre el endpoint sites.

Ahora sólo queda configurar el flujo de trabajo.

Automatizar el flujo de trabajo con Python y Gemini

El último archivo que necesitas crear es el motor de tu aplicación. Siempre en el directorio raíz de tu proyecto de GitHub, crea un archivo main.py. Para empezar, añade el siguiente código:

import os
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
from google.genai import Client
from fpdf import FPDF, XPos, YPos
from datetime import datetime, timedelta
from kinsta_utils import fetch_kinsta_metric, format_bytes_to_mb, fetch_site_name

REPORT_LANG = "en" 
MODEL_ID = "gemini-2.5-flash" 
GEMINI_API_KEY = os.getenv("GEMINI_API_KEY")
client = Client(api_key=GEMINI_API_KEY)

today = datetime.now()
curr_end_dt = today - timedelta(days=1)
curr_start_dt = today - timedelta(days=7)
prev_end_dt = today - timedelta(days=8)
prev_start_dt = today - timedelta(days=14)

CURR_RANGE = f"{curr_start_dt.strftime('%b %d')} - {curr_end_dt.strftime('%b %d')}"
PREV_RANGE = f"{prev_start_dt.strftime('%b %d')} - {prev_end_dt.strftime('%b %d')}"

DATES = [
    prev_start_dt.strftime("%Y-%m-%d"), 
    prev_end_dt.strftime("%Y-%m-%d"), 
    curr_start_dt.strftime("%Y-%m-%d"), 
    curr_end_dt.strftime("%Y-%m-%d")
]

CURR_DAYS_LABELS = [(curr_start_dt + timedelta(days=i)).strftime("%d %a") for i in range(7)]
PREV_DAYS_LABELS = [(prev_start_dt + timedelta(days=i)).strftime("%d %a") for i in range(7)]
X_AXIS_LABELS = [(curr_start_dt + timedelta(days=i)).strftime("%d") for i in range(7)]

Así se configura el script:

  • Las sentencias import cargan las bibliotecas necesarias, y matplotlib.use('Agg') indica a Python que genere los gráficos y los guarde en memoria.
  • El siguiente bloque establece el idioma (en) y el modelo (gemini-2.5-flash), y luego inicializa el cliente Google.
  • A continuación, define ventanas de tiempo para comparar los valores de los últimos siete días con los de los siete días anteriores.
  • Por último, establece las etiquetas para las tablas y los gráficos.

El siguiente paso es definir una clase KinstaReport para generar páginas de informes utilizando la biblioteca FPDF:

class KinstaReport(FPDF):
    def __init__(self, site_name="Unknown Site"):
        super().__init__()
        self.site_name = site_name

    def header(self):
        self.set_font("Helvetica", "B", 8)
        self.set_text_color(150)
        # Site name
        self.cell(100, 10, f"Site: {self.site_name}", align="L")
        # Date generated
        self.cell(0, 10, f"Kinsta Analytics Report | Generated: {datetime.now().strftime('%Y-%m-%d')}", 
                  align="R", new_x=XPos.LMARGIN, new_y=YPos.NEXT)

    def add_metric_page(self, title, chart_path, prev_vals, curr_vals, unit=""):
        self.add_page()
        # Page title
        self.set_font("Helvetica", "B", 24)
        self.set_text_color(83, 51, 237)
        self.cell(0, 15, title, align="C", new_x=XPos.LMARGIN, new_y=YPos.NEXT)
        
        # Subtitle
        self.set_font("Helvetica", "I", 10)
        self.set_text_color(120)
        self.cell(0, 5, f"Comparison: {CURR_RANGE} vs {PREV_RANGE}", align="C", new_x=XPos.LMARGIN, new_y=YPos.NEXT)
        
        self.image(chart_path, x=10, y=42, w=190)
        
        # Data tables
        self.set_y(150)
        self.set_font("Helvetica", "B", 10)
        self.set_fill_color(245, 245, 255)
        self.set_text_color(83, 51, 237)
        
        # Table header
        col1, col2 = 35, 60
        self.cell(col1, 10, " Day (Prev)", border=1, align='C', fill=True, new_x=XPos.RIGHT, new_y=YPos.TOP)
        self.cell(col2, 10, f"Value {unit}", border=1, align='C', fill=True, new_x=XPos.RIGHT, new_y=YPos.TOP)
        self.cell(col1, 10, " Day (Curr)", border=1, align='C', fill=True, new_x=XPos.RIGHT, new_y=YPos.TOP)
        self.cell(col2, 10, f"Value {unit}", border=1, align='C', fill=True, new_x=XPos.LMARGIN, new_y=YPos.NEXT)
        
        self.set_font("Helvetica", "", 10)
        self.set_text_color(50)
        for i in range(7):
            # Zebra striping
            fill = (i % 2 == 0)
            if fill: self.set_fill_color(250, 250, 250)
            else: self.set_fill_color(255, 255, 255)
            
            self.cell(col1, 9, f" {PREV_DAYS_LABELS[i]}", border=1, align='C', fill=fill, new_x=XPos.RIGHT, new_y=YPos.TOP)
            self.cell(col2, 9, f" {prev_vals[i]}", border=1, align='C', fill=fill, new_x=XPos.RIGHT, new_y=YPos.TOP)
            self.cell(col1, 9, f" {CURR_DAYS_LABELS[i]}", border=1, align='C', fill=fill, new_x=XPos.RIGHT, new_y=YPos.TOP)
            self.cell(col2, 9, f" {curr_vals[i]}", border=1, align='C', fill=fill, new_x=XPos.LMARGIN, new_y=YPos.NEXT)

No vamos a entrar en demasiados detalles sobre este código. Para obtener más información sobre la biblioteca FPDF, consulta los recursos online:

A continuación, define una función generated_chart. Esta función convierte los datos sin procesar recibidos de Kinsta en gráficos.

def generate_chart(labels, curr, prev, title, ylabel, filename, is_bar=False):
    plt.figure(figsize=(10, 5), dpi=100)
    ax = plt.gca()
    
    ax.spines['top'].set_visible(False)
    ax.spines['right'].set_visible(False)
    ax.spines['left'].set_color('#dddddd')
    ax.spines['bottom'].set_color('#dddddd')

    if is_bar:
        # Bar Chart for bandwidth
        bars = plt.bar(labels, curr, color='#00c4b4', alpha=0.6, label='Current Period', width=0.6)
        # Add labels above the bars
        for bar in bars:
            height = bar.get_height()
            plt.text(bar.get_x() + bar.get_width()/2., height + 0.02, f'{height}', ha='center', va='bottom', fontsize=8, color='#00a194')
    else:
        # Line chart for visits
        plt.plot(labels, curr, color='#5333ed', marker='o', markersize=6, linewidth=3, label='Current', zorder=3)
        plt.plot(labels, prev, color='#a1a1a1', linestyle='--', marker='x', markersize=5, linewidth=1.5, label='Previous', alpha=0.6)
        
        plt.fill_between(labels, curr, color='#5333ed', alpha=0.1)
    
    plt.title(title, fontsize=14, pad=20, color='#333333', fontweight='bold')
    plt.ylabel(ylabel, color='#666666')
    plt.xlabel("Day of Month", color='#666666')
    plt.legend(frameon=False, loc='upper right')
    plt.grid(axis='y', linestyle='--', alpha=0.3)
    plt.tight_layout()
    plt.savefig(filename)
    plt.close()

Esta función utiliza la biblioteca Matplotlib para convertir los datos extraídos de Kinsta en gráficos para incluirlos en el informe PDF. Para más información sobre el uso de la biblioteca Matplotlib, consulta la documentación online:

Por último, añade la función que combina todas las partes que hemos descrito hasta ahora.

def main():
    site_display_name = fetch_site_name()

    metrics = {
        "visits": {"title": "Site Visits", "unit": ""},
        "bandwidth": {"title": "Server Bandwidth", "unit": "(MB)"},
        "cdn-bandwidth": {"title": "CDN Bandwidth", "unit": "(MB)"}
    }
    
    report_data = {}
    for key in metrics:
        _, data_curr = fetch_kinsta_metric(key, DATES[2], DATES[3])
        _, data_prev = fetch_kinsta_metric(key, DATES[0], DATES[1])
        
        curr_vals = []
        prev_vals = []
        for i in range(7):
            c = float(data_curr[i]['value']) if i < len(data_curr) else 0
            p = float(data_prev[i]['value']) if i < len(data_prev) else 0
            
            if "bandwidth" in key:
                curr_vals.append(format_bytes_to_mb(c))
                prev_vals.append(format_bytes_to_mb(p))
            else:
                curr_vals.append(int(c))
                prev_vals.append(int(p))
                
        report_data[key] = {"curr": curr_vals, "prev": prev_vals}

    pdf = KinstaReport(site_name=site_display_name)
    
    for key, info in metrics.items():
        chart_file = f"{key}_chart.png"
        generate_chart(X_AXIS_LABELS, report_data[key]["curr"], report_data[key]["prev"], 
                       f"{info['title']} Trends", "Units", chart_file, is_bar=("bandwidth" in key))
        pdf.add_metric_page(info["title"], chart_file, report_data[key]["prev"], report_data[key]["curr"], info["unit"])

    # Executive Summary
    pdf.add_page()
    pdf.set_font("Helvetica", "B", 20)
    pdf.set_text_color(83, 51, 237)
    pdf.cell(0, 15, "Executive Summary", align="C", new_x=XPos.LMARGIN, new_y=YPos.NEXT)
    
    curr_visits = sum(report_data['visits']['curr'])
    prev_visits = sum(report_data['visits']['prev'])
    curr_bw = sum(report_data['bandwidth']['curr'])
    prev_bw = sum(report_data['bandwidth']['prev'])

    try:
        summary_prompt = (
            f"Analyze Kinsta performance for site {site_display_name}. "
            f"Current Period ({CURR_RANGE}): {curr_visits} visits, {curr_bw:.2f}MB server bandwidth. "
            f"Previous Period ({PREV_RANGE}): {prev_visits} visits, {prev_bw:.2f}MB server bandwidth. "
            f"Compare these periods and identify trends. Language: {REPORT_LANG}. Max 4 sentences."
        )
        response = client.models.generate_content(model=MODEL_ID, contents=summary_prompt)
        summary = response.text
    except Exception as e:
        summary = f"Analytical insights unavailable. Error: {str(e)}"

    pdf.set_y(40)
    pdf.set_font("Helvetica", "", 12)
    pdf.set_text_color(0)
    pdf.multi_cell(0, 8, summary)
    
    report_filename = f"Kinsta_Report_{datetime.now().strftime('%Y-%m-%d')}.pdf"
    pdf.output(report_filename)
    print(f"Report generated: {report_filename}")

if __name__ == "__main__":
    main()

Esto es lo que hace este código

  • El bucle for recorre el array metrics y consulta la API de Kinsta dos veces: una para la semana actual y otra para la semana anterior.
  • Si los datos se refieren al ancho de banda, la función format_bytes_to_mb() convierte los datos brutos en MB.
  • La función report_data() almacena los datos recuperados.
  • A continuación, KinstaReport crea un PDF para cada centro.
  • El siguiente bucle for genera imágenes PNG para los gráficos y crea una nueva página para cada métrica.
  • La siguiente sección genera el resumen ejecutivo, calcula el número total de visitas y el total de megabytes del periodo, y envía una consulta dinámica a Gemini 2.5 Flash. Por último, la respuesta se utiliza para completar la última página del PDF.
  • El script guarda el documento con un nombre de archivo que incluye la fecha actual.
  • * La condición final garantiza que el proceso sólo se ejecute cuando el script se ejecute como programa principal.

Es hora de construir y ejecutar tu aplicación.

Recuperación del Artefacto

Ya puedes ejecutar tu aplicación. En la página de tu proyecto en GitHub, haz clic en la pestaña Actions. Busca el nombre de tu acción en el menú de la izquierda (en nuestro ejemplo, es Generate Kinsta Analytics Report, tal y como se especifica en tu archivo generate_report.yml).

La pestaña Actions muestra una lista de los flujos de trabajo
La pestaña Actions muestra una lista de los flujos de trabajo

A continuación, haz clic en el menú desplegable Run workflow de la derecha y, después, pulsa el botón verde Run workflow (actualmente solo está disponible la rama main).

Ejecutar flujo de trabajo de GitHub.
Ejecutar flujo de trabajo de GitHub.

La siguiente página muestra el flujo de trabajo actual. Haz clic en él para ver la lista de operaciones en curso.

Usar flujo de trabajo de la rama
Usar flujo de trabajo de la rama

La sección Run Report Script muestra una lista de las operaciones realizadas, mientras que la sección Upload Report proporciona la URL de descarga del artefacto. Haz clic en este enlace para descargar tu informe en formato PDF.

La sección Upload Report proporciona el enlace al informe en PDF.
La sección Upload Report proporciona el enlace al informe en PDF.

Encontrarás el mismo enlace en la sección Artifacts, en la parte inferior de la página Summary (Resumen) del flujo de trabajo

Los pasos Run Report Script (Ejecutar script de informe) y Upload Report (Cargar informe).
Los pasos Run Report Script (Ejecutar script de informe) y Upload Report (Cargar informe).

Las imágenes a continuación muestran el informe completo, incluyendo el Executive Summary (Resumen ejecutivo) generado por la IA de Google

Páginas del informe Visitas al sitio y Ancho de banda del servidor.
Páginas del informe Visitas al sitio y Ancho de banda del servidor.
Páginas de los informes de Ancho de banda de CDN y Resumen ejecutivo.
Páginas de los informes de Ancho de banda de CDN y Resumen ejecutivo.

Próximos pasos: Cómo mejorar la escalabilidad y automatizar la entrega

Esto es sólo una muestra de lo que puede hacer la API de Kinsta cuando se combina con herramientas de automatización avanzadas como GitHub Actions. La integración de la IA va más allá, transformando las cifras brutas en informes de profundidad listos para compartir con tus clientes.

Puedes mejorar aún más tus informes de varias maneras:

  • Puedes configurar tu aplicación añadiendo una línea al archivo YAML (schedule: '0 9 * * 1') para generar el informe todos los lunes por la mañana a las 9:00.
  • Puedes integrar una biblioteca como smtplib o un servicio como SendGrid para enviar el informe directamente a tu cliente.
  • Si eres una agencia con docenas o incluso cientos de sitios, podrías implementar un bucle que itere sobre una lista de ID de sitios para generar todos tus informes en una sola ejecución.
  • Puedes enriquecer aún más el contenido de tu informe utilizando la API de Kinsta para recuperar datos geográficos, desgloses de código HTTP, registros de servidor y cualquier otro dato que quieras incluir. Analizando estos datos, la IA puede identificar intentos de ataque (códigos 4xx) o picos de tráfico procedentes de regiones inesperadas.
  • Puedes afinar tu consulta para obtener respuestas de la IA más detalladas y completas.
  • Puedes personalizar la plantilla PDF con los logotipos de tu agencia y de tu cliente.

Los informes automatizados reducen la carga de trabajo de tu equipo, y la coherencia y precisión que proporcionan refuerzan la confianza y fidelidad de tus clientes.

¿Quieres empezar ya a automatizar los informes de tus clientes? Suscríbete al plan que mejor se adapte a tus necesidades y empieza a crear con la API de Kinsta hoy mismo.

Carlo Daniele Kinsta

Carlo es un diseñador y desarrollador de front-end freelance. Cuando escribe artículos y tutoriales, Carlo se ocupa principalmente de los estándares web, pero cuando juega con sitios web, su mejor compañero de trabajo es WordPress.