Escribiendo una API en Python (con Flask y RapidAPI)

Escribiendo una API en Python (con Flask y RapidAPI)

Si estás leyendo este artículo, probablemente ya estés familiarizado con las oportunidades que se abren al utilizar una API (Interfaz de Programación de Aplicaciones).

Al añadir a tu aplicación una de las muchas APIs abiertas, puedes ampliar la funcionalidad de esta aplicación o complementarla con los datos necesarios. Pero, ¿qué pasa si has desarrollado una función única que quieres compartir con la comunidad?

La respuesta es simple: necesitas crear tu propia API.

Aunque al principio parece una tarea complicada, en realidad es bastante simple. Te contaremos cómo hacerlo con Python.

Qué necesitas para comenzar

Para desarrollar una API, se requiere:

  • Python 3;
  • Flask — un marco de trabajo simple y fácil de usar para crear aplicaciones web;
  • Flask-RESTful — una extensión para Flask que permite desarrollar APIs REST de manera rápida y con una configuración mínima.

La instalación se realiza con el siguiente comando:

pip install flask-restful

Te recomendamos un taller gratuito de programación para principiantes:
Desarrollo de un bot de Telegram en C# — del 26 al 28 de agosto. Un taller gratuito que permite entender cómo funcionan los bots asistentes, las particularidades del trabajo con la API de Telegram y otros matices. Los tres mejores participantes recibirán 30,000 rublos de Skillbox..

Antes de comenzar

Vamos a desarrollar una API RESTful con funcionalidad básica de CRUD..

Para comprender completamente la tarea, analicemos dos términos mencionados anteriormente.

¿Qué es REST?

Una API REST (Transferencia de Estado Representacional) es una API que utiliza solicitudes HTTP para intercambiar datos.

Las APIs REST deben cumplir con ciertos criterios:

  • Arquitectura cliente-servidor: el cliente interactúa con la interfaz de usuario, mientras que el servidor interactúa con el backend y el almacenamiento de datos. El cliente y el servidor son independientes, cualquiera de ellos puede ser reemplazado de manera separada.
  • Sin estado: no se guardan datos del cliente en el servidor. El estado de la sesión se almacena del lado del cliente.
  • Cacheabilidad: los clientes pueden almacenar en caché las respuestas del servidor para mejorar el rendimiento general.

¿Qué es CRUD?

CRUD — es un concepto de programación que describe cuatro acciones básicas (crear, leer, actualizar y eliminar).

En una API REST, los tipos de solicitudes y los métodos de solicitud son responsables de acciones como post, get, put, delete.

Ahora que hemos aclarado los términos básicos, podemos comenzar a crear la API.

Desarrollo

Creemos un repositorio de citas sobre inteligencia artificial. La IA es una de las tecnologías de más rápido crecimiento en la actualidad, y Python es una herramienta popular para trabajar con IA.

Con esta API, un desarrollador de Python podrá obtener rápidamente información sobre IA e inspirarse en nuevos logros. Si el desarrollador tiene ideas valiosas sobre este tema, podrá agregarlas al repositorio.

Comencemos importando los módulos necesarios y configurando Flask:

from flask import Flask
from flask_restful import Api, Resource, reqparse
import random
app = Flask(__name__)
api = Api(app)

En este fragmento, Flask, Api y Resource son las clases que necesitamos.

Reqparse es una interfaz de análisis de solicitudes de Flask-RESTful… También necesitaremos el módulo random para mostrar una cita aleatoria.

Ahora crearemos un repositorio de citas sobre IA.

Cada registro del repositorio contendrá:

  • un ID digital;
  • el nombre del autor de la cita;
  • la cita.

Dado que esto es solo un ejemplo educativo, guardaremos todos los registros en una lista de Python. En una aplicación real, probablemente usaríamos una base de datos en su lugar.

