Una nueva API de Python

Me complace compartir fluent-discourse, un nuevo paquete de Python para consumir la API de Discourse.

Ya existen varios paquetes para consumir la API de Discourse mediante Python. ¿Entonces, por qué crear otro?

Los otros paquetes de Discourse disponibles suelen abordar el problema de manera similar: crear una función única de Python para cada extremo (endpoint) de la API.

Este enfoque tiene algunas desventajas:

  1. Es muy difícil lograr una paridad de características completa con la API. La API de Discourse está algo subdocumentada y a menudo es necesario realizar ingeniería inversa en los extremos. Además, existen numerosos plugins que exponen extremos de API que ni siquiera forman parte del núcleo. Esto presenta al usuario de la biblioteca la difícil opción de enviar solicitudes de extracción (pull requests) para agregar los extremos que necesita a la biblioteca, o construir una solución personalizada para los extremos adicionales.
  2. Tienes que aprender otra API. Además de aprender los métodos y extremos de la API de Discourse, debes averiguar cuál es la llamada de función correspondiente en Python.
  3. Hay mucho más código para probar, por lo que es más difícil lograr una cobertura de pruebas del 100 %. Por lo tanto, hay menos confianza en la calidad del software producido.

En contraste con este enfoque, utilicé una interfaz “fluent” (fluida), donde se usa la encadenación de métodos para construir solicitudes. Veamos un ejemplo.
Para obtener los temas más recientes en una categoría ‘foo’ con id=5, se utiliza este extremo:
GET /c/foo/5.json.
Para realizar esa solicitud con esta biblioteca, simplemente llama a:
client.c.foo[5].json.get()

Puedes ver que hay una paridad semántica entre el extremo de la API y la llamada correspondiente en Python.

Este enfoque:

  1. Ofrece de inmediato una paridad de características completa con la API de Discourse, incluyendo extremos no documentados, extremos de plugins y extremos que aún no se han definido (a prueba de futuro).
  2. Solo tienes que aprender la API de Discourse. Es fácil traducir cualquier llamada a la API de esta manera, por lo que no necesitas buscar la función que le corresponde.
  3. Toda la biblioteca tiene aproximadamente 150 líneas de código. Esto hace que sea trivial lograr una cobertura de pruebas del 100 %.

Hay una cobertura de pruebas del 100 % con un puñado de pruebas de integración contra un servidor de Discourse en vivo.

Si esto te resulta atractivo, ¡espero que pruebes este paquete!

21 Me gusta

Esa es una aproximación interesante…

Para hacer algo similar en PHP, tendríamos que confiar en los métodos mágicos y, por lo tanto, perder la ventaja de la autocompletación del IDE, etc. Pero podría ser un precio que valga la pena pagar.

¿Cuál es la ventaja de este enfoque sobre simplemente pasar la URL como argumento: client.get(url)?

Ese es un buen punto; la autocompletación del IDE no será de mucha ayuda aquí. Podría valer la pena usar una biblioteca diferente si eso es importante para ti.

Dado que cada cadena de métodos devuelve un nuevo cliente, una ventaja que se me ocurre es almacenar una cadena de métodos específica en una variable y reutilizarla para llamadas posteriores. Por ejemplo, supongamos que tienes una lista de datos para nuevos posts que deseas crear.

post_data = [
  {
    "raw": "Hello World!",
    "topic_id": 123,
    ...
  },
  {
    "raw": "Tester",
    "topic_id": 501,
    ...
  },
  ...
]

Podrías almacenar la cadena de métodos “Nuevo post” y reutilizarla para crear cada uno de los posts de la lista.

new_post_endpoint = client.posts.json

for post in post_data:
  new_post_endpoint.post(data=post) 

Podrías imaginar otros escenarios donde esta capacidad de reutilizar un cliente podría ser útil. Más allá de eso, no hay una gran ventaja sobre simplemente pasar la URL como sugeriste. Te animo a leer sobre la biblioteca Universal Client, que contiene información sobre la razón de ser de este tipo de enfoque.

Además, para una implementación específica de PHP de este enfoque, consulta la API de PHP de SendGrid. Me inspiré para construir esto cuando leí sobre la API de Python de SendGrid.

3 Me gusta