Ahora que tengo la idea general escrita, voy a avanzar con la ejecución de los primeros pasos del proyecto. En principio necesito un repositorio, así que les voy a mostrar una manera práctica que encontré mediante PyCharm.
GitHub y PyCharm
Primero armo un proyecto en el IDE, lo de siempre:
Luego en el menú superior voy a VSC y toco "Share Project on GitHub". Los campos se explican por sí mismos.
Una vez le doy a share, me pedirá que haga un commit inicial. Esto es necesario para inicializar el branch:
Con esto, se generará un proyecto en nuestra cuenta. Este es el repositorio que voy a utilizar.
Hola mundo (version API)
Siempre hay que empezar desde lo más simple hasta alcanzar un punto de complejidad, el cual no deja de ser un conjunto funcional de cosas simples interactuando entre ellas.
Por eso, luego de importar los paquetes correspondientes, este es mi hola mundo en FastAPI:
from fastapi import FastAPI, status
app = FastAPI()
@app.get('/', status_code=status.HTTP_200_OK)
async def home():
return "hello api!"
Debemos correr esto con la configuración de Uvicorn que había comentado en el artículo anterior:
Y si vemos un "hello api!" en nuestra dirección http://127.0.0.1:8000/, ¡entonces estamos arriba!
Persistencia, o el arte de guardar cosas
La parte más importante de este proyecto va a ser la persistencia: esos usuarios registrados con sus votos deben guardarse en algún lugar.
En el proyecto de la pizzería, utilicé Postgresql y no me terminó de convencer la cantidad de configuración que debía implementar. Quería algo más sencillo y ligero, por lo cual mi opción luego de meditar un buen rato será SQLite.
Por otro lado, para ORM voy a utilizar SQLModel, librería que desarrolló el mismo creador de FastAPI, por lo cual la compatibilidad es absoluta.
Dicho esto, procedo a implementar mi archivo que tendrá las instrucciones para armar la BD:
from sqlmodel import create_engine
import os
BASE_DIR = os.path.dirname(os.path.realpath(__file__))
conn_str = 'sqlite:///' + os.path.join(BASE_DIR, 'color_choice.db')
engine = create_engine(conn_str, echo=True)
Luego voy a crear el archivo que permite ejecutar la creación de mi nueva base de datos (create_db.py):
from sqlmodel import SQLModel
from storage.db import engine
print("CREATING DB.......")
SQLModel.metadata.create_all(engine)
SQLModel utiliza el objeto engine, el cual contiene la información de la BD que vamos a crear, y luego genera la misma. Eso nos da como resultado una BD vacía a modo de archivo que encontraremos en el mismo directorio raíz del proyecto llamada color_choice.db.
Finalmente debemos crear un objeto Session para manejar las transacciones en cada endpoint, por lo cual volvemos a main.py y agregamos:
from storage.db import engine
session = Session(bind=engine)
Los modelos
Para SQLModel, los modelos son la representación de las tablas en nuestra base de datos. De momento no tenemos ninguno, por eso la BD está vacía. Vamos a generar los modelos que nos servirán para gestionar los votos en models.py:
from sqlmodel import SQLModel, Field
from typing import Optional
class Color(SQLModel, table=True):
color_id: int = Field(default=None, primary_key=True)
color: str
class Vote(SQLModel, table=True):
user_id: str = Field(default=None, primary_key=True)
color_id_selected: Optional[int] = Field(default=None, foreign_key="color.color_id")
color_voted: bool = Field(default=False)
Al principio pensé en mantener siempre los mismos colores, pero me di cuenta que podía perder escalabilidad. Por lo tanto, decidí crear una tabla para color y otra con los votos que tenga una clave foránea a la anterior. Entonces si un día decido agregar un color, o incluso cambiarle el nombre a uno existente, puedo hacerlo.
Recrear la BD
Ahora que tenemos los modelos armados, hay que volver a generar la BD, pero en el archivo create_db.py vamos a importarlos:
import models
No importa que nuestro IDE diga que el módulo no está en uso, porque en el momento en el que corra create_all(engine) va a considerar automáticamente las clases del modelo. Esto no ocurre por arte de magia, sino que genera tablas de las clases que hereden de SQLModel.
Cuando miremos nuestra BD, ahora tendremos dos tablas: color y vote.
Conclusiones
Todo lo que hicimos constituye un gran avance. Con el proyecto y la BD armados, ya podemos trabajar en los endpoints y la interacción con el usuario. El código, como siempre, pueden encontrarlo en el repositorio del proyecto.
Top comments (0)