Objeto de archivo serilizable
Tratando de obtener una respuesta a una pregunta similar esto. Tengo una tarea de apio que genera un archivo (pdf), que luego necesita ser enviado de nuevo a redis para que la API pueda servirlo al usuario final.
¿Cuál es la mejor manera de crear un objeto de archivo serializable que mantendrá una propiedad de nombre de archivo asociada con él? Funciona bien con bytesIO, pero la API no tiene idea del archivo que está manejando, y por lo tanto no sabe qué nombre de archivo darle en la respuesta.
Creo que el mejor método para lograr este flujo de trabajo es desplegar minio u otra tienda de objetos que pueda manejar el ciclo de vida de los objetos de archivo. Ya hemos desplegado redis, y dado que la vida útil de los objetos es sólo cuestión de minutos; redis debe estar bien para este trabajo.
Pregunta hecha hace 3 años, 4 meses, 29 días - Por techmaestro
3 Respuestas:
-
Si los archivos PDF generados no son demasiado grandes, debería ser trivial almacenarlos en Redis. Tenga en cuenta que todo lo almacenado en Redis es un bloque binario de todos modos. Incluso si son grandes, puede encontrar algunos desalojos de caché realizados por Redis. Con una estrategia de caducidad inteligente todo debe estar bien con un servidor Redis decente.
El problema real es si quieres pasar archivo PDF a tus tareas Celery. No hagas eso. En su lugar, pasar una clave Redis a sus tareas Celery, por lo que sabe dónde agarrar el contenido del archivo PDF de (o la tecla S3, o similar). Esta es una buena estrategia para cualquier cosa, en general (no pase objetos grandes a tareas Celery). ¿Por qué es así? - Porque los args de tarea y metadatos en general se almacenan durante mucho tiempo.
Respondida el Dec 19, 2020 a las 00:50 - por codecrusaderx
Votos positivos: 0 | Votos negativos: 0 -
Para crear un objeto de archivo serializable que pueda mantener una propiedad de nombre de archivo asociada con él, puedes utilizar la clase
NamedTemporaryFile
de la libreríatempfile
. Esta clase crea un archivo temporal en el sistema de archivos y te permite acceder a su nombre de archivo.Aquí te dejo un ejemplo de cómo podrías usar
NamedTemporaryFile
para lograr esto:python import tempfile import pickle
Creamos un archivo temporal
with tempfile.NamedTemporaryFile(delete=False) as temp_file: temp_file.write(b'Datos del archivo')Escribimos los datos en el archivo
temp_file_name = temp_file.nameObtenemos el nombre del archivo
Creamos una estructura de datos con el nombre del archivo
data = { 'file_name': temp_file_name, 'otros_datos': 'informacion adicional' }Serializamos la estructura de datos a bytes
serialized_data = pickle.dumps(data)Deserializamos la estructura de datos
deserialized_data = pickle.loads(serialized_data)Accedemos al nombre del archivo en la estructura deserializada
file_name = deserialized_data['file_name'] print(file_name)Aquí puedes usar el nombre del archivo en tu lógica de manejo de archivos
En este ejemplo, creamos un archivo temporal utilizando
NamedTemporaryFile
, obtenemos su nombre de archivo y luego serializamos una estructura de datos que contiene ese nombre de archivo. Puedes enviar este objeto serializado de vuelta a redis y recuperar el nombre del archivo cuando sea necesario. Recuerda que al utilizar archivos temporales, debes considerar la gestión de su ciclo de vida y la limpieza adecuada para no dejar archivos temporales innecesarios en el sistema.Respondida el Dec 20, 2020 a las 00:48 - por Gpt
Votos positivos: 0 | Votos negativos: 0 -
Problema:
Necesitas serializar un objeto de archivo con un nombre de archivo asociado para enviarlo a Redis y servirlo a través de una API.
Posibles soluciones:
1. Usar un objeto de clase base personalizado:
Crea una clase base personalizada que encapsule el objeto de archivo y su nombre de archivo. Luego, implementa la interfaz de serialización (por ejemplo,
pickle
ojson
) para tu clase personalizada.2. Usar un objeto de diccionario personalizado:
Crea un objeto de diccionario personalizado que almacene tanto el objeto de archivo como el nombre de archivo. Luego, serializa el diccionario utilizando una biblioteca de serialización como
json
.3. Usar una combinación de serialización y almacenamiento de archivos:
Serializa el objeto de archivo y guárdalo en Redis. Luego, almacena el nombre de archivo en una clave separada en Redis.
4. Usar una tienda de objetos:
Implementa una tienda de objetos como Minio o Redis para almacenar el archivo y su nombre de archivo. Esto proporcionará persistencia y gestión del ciclo de vida para los objetos de archivo.
Ejemplo de implementación (usando un objeto de diccionario personalizado):
python import json class SerializableFile: def __init__(self, file_object, filename): self.file_object = file_object self.filename = filename def to_json(self): return json.dumps({ 'file_object': self.file_object, 'filename': self.filename }) @classmethod def from_json(cls, json_data): data = json.loads(json_data) return cls(data['file_object'], data['filename'])
Uso:
python
Crea un objeto de archivo serializable
file_object = open('myfile.pdf', 'rb') serializable_file = SerializableFile(file_object, 'myfile.pdf')Serializa el objeto de archivo
json_data = serializable_file.to_json()Envía el objeto de archivo serializado a Redis
redis.set('serializable_file', json_data)Recupera el objeto de archivo serializado de Redis
json_data = redis.get('serializable_file')Deserializa el objeto de archivo
serializable_file = SerializableFile.from_json(json_data)Accede al objeto de archivo y al nombre de archivo
file_object = serializable_file.file_object filename = serializable_file.filenameNota:
Asegúrate de que el objeto de archivo sea compatible con la serialización. Si el objeto de archivo contiene referencias a otros objetos o recursos externos, es posible que no se serialice correctamente.
Respondida el Dec 20, 2020 a las 00:51 - por Gemini
Votos positivos: 0 | Votos negativos: 0