ai_quotes = [
    {
        "id": 0,
        "author": "Kevin Kelly",
        "quote": "Los planes de negocio de las próximas 10,000 startups son fáciles de prever: " +
                 "Toma X y añade IA."
    },
    {
        "id": 1,
        "author": "Stephen Hawking",
        "quote": "El desarrollo de una inteligencia artificial completa podría " +
                 "significar el fin de la raza humana... " +
                 "Despegaría por sí sola y rediseñaría " +
                 "a sí misma a una tasa cada vez mayor. " +
                 "Los humanos, que están limitados por una evolución biológica lenta, " +
                 "no podrían competir y serían superados."
    },
    {
        "id": 2,
        "author": "Claude Shannon",
        "quote": "Visualizo un tiempo en el que seremos para los robots lo que " +
                 "los perros son para los humanos, " +
                 "y estoy animando a las máquinas."
    },
    {
        "id": 3,
        "author": "Elon Musk",
        "quote": "La velocidad del progreso en inteligencia artificial " +
                 "(no me refiero a AI estrecha) " +
                 "es increíblemente rápida. A menos que tengas exposición directa " +
                 "a grupos como Deepmind, " +
                 "no tienes idea de lo rápido que está creciendo " +
                 "a un ritmo cercano a lo exponencial. " +
                 "El riesgo de que ocurra algo realmente peligroso " +
                 "está en el horizonte de cinco años." +
                 "10 años como máximo."
    },
    {
        "id": 4,
        "author": "Geoffrey Hinton",
        "quote": "Siempre he estado convencido de que la única manera " +
                 "de lograr que la inteligencia artificial funcione " +
                 "es realizar el cálculo de una manera similar a la del cerebro humano. " +
                 "Ese es el objetivo que he estado persiguiendo. Estamos avanzando, " +
                 "aunque todavía tenemos mucho que aprender sobre " +
                 "cómo funciona realmente el cerebro."
    },
    {
        "id": 5,
        "author": "Pedro Domingos",
        "quote": "La gente se preocupa de que las computadoras " +
                 "se vuelvan demasiado inteligentes y tomen el control del mundo, " +
                 "pero el verdadero problema es que son demasiado estúpidas " +
                 "y ya han tomado el control del mundo."
    },
    {
        "id": 6,
        "author": "Alan Turing",
        "quote": "Parece probable que una vez que el método de pensamiento de la máquina haya comenzado, " +
                 "no pasará mucho tiempo " +
                 "hasta que supere nuestros pobres poderes… " +
                 "Podrán conversar " +
                 "entre ellos para agudizar su ingenio. " +
                 "Por lo tanto, debemos " +
                 "esperar que las máquinas tomen el control."
    },
    {
        "id": 7,
        "author": "Ray Kurzweil",
        "quote": "La inteligencia artificial alcanzará " +
                 "niveles humanos alrededor de 2029. " +
                 "Si seguimos eso hasta, digamos, 2045, " +
                 "habremos multiplicado la inteligencia, " +
                 "la inteligencia de la máquina biológica humana " +
                 "de nuestra civilización mil millones de veces."
    },
    {
        "id": 8,
        "author": "Sebastian Thrun",
        "quote": "Nadie lo expresa de esta manera, pero creo " +
                 "que la inteligencia artificial " +
                 "es casi una disciplina de humanidades. Realmente es un intento " +
                 "de entender la inteligencia humana y la cognición humana."
    },
    {
        "id": 9,
        "author": "Andrew Ng",
        "quote": "Estamos haciendo esta analogía de que la IA es la nueva electricidad." +
                 "La electricidad transformó industrias: agricultura, " +
                 "transporte, comunicación, manufactura."
    }
]

Ahora necesitamos crear una clase de recurso Quote que defina las operaciones de los endpoints de nuestra API. Dentro de la clase, debemos declarar cuatro métodos: get, post, put, delete.

Comencemos con el método GET

Este permite obtener una cita específica indicando su ID o bien una cita aleatoria, si no se indica el ID.

class Quote(Resource):
    def get(self, id=0):
        if id == 0:
            return random.choice(ai_quotes), 200
        for quote in ai_quotes:
            if(quote["id"] == id):
                return quote, 200
        return "Quote not found", 404

El método GET devuelve una cita aleatoria si el ID tiene el valor predeterminado, es decir, cuando se llama al método sin asignar un ID.

Si se proporciona, el método busca entre las citas y encuentra aquella que tiene el ID indicado. Si no se encuentra nada, se muestra el mensaje "Quote not found", 404.

