DEV Community

¿Qué es una API REST? ¿Cómo funciona?

Accediendo mediante REST

Vamos a ver cómo podemos acceder a una API REST mediante Python, de la manera más sencilla posible. Las API REST ofrecen una serie de operaciones estandarizadas, como GET (obtener información), POST (guardar información), DELETE (borrar información), o PUT (modificar información). En este pequeño artículo, solo veremos GET.

Básicamente, el acceso se realiza mediante una URL. A partir de esa URL, utilizando barras "/" o parámetros URL ("?param1=valor1&param2=valor2..."), especificamos la información que necesitamos darle al servidor para que nos devuelva los datos pedidos.

Por ejemplo, vamos a utilizar dos servicios REST API. El primero se refiere a (muchos), datos de países. La información a facilitar será el nombre del país. Las siguientes URL se pueden probar en el navegador directamente, claro. Por ejemplo:

URL de entrada base: https://restcountries.com/v3.1/name/

Esta URL nos permitirá obtener información sobre cualquier país, ofreciendo el nombre del país (en inglés), al final de la URL. Así, para España:

Ejemplo de uso: https://restcountries.com/v3.1/name/spain

El segundo servicio es sobre la salida y la puesta del sol, indicándonos las horas exactas (en UTC), y el tiempo de luz en el día.

URL de entrada base:
https://api.sunrise-sunset.org/json

Esta URL nos devolverá la información de la salida y puesta del sol si le damos la latitud y la longitud deseadas. En este caso, emplearemos parámetros en la URL. En cuanto al parámetro formatted=0, se emplea para que devuelva las fechas y horas en formato ISO.

Ejemplo de uso: https://api.sunrise-sunset.org/json?lat=40.4378373&lng=-3.8443425&formatted=0

De acuerdo, ahora ya podemos escribir un programa que se conecte a estas API y nos devuelva la información en formato JSON, que en Python podemos manejar como un diccionario.

Una función para lograrlo sería la siguiente:

import urllib.request as request
import urllib
import json


def get_data_from_url(url: str) -> dict:
    toret = {"request": {"url": url}, "data": None}

    try:
        with request.urlopen(url) as response:
            if response.status == 200:
                toret["data"] = json.loads(response.read().decode())
                toret["request"]["response"] = 200
            else:
                toret["request"]["response"] = response.status
            ...
        ...
    except Exception as err:
        if isinstance(err, urllib.error.URLError):
            toret["request"]["response"] = err.code
        ...

        toret["request"]["message"] = str(err)
    ...

    return toret
...
Enter fullscreen mode Exit fullscreen mode

En el repositorio Github para free_apis se puede encontrar el código completo, con un ejemplo interactivo.

La función get_data_from_url(url: str) -> dict tiene como parámetro la URL completa para la conexión. Mediante la librería estándar urllib, concretamente del módulo request, podemos utilizar la función urlopen(url: str): Object, que nos devolver un objeto que tiene el atributo status, para poder comprobar el código de retorno, y el método read() para leer los bytes que retorne la web. Podemos transformar esos bytes en una cadena de caracteres Unicode con el método decode(). En caso de que haya algún error, lo introduce como parte del diccionario que devuelve. En todo caso, siempre introduce la URL y el código de respuesta.

Así, en el diccionario devuelto encontraremos:

{
    "request": {
        "url": "http://...",
        "response": 200,
    },
    data: {
        ...
    }
}
Enter fullscreen mode Exit fullscreen mode

En caso de error, encontraremos el subdiccionario request con la URL, el código de respuesta, y además un nuevo campo message que nos devolverá más información sobre el error. El subdiccionario data será None (null en JSON).

En otro caso, no habrá campo message en request, y response será 200, y dentro de data estarán los datos pedidos.

Por ejemplo, podemos utilizar Spain como parámetro para obtener los datos de España, guardarlos en un diccionario, y acceder a su información:

resp = get_data_from_url("https://restcountries.com/v3.1/name/spain")
print("Superficie:", resp["data"][0]["area"])
print("Población:", resp["data"][0]["population"])
Enter fullscreen mode Exit fullscreen mode

Por algún motivo, los datos devueltos son una lista de diccionarios, así que tendremos que acceder a la primera posición.

Si tomamos la longitud y latitud de un sitio muy chulo, (lat: 42.344873, lon: -7.8580309) podemos acceder a la web de datos de horas de salidas y puestas de sol:

resp = get_data_from_url("https://api.sunrise-sunset.org/json?lat=42.344873&lng=-7.8580309&formatted=0")
print("Salida del sol:", resp["data"]["results"]["sunrise"])
print("Puesta del sol:", resp["data"]["results"]["sunset"])
Enter fullscreen mode Exit fullscreen mode

Ya solo queda comentar que, en algunas de estas API, será necesario obtener una API key que después será necesario agregar a la URL de acceso. Esta API key se obtiene rellenando un formulario en el sitio web de la API. La razón de ser es controlar el acceso de manera que se pueda responder a un DoS, posible ataque de denegación de acceso, por ejemplo.

¡Acceder a información proporcionada por la REST API que deseemos es muy sencillo!

Top comments (2)

Some comments may only be visible to logged-in visitors. Sign in to view all comments.