Explicando un script de Python para la API de Cato

Este artículo introduce la API de Cato y analiza una aplicación de Python de ejemplo.

Introducción

La API de Cato se implementa de acuerdo con la especificación de GraphQL. Aunque GraphQL está diseñado para producir APIs fáciles de usar, aprender a utilizar cualquier nueva tecnología aún requiere una inversión de tiempo por parte del desarrollador. El objetivo de este documento es reducir el nivel de esta inversión y guiar por una pequeña aplicación de Python que ejecuta la llamada de API de Cato admins y simplemente devuelve el número de administradores que se han definido para una cuenta. Al hacerlo, se introducen al lector los elementos más importantes de una aplicación de API de Cato GraphQL.

Nota

Notas:

Se espera que el lector tenga una comprensión básica de lo siguiente:

  • Scripting o programación (por ejemplo, está familiarizado con conceptos como variables y bibliotecas de código)

  • La especificación de JSON (por ejemplo, ha trabajado con documentos JSON)

  • Redes (por ejemplo, conoce la existencia del protocolo HTTP y qué es un servidor)

Tener algo de experiencia con el lenguaje Python sería beneficioso, pero debería ser posible entender el artículo sin esto.

Repaso de una aplicación básica de API de Cato

La aplicación presentada aquí ha sido escrita en Python y utiliza la llamada admins de la API de Cato para recuperar el número total de administradores definidos para una cuenta.  Se eligieron Python y la llamada de API admins porque:

  • Python es un lenguaje muy común que es fácil de leer y entender

  • La llamada de API admins puede ser usada para crear un ejemplo muy simple de llamada a la API de Cato GraphQL

El programa de ejemplo es básico y no contiene verificaciones de errores.  El programa no hace más que imprimir el número total de administradores definidos para la cuenta. 

Nota

Nota: La API de Cato no está ligada a ningún lenguaje de programación específico.  Es posible implementar una aplicación usando cualquier lenguaje que pueda usar la función HTTP POST y procesar documentos JSON.  

Descripción general del programa de ejemplo

Este programa de ejemplo es corto y no incluye ninguna lógica de toma de decisiones ni código para repetir acciones.  Podría haber sido aún más corto combinando algunas de las líneas de código en una sola línea.  Se han incluido líneas de código adicionales para facilitar la explicación de lo que está sucediendo.

# Importar código de biblioteca de Python
import os
import urllib.request
import ssl
import json

# Obtener la clave de API de Cato de una variable de entorno
cato_api_key = os.getenv("CATO_API_KEY")

# Crear la solicitud de GraphQL para ser enviada
get_total_admins = '''{
    admins (accountID: 12345) {
        total        
    }
}'''
graphql_query = {'query': get_total_admins}

# Construir la solicitud http
cato_api_url = "https://api.catonetworks.com/api/v1/graphql2"
headers = {'x-api-key': cato_api_key,
           'Content-Type':'application/json'}
unverified_ctx = ssl._create_unverified_context()
json_post = json.dumps(graphql_query)
json_post_encoded = json_post.encode()
request = urllib.request.Request(url=cato_api_url, data=json_post_encoded, headers=headers)

# Enviar la consulta y convertir la respuesta en un diccionario de Python
response = urllib.request.urlopen(request, context=unverified_ctx, timeout=30)
json_response_encoded = response.read()
json_response = json_response_encoded.decode()
get_admins_total_result = json.loads(json_response)

# Extraer el total de los datos devueltos e imprimirlo
total = get_admins_total_result['data']['admins']['total']
print('El número total de administradores definidos con su cuenta es: {}'.format(total))

Nota

¡IMPORTANTE! Este programa se proporciona como una demostración de cómo acceder a la API de Cato con Python. No es una versión oficial de Cato y se proporciona sin garantías de soporte. El manejo de errores está restringido al mínimo necesario para que el script funcione con la API, y puede no ser suficiente para entornos de producción.

Todas las preguntas o comentarios deben enviarse a api@catonetworks.com

El diagrama proporcionado a continuación muestra la secuencia de eventos que tienen lugar cuando se ejecuta el programa:

  1. El programa crea un documento JSON que se envía al servidor de GraphQL de la API de Cato.

  2. El servidor de GraphQL de la API de Cato verifica que la llamada de API definida en el documento JSON sea correcta y obtiene los datos solicitados del servicio de Cato.

  3. El servidor de GraphQL de la API de Cato devuelve los datos al programa en un archivo JSON.

