Utilizando un "faker" para guardar archivos (livianos) en memoria
En algunos proyectos vamos a encontrarnos con algunas particularidades cuando manejamos servicios en la nube (como AWS S3 por ejemplo) debemos jugar mucho con archivos en memoria ya que el almecenamiento local para archivos pequeños se evita, en este ejemplo veremos como implementar un codigo sencillo en donde generaremos un pdf apartir de una imagen y la guardaremos en memoria para posteriormente guardarla en la nube sin utilizar el disco local
Para el ejemplo usaremos la libreria img2pdf la cual permite convertir jpg a pdf, haremos primero la implementacion segun la documentacion generando el archivo pdf escribiendolo en disco y posteriormente realizaremos el ejemplo guardandolo en memoria
import img2pdf
with open("name.pdf","wb") as f:
f.write(img2pdf.convert('test.jpg'))
En el anterior codigo convertimos un archivo llamado "test.jpg" a un archivo "name.pdf" y lo escribimos en disco, este codigo funciona, pero para nuestro requerimiento no queremos guardar el resultado de convertir la imagen a pdf en disco ya que el archivo va ir directamente a la nube por lo tanto debemos guardarlo en memoria, para ello nos apoyaremos de la clase BytesIO la cual es una clase que nos permite leer y escribir en memoria, explicaremos a continuacion el siguiente codigo
from io import BytesIO
from typing import BinaryIO
import img2pdf
def convert_jpg_to_pdf(self, image_jpg: BinaryIO) -> BinaryIO:
pdf_file_bytes_io = BytesIO()
img_to_pdf: bytes = img2pdf.convert(image_jpg)
pdf_file_bytes_io.write(img_to_pdf)
pdf_file_bytes_io.seek(0)
return pdf_file_bytes_io
En el ejemplo iniciamos creando un metodo donde recibiremos la imagen como parametro, esto por que es una simulacion posiblemente esta imagen viene de alguna peticion por algun request
def convert_jpg_to_pdf(self, image_jpg: BinaryIO) -> BinaryIO:
entrando al metodo vemos que creamos una instancia de BytesIO
pdf_file_bytes_io = BytesIO()
seguido convertimos la imagen en pdf (utilizando la libreria img2pdf) lo cual nos devuelve el resultado en bytes
img_to_pdf: bytes = img2pdf.convert(image_jpg)
ahora utlizando el objeto de BytesIO escribimos en memoria llamando al metodo write() ya que mas adelante necesitaremos utilizar tambien el metodo .read() para que se lleve a la nube
pdf_file_bytes_io.write(img_to_pdf)
cuando escribimos en memoria debemos de llamar al metodo seek, esto es muy importante y seguramente les ahorrara tiempo buscando algun bug y finalmente retornanos el objeto BytesIO que contiene el pdf almacenado en memoria el cual ahora podemos enviarlo a cualquier servidor cloud
pdf_file_bytes_io.seek(0)
return pdf_file_bytes_io
Esta estrategia nos ayuda cuando se quiere evitar guardar informacion en local o en disco, pero es importante saber que estos archivos deben ser livianos ya que con archivos mas pesados debemos utilizar otros metodos.