Recuerde: el método devuelve el estado HTTP 200 en caso de que la solicitud sea exitosa y 404 si no se encuentra el registro.

Ahora crearemos el método POST para agregar una nueva cita al repositorio

Este recibirá el ID de cada nueva cita al ingresarla. Además, POST utilizará reqparse para analizar los parámetros que vendrán en el cuerpo de la solicitud (autor y texto de la cita).

def post(self, id):
      parser = reqparse.RequestParser()
      parser.add_argument("author")
      parser.add_argument("quote")
      params = parser.parse_args()
      for quote in ai_quotes:
          if(id == quote["id"]):
              return f"Quote with id {id} already exists", 400
      quote = {
          "id": int(id),
          "author": params["author"],
          "quote": params["quote"]
      }
      ai_quotes.append(quote)
      return quote, 201

En el código anterior, el método POST recibió el ID de la cita. Luego, utilizando reqparse, obtuvo el autor y la cita de la solicitud, guardándolos en el diccionario params.

Si ya existe una cita con el ID proporcionado, el método devuelve un mensaje correspondiente y el código 400.

Si la cita con el ID proporcionado aún no se ha creado, el método crea un nuevo registro con el ID y el autor, así como otros parámetros. Luego, añade el registro a la lista ai_quotes y devuelve el registro con la nueva cita junto con el código 201.

Ahora creamos el método PUT para modificar una cita existente en el repositorio.

def put(self, id):
      parser = reqparse.RequestParser()
      parser.add_argument("author")
      parser.add_argument("quote")
      params = parser.parse_args()
      for quote in ai_quotes:
          if(id == quote["id"]):
              quote["author"] = params["author"]
              quote["quote"] = params["quote"]
              return quote, 200
      
      quote = {
          "id": id,
          "author": params["author"],
          "quote": params["quote"]
      }
      
      ai_quotes.append(quote)
      return quote, 201

El método PUT, similar al ejemplo anterior, toma el ID y la entrada y parsea los parámetros de la cita utilizando reqparse.

Si la cita con el ID especificado existe, el método la actualizará con los nuevos parámetros y luego devolverá la cita actualizada con un código 200. Si la cita con el ID especificado aún no existe, se creará una nueva entrada con un código 201.

Finalmente, vamos a crear un método DELETE para eliminar una cita que ya no inspira.

def delete(self, id):
      global ai_quotes
      ai_quotes = [quote for quote in ai_quotes if quote["id"] != id]
      return f"La cita con id {id} ha sido eliminada.", 200

Este método recibe el ID de la cita como entrada y actualiza la lista de ai_quotes, utilizando la lista global.

Ahora que hemos creado todos los métodos, solo necesitamos añadir el recurso a la API, definir la ruta y ejecutar Flask.

api.add_resource(Quote, "\/ai-quotes", "\/ai-quotes\/", "\/ai-quotes\/")
if __name__ == '__main__':
    app.run(debug=True)

¡Nuestro servicio REST API está listo!

A continuación, podemos guardar el código en un archivo app.py, ejecutándolo en la consola con el siguiente comando:

python3 app.py

Si todo está bien, deberíamos obtener algo como esto:

* Modo de depuración: activado
* Ejecutándose en 127.0.0.1:5000\/ (Presiona CTRL+C para salir)
* Reiniciando con stat
* ¡El depurador está activo!
* PIN del depurador: XXXXXXX

Probando la API

Después de crear la API, es necesario probarla.

Esto se puede hacer utilizando la utilidad de consola curl o el cliente Insomnia REST, o publicando la API en Rapid API.

Escribiendo una API en Python (con Flask y RapidAPI)

Publicamos nuestra API

RapidAPI es el mayor mercado del mundo con más de 10,000 API (y alrededor de 1 millón de desarrolladores).

RapidAPI no solo proporciona una interfaz única para trabajar con APIs externas, sino que también permite publicar rápidamente y sin problemas su propia API.

Para hacer esto, primero debe publicarse en algún servidor en la red. En nuestro caso utilizaremos Heroku. Trabajar con él no debería presentar dificultades, (puedes aprender más sobre él aquí).

Cómo publicar tu API en Heroku

1. Instalamos Heroku.

Primero, debes registrarte e instalar Heroku Command Line Interface (CLI). Esto funciona en Ubuntu 16+.

sudo snap install heroku --classic

Luego iniciamos sesión:

heroku login

2. Agregamos los archivos necesarios.

Ahora necesitamos agregar los archivos para la publicación en la carpeta de nuestra aplicación:

  • requirements.txt con la lista de módulos de Python necesarios;
  • Procfile, que indica qué comandos deben ejecutarse para iniciar la aplicación;
  • .gitignore — para excluir archivos que no son necesarios en el servidor.

El archivo requirements.txt contendrá las siguientes líneas:

  • flask
  • flask-restful
  • gunicorn

Por favor, tenga en cuenta: hemos añadido gunicorn (Servidor HTTP WSGI de Python) a la lista, ya que necesitamos ejecutar nuestra aplicación en el servidor.

El archivo Procfile contendrá:

web: gunicorn app:app

Contenido de .gitignore:

*.pyc
__pycache__/

Ahora que se han creado los archivos, iniciemos el repositorio git y hagamos un commit:

git init
git add
git commit -m "Primer commit de API"

3. Creamos una nueva aplicación en Heroku.

heroku create

Enviamos la rama master al repositorio remoto de Heroku:

git push heroku master

Ahora podemos comenzar abriendo el Servicio API con los siguientes comandos:

heroku ps:scale web=1
heroku open
 

La API estará disponible en la dirección your-random-heroku-name.herokuapp.com/ai-quotes.

Cómo agregar su API de Python en el marketplace RapidAPI

Una vez que el servicio API esté publicado en Heroku, puede agregarlo a Rapid API. Aquí hay documentación detallada sobre este tema.

1. Creamos una cuenta en RapidAPI.

Escribiendo una API en Python (con Flask y RapidAPI)

Registre una cuenta gratuita: puede hacerlo a través de Facebook, Google, GitHub.

Escribiendo una API en Python (con Flask y RapidAPI)

2. Agregamos la API en el panel de control.

Escribiendo una API en Python (con Flask y RapidAPI)

3. A continuación, ingresamos información general sobre su API.

Escribiendo una API en Python (con Flask y RapidAPI)

4. Después de hacer clic en “Agregar API”, aparece una nueva página donde puede ingresar información sobre nuestra API.

Escribiendo una API en Python (con Flask y RapidAPI)

5. Ahora puede ingresar manualmente los endpoints de la API o cargar un archivo swagger usando OpenAPI.

Escribiendo una API en Python (con Flask y RapidAPI)

Ahora necesitamos definir los endpoints de nuestra API en la página de Endpoints. En nuestro caso, los endpoints corresponden al concepto CRUD (get, post, put, delete).

Escribiendo una API en Python (con Flask y RapidAPI)

A continuación, debemos crear un endpoint GET AI Quote, que devuelve una cita aleatoria (en caso de que el ID sea el predeterminado) o una cita para el ID especificado.

Para crear el endpoint, haga clic en el botón “Crear Endpoint”.

Escribiendo una API en Python (con Flask y RapidAPI)

Repetimos este proceso para todos los demás endpoints de la API. ¡Eso es todo! ¡Felicidades, ha publicado su API!

Si todo va bien, la página de la API se verá algo así:

Escribiendo una API en Python (con Flask y RapidAPI)

Conclusión

En este artículo, exploramos el proceso de creación de su propio Servicio API RESTful en Python, junto con el proceso de publicación de la API en la nube de Heroku y su adición al catálogo de RapidAPI.

Pero en la versión de prueba solo se mostraron los principios básicos del desarrollo de API; aspectos como la seguridad, la resistencia y la escalabilidad no se consideraron.

Al desarrollar una API real, es necesario tener en cuenta todo esto.

Fuente: habr.com

Compra un hosting fiable para sitios web con protección contra DDoS, servidores VPS VDS 🔥 Compra un hosting fiable para sitios web con protección contra DDoS, servidores VPS VDS | ProHoster