Proyecto Python medio: ¿Cómo crear una API usando FastAPI?

Hola mundo 🤟🏻 mi nombre es Francisco, fcoterroba en Internet y hoy os traigo un post de los que suelen gustar aquí en la web. Como veis en el título, hoy vamos a crear una API en Python usando la librería o framework FastAPI.

Proyecto muy interesante para añadir a tu portafolio de desarrollador ya sea backend e incluso front-end.

Antes de comenzar, cómo no podía ser de otra forma, si aún no lo has visto, te recomiendo encarecidamente que vayas a ver el último vídeo que tengo en mi canal de YouTube en el que expliqué, de manera muy sencilla y concisa, cómo realizar la instalación de una bombilla inteligente 🧠 con la cual podrás cambiar el color del mismo, controlarla mediante tu propia voz y muchísimo más! Puedes verlo aquí 👇🏻

Por último antes de comenzar, quería comunicar que llevo unas semanas subiendo vídeos a TikTok. Últimamente son de Eurovisión dado que ya queda poco para ello pero te dejo por aquí el último que hice a día de hoy sobre informática.

@fcoterroba ¿Cómo hacer un pequeño #juego en #Python ? Like para parte 2! #fyp #parati #dev #programacion ♬ LoFi(860862) – skollbeats

¿Algo que deba saber antes de empezar?

Pues sí, varias cosas realmente:

  • ¿Qué es una API?
    • Una API (abreviatura de Application Programming Interfaces), es, básicamente, un conjunto de definiciones y protocolos que se utilizan para desarrollar e integrar el software de las aplicaciones o webs. Permitiendo así la comunicación entre dos aplicaciones a priori totalmente distintas.
    • Una API es un sitio donde se engloba cierta información sobre ciertos aspectos. La cosa es que dicha información no es accesible y no es leíble por humanos fácilmente.
    • Por lo general, una API devuelve la información cuando es requerida en formato JSON y es el desarrollador en su nueva web o software, el encargado de hacer legible dicha información.
      • Por ejemplo, esta API gratuita de Los Simpsons, si accedes a la API básica, te devuelve una frase de alguno de los personajes de esta serie.
  • ¿Qué es Python?
    • Python es un lenguaje de programación usado en prácticamente todo lo imaginable
    • Desarrollo web, software, IA, ML, Data Science. Son algunos de los ámbitos tech en los que Python es ampliamente usados.
    • Ofrece una legibilidad bastante buena y cercana a la lectura humana.
      • En la categoría Python de la web puedes encontrar +8 proyectos con Python divididos por su dificultad. ¿A qué esperas? Tu API puede esperar.
  • ¿Qué es FastAPI?
    • FastAPI es un framework para construir APIs de forma sencilla y rápida con Python.
    • En los últimos tiempos se ha vuelto un framework muy popular al ser considerado como uno de los frameworks más rápidos existentes en Python.
    • Algunos benchmarks han llegado a sacar a FastAPI mucho más por delante de Django, FLask o Pyramid.
Gráfico de comparación de número de respuestas por segundo para petición que devuelve una fila de la base de datos. FastAPI en segundo lugar.

1️⃣ PRIMER PASO 1️⃣ Instalar lo necesario

Vamos a tener en cuenta que tenemos ya instalado Python, en mi caso tengo la versión Python 3.10.7 pero no necesariamente debes tener esta versión para seguir el tutorial. Solo es recomendable que sea una versión Python 3. python 3.x.x

Lo primero que tenemos que hacer es instalar la librería de FastAPI, para ello vamos a usar el comando

pip install fastapi

Por último, necesitaremos la librería uvicorn, un servidor web ASGI escrito para Python. Necesitaremos esta librería para comprobar que todo esté funcionando. Podemos instalarla con este comando:

pip install uvicorn

Una vez instalados, podemos empezar de verdad

2️ SEGUNDO PASO 2️⃣ Hola mundo

Lo primero y como ya te estarás imaginado, es importar la librería de FastAPI, para ello lo importamos como cualquier otro:

from fastapi import FastAPI

Luego, tendremos que crear un objeto general que, por lo normal, se le suele denominar como app

app = FastAPI()

FastAPI funciona con funciones asíncronas y muchos getters, por lo que tendremos que coger, para empezar, la raíz de nuestro servidor y justo debajo declarar el mensaje de return:

from fastapi import FastAPI

app = FastAPI()


@app.get("/")
async def root():
    return {"message": "Hello World"}

Con esto, si vistamos nuestro localhost (por defecto en el puerto 8000), obtendremos el json que hemos mandado para return:

3️ TERCER PASO 3️⃣ Más funciones y páginas

Con el paso anterior hemos hecho un gran avance, tenemos ya nuestro servidor web funcionando, a la espera de consulta y que nos devuelve un json con lo que decimos. Está bien, pero falta más chicha, no?

En este caso voy a hacer la prueba como si fuera a crear un API del famoso anime “Shin Chan”.