Cato_API_FLow.jpeg

Importar código de biblioteca de Python

Una de las razones para usar Python para el programa de ejemplo es la disponibilidad de un conjunto variado de bibliotecas.  Estas bibliotecas proporcionan funciones y objetos que pueden manejar una amplia gama de tareas.  Ahora examinaremos cada biblioteca importada y proporcionaremos notas para explicar por qué es necesaria.

import os
  • La biblioteca os proporciona una función que permite al código acceder a los datos contenidos en las variables de entorno del sistema operativo.

import urllib.request
  • El módulo request de la biblioteca urllib define la clase Request que crea objetos que pueden manejar la comunicación con servidores remotos accesados a través de una URL.

  • Esto hará posible enviar la solicitud de API de Cato al servidor de API de GraphQL de Cato

import ssl
  • La biblioteca ssl es necesaria para crear un contexto no verificado personalizado para las solicitudes enviadas al servidor de API de GraphQL de Cato.

import json
  • Esta biblioteca contiene funciones que harán posible convertir un diccionario de Python en una cadena JSON y viceversa.

  • Esta capacidad para convertir entre los dos formatos diferentes hace que sea mucho más fácil escribir código que pueda trabajar con documentos JSON.

Obteniendo la clave de API de Cato

Esta línea de código utiliza la función de biblioteca getenv para leer la clave de API de una variable de entorno y asignarla a una variable.

cato_api_key = os.getenv("CATO_API_KEY")

El servidor de GraphQL de Cato espera recibir esta clave en un encabezado HTTP.  La clave no se proporciona en el documento JSON porque la especificación de GraphQL no incluye la autorización como parte del estándar.  Incluir la autorización en el documento JSON sería una violación de la especificación.  La clave de API de Cato se genera a través de la Aplicación de Gestión de Cato.  Para obtener más información sobre cómo crear una clave de API, consulte Generación de claves de API para la API de Cato.

Nota

¡ADVERTENCIA! Aunque es posible codificar rígidamente la clave de API de Cato en su código, se recomienda encarecidamente que no lo haga.

Creando la solicitud de GraphQL para enviar

Las siguientes líneas de código crean un directorio de Python que contiene un par clave/valor.  El valor de la entrada se construye usando una cadena multilínea de Python que define la consulta que se enviará al servidor de GraphQL.

get_total_admins = '''{
    admins (accountID: 12345) {
        total    
    }
}'''
graphql_query = {'query': get_total_admins}

El servidor de GraphQL de Cato interpretará esta cadena para significar: ejecutar la función get_total_admins, pasándole dos argumentos (accountID y tipo) y devolviendo solo el "total" de entidades.  O dicho más directamente, "Devuelve el número total de entidades de administradores que están definidas para el ejemplo de cuenta # 12345".  Este ejemplo específico de la llamada de API admins ilustra una ventaja importante de una API de GraphQL

  • El servidor solo devuelve los datos que la aplicación solicitó

De hecho, la llamada admins puede devolver muchos más datos.  Por ejemplo, es posible que una aplicación solicite que admins devuelva detalles sobre cada administrador.  Sin embargo, esta aplicación solo necesita saber el número total de administradores.  Esta característica de GraphQL evita lo que se conoce como sobreobtener y puede simplificar enormemente el código necesario para implementar la aplicación.

Construyendo la solicitud HTTP

En esta sección del programa se construye un objeto de solicitud.  Este objeto se utilizará para enviar la llamada de API al servidor de GraphQL utilizando HTTPS. Este objeto de solicitud requiere información que es proporcionada por varios otros objetos que necesitan ser creados primero.   Primero, se construye un objeto de cadena simple para contener la URL del servidor de GraphQL al que el objeto de solicitud enviará la consulta.

cato_api_url = "https://api.catonetworks.com/api/v1/graphql2"

Nota

Nota: Una API de GraphQL utiliza solo una URL para todas las llamadas de API.  Los detalles de la llamada, como los argumentos, se proporcionan en el documento JSON.  Esto contrasta con una API REST, que usaría una URL diferente para cada llamada de API y pasaría los argumentos a la llamada agregándolos a la URL.  Este uso de una única URL que no está sobrecargada de argumentos se considera otra ventaja de una API de GraphQL. 

A continuación, se crea un diccionario que define dos encabezados HTTP.  Estos encabezados son utilizados por el objeto de solicitud para construir una solicitud HTTP POST que el servidor de GraphQL aceptará.  Sin estos encabezados, las solicitudes HTTP POST serían rechazadas por el servidor.

headers = {'x-api-key': cato_api_key,           
           'Content-Type':'application/json'}

La siguiente línea de código crea un objeto de contexto SSL. Python usa este objeto para determinar cómo debería cifrar las solicitudes HTTP y enviarlas usando Seguridad a Nivel de Transporte (TLS). Aquí estamos creando un objeto de contexto SSL que no verifica certificados. Esto se ha hecho para evitar errores de certificado en redes sujetas a inspección TLS ascendente.

unverified_ctx = ssl._create_unverified_context()

Nota

¡IMPORTANTE! Usar un objeto de contexto SSL no verificado significa que no se realizarán verificaciones para asegurarse de que los certificados sean válidos. Cato Networks recomienda que nunca use tal enfoque en producción. Los detalles de cómo fortalecer la seguridad están fuera del alcance de este documento.

Las siguientes dos líneas de código convierten el diccionario de Python que contiene la llamada de API de Cato en una cadena y codifican esa cadena en bytes.  El segundo paso es necesario para permitir que la cadena se transmita sobre la red.

json_post = json.dumps(graphql_query)
json_post_encoded = json_post.encode()

Finalmente se crea el objeto de solicitud y el programa ahora está listo para enviar la llamada get_total_admins al servidor.

request = urllib.request.Request(url=cato_api_url, data=json_post_encoded, headers=headers)

Enviando la consulta y procesando la respuesta

Aquí el programa envía la solicitud al servidor de GraphQL llamando a la función urlopen de la biblioteca urllib.  Llamar a esta función resultará en el retorno de un objeto HTTPResponse.  

response = urllib.request.urlopen(request, context=unverified_ctx, timeout=30)

Nota

¡ADVERTENCIA! Llamar a la función urlopen podría resultar en la generación de un error.  Por ejemplo, el servidor de GraphQL podría rechazar la solicitud debido a un error de sintaxis o problemas de red podrían resultar en un tiempo de espera (es decir, no hay respuesta después de 30 segundos).  Estos errores no se manejan aquí.

El objeto devuelto por la función urlopen incluye un campo de cuerpo que contiene el documento JSON devuelto por el servidor.  Esto se puede extraer del objeto ejecutando su método read que devuelve un objeto de bytes.  Este objeto de bytes se convierte luego en un objeto de cadena llamando al método decode del objeto de bytes.

json_response_encoded = response.read()
json_response = json_response_encoded.decode()

Esta cadena decodificada contiene un documento JSON que se verá así:

{    
    "data" : {
         "admins" : {
              "total": 4
         }
    }
}

Como verás, el formato de los datos devueltos se parece mucho al formato de la solicitud que fue enviada al servidor.  Esto es intencional y otra ventaja de usar la especificación GraphQL para implementar una API.  Este enfoque simplifica la codificación de la aplicación al mantener los datos devueltos con la misma estructura que la solicitud.

La línea final de código en esta sección del programa utiliza la función 'loads' de la librería json para convertir la cadena JSON devuelta en un diccionario anidado de Python.  

get_total_admin_result = json.loads(json_response)

Extrayendo el Total de los Datos Devueltos e imprimiéndolo

Las últimas dos líneas del código extraen el valor del campo total que fue devuelto por el servidor y lo imprimen en la consola. 

total = get_total_admins_result['data']['get_total_admins']['total']
print('El número total de administradores definidos para su cuenta es: {}'.format(total)) 

La salida se verá así:

El número total de administradores definidos para su cuenta es: 4

Resumen

El objetivo de este documento era ilustrar al lector lo fácil que es usar la API de Cato.  No se han incluido detalles exhaustivos sobre la API de Cato y no se ha escrito código para manejar errores.  En su lugar, se ha utilizado un simple programa Python para resaltar los elementos más importantes de una aplicación API de Cato.  Estos son:

  • Crear una llamada a la API de Cato y agregarla a un documento JSON

  • Obtener la clave de API de Cato

  • Crear encabezados HTTP que contengan la clave de la API de Cato y definan el formato de los datos (JSON) que se envían

  • Enviar el documento JSON (codificado en bytes) al servidor de la API Cato GraphQl usando el comando POST de HTTP cifrado con TLS

  • Convertir el objeto de respuesta devuelto por el servidor en un documento JSON

  • Convertir el documento JSON en un formato que pueda ser usado por el programa

¿Fue útil este artículo?

Usuarios a los que les pareció útil: 5 de 5

0 comentarios