Lo primero que tendremos que hacer es, de alguna forma, almacenar la información que querremos devolver en la API. Yo voy a almacenar los personajes principales de la serie en un JSON con su edad, una imagen, nombre, etc. Tal que así:

Ahora, supongamos que queremos pasar esos cuatro personajes a la raíz de nuestra API.

Para ello simplemente tendremos que convertir nuestro archivo JSON a un diccionario Python. Importamos la librería json para trabajarlo y abriéndolo, podemos pasar la variable usando la función load

import json

data = ""

with open('characters.json') as json_file:
    data = json.load(json_file)

Por último, en nuestro root le pasamos dicha variable y si visitamos nuestra API obtendremos dicho json

@app.get("/")
async def root():
    return data

Si le pasamos, por ejemplo, data[0] le pasaremos solo el primer campo del json, data[1] para el segundo campo, etc.

Ahora, todo esto que hemos hecho ha sido en el root, al acceder a la página principal de la API, supongamos que queremos que en cada página se devuelva una cierta cosa.

Para ello, tendremos que crear un getter con una función por cada página que queramos.

Por ejemplo, digamos que quiero una página que devolverá un personaje totalmente random por cada visita. Importamos la librería random y usamos la función choice pasándole COMO LISTA nuestro diccionario.

import random

@app.get("/randomCharacter")
async def randomCharacter():
    return random.choice(list(data))

Otro ejemplo, supongamos que tenemos un listado con todos los ids que podemos obtener, para ello podemos pasarle un id al getter y a la función, para devolver dicho registro.

Ten en cuenta que restamos uno porque el json empieza por 0 pero el usuario escribirá “normal”, empezando por 1.

@app.get("/specificCharacter/{id}")
async def specificCharacter(id: int):
    return data[id-1]

4️⃣ CUARTO PASO 4️ Página principal

Ya estamos casi casi acabando, tenemos ya nuestra API básica, nuestras funciones, nuestras llamadas, todo.

Pero claro, nuestro root sigue devolviendo un json, ni es estético ni es sencillo ni tiene buenas prácticas. Lo correcto será que creemos un index.html y llamemos dicho archivo en el root.

Yo he creado este pequeño html de 50 líneas básandome en una plantilla del W3Schools.

<!DOCTYPE html>
<html>
    <head>
        <title>The Shin Chan API - @fcoterroba</title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3.css">
        <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Raleway">
        <style>
        body,h1,h2{font-family: "Raleway", sans-serif}
        body, html {height: 100%}
        p {line-height: 2}
        .bgimg {
        min-height: 100%;
        background-position: center;
        background-size: cover;
        }
        .bgimg {background-image: url("https://preview.redd.it/7fx1jell8p551.png?auto=webp&s=8ff53edc7ff4752ca0262c8a58f2d0a7efbbad61")}
        </style>
    </head>
    <body>

        <header class="w3-display-container w3-wide bgimg w3-grayscale-min" id="home">
            <div class="w3-display-middle w3-text-blue w3-center" style="background-color: white;">
                <h1 class="w3-jumbo">Shin Chan API</h1>
                <h2>The free Shin Chan API</h2>
                <h2><b>Created by @fcoterroba</b></h2>
            </div>
        </header>

        <div class="w3-container w3-padding-64 w3-pale-blue w3-grayscale-min" id="us">
            <div class="w3-content">
                <h1 class="w3-center w3-text-grey"><b>Just call it</b></h1>
                <img class="w3-round" src="https://images5.alphacoders.com/116/1166283.jpg" style="width:100%;margin:32px 0">
                <p><i>Get the full name, age and picture of your favourite characters.</i>
                </p><br>
                <p class="w3-center"><a href="#" class="w3-button w3-black w3-round w3-padding-large w3-large">Documentation</a></p>
            </div>
        </div>

    </body>
</html>

Una vez que tengamos el html, simplemente importamos la función FileResponse de starlette.responses y lo devolvemos usando dicha función.

from starlette.responses import FileResponse 

@app.get("/")
async def root():
    return FileResponse('index.html')

5️ QUINTO PASO 5️⃣ Generar documentación

Toda API que se precie requiere una documentación a medida y en eso FastAPI también se lleva un muy buen punto a favor.

Por defecto, esta librería genera dos documentaciones muy limpias y bonitas

Una de ellas está en /redoc y la otra, algo más clásica, en /docs.

Puedes entrar al repositorio de dicha API en mi GitHub!

🏁 FIN DEL POST 🏁

Y esto ha sido todo por hoy. Gracias por llegar hasta el final, espero que os haya servido y gustado. Nos vemos pronto!

Podéis contribuir económicamente mediante Paypal. Toda cantidad es bien recibida! 🙂

Espero también que tengáis una genial semana y nos vemos por aquí dentro de poquito! Un saludo y recuerda seguirme en las redes como TwitterFacebookInstagram, GitHub, LinkedIn y ahora también en TikTok. 🤟🏻

fuentes: Xataka.com, AWS.amazon.com, sngular.com, coffeebytes.dev, w3schools.com

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *