10분 동안 Python에서 AWS S3로 아카이브 보관소 가져오기

18082 단어 awspythonclouds3
S3 es un servicio excelente que permite almacenar y recuperar cantidades ilimitadas de información desde cualquier parte del mundo, es una de las alternativas más atractivas si no es la mejor cuando se trata de lagos de datos y es que S3 puede almacenar cualquier tipo de archivo, tiene muchas capacidades como las de encriptación hasta seguridad para accesos en todos los niveles, puede almacenar logs hasta 포괄적인 웹사이트 estáticas.

La unidad de almacenamiento son denominados objetos, cada objeto puede pesar hasta 5TB.

AWS S3 almacena los objetos en un contenedor al cual se le denomina "Bucket", el cual puede almacenar de forma ilimitada un numero de objetos. Los nombres de los buckets son únicos de forma global, es decir no hay otra cuenta de AWS que pueda tener el mismo nombre de un bucket.

Python(Boto3)을 통해 AWS SDK를 사용하는 경우 다음과 같은 질문에 대한 API 호출: put_object, copy, copy_object, upload_file, upload_fileobj.

Dicho lo anterior, algunas formas para subir archivos en S3 son:

1. AWS S3를 사용하는 단일 문서 보관소, desde la consola de administración es posible subir un objeto hasta los 160GB.


2. Cargar un objeto en una sola operation usando AWS CLI: entre las operaciones diponibles estan:

  • cp - 복사

  • mv-무버

  • sync-Sincronizar

  • aws s3 cp "video2.mp4" "s3://bucket-test-uploads"
    

    3. AWS SDK, REST API를 사용하는 유일한 작업 대상인 Cargar un objeto: con una operation PUT se puede subir un objeto hasta 5GB. En esta función abrimos el archivo en memoria e invocamos la función put_object al cual le pasamos los datos del archivo, el nombre y el bucket de destino, finalmente imprimimos la respuesta o en caso de haber una excepción capturarla.

    def put_object(self, s3_client):
        try:
            with open(self.file, 'rb') as fd:
                response = s3_client.put_object(
                    Bucket=self.bucket,
                    Key=self.key,
                    Body=fd
                )
            print(json.dumps(response, sort_keys=True, indent=4))
            print("Put Object exitoso")
            return True
        except FileNotFoundError:
            print("Archivo no encontrado")
            return False
        except Exception as e:
            print(str(e))
            return False
    
    


    4. Cargar un object en partes usando los AWS SDK, REST API o AWS CLI con la API 멀티파트 업로드, es 가능한 subir archivos hasta 5TB.
    hemos creado la función multipart_upload, donde iniciamos el proceso de carga y obteniendo el UploadId

    def multipart_upload(file, key, bucket, chunk_size, processes):
    
        upload_id = start_upload(bucket, key)
        print(f'Starting upload: {upload_id}')
    


    Abrimos el archivo en modo lectura en memoria, y definimos una cola para paralelizar procesos, cada parte debe estar entre 5MB y 100Mb

        file_upload = open(file, 'rb')
        part_procs = []
        proc_queue = multiprocessing.Queue()
        queue_returns = []
        chunk_size = (chunk_size * 1024) * 1024
        part_num = 1
        chunk = file_upload.read(chunk_size)
    
    


    Iteramos cada 5MB y los vamos metiendo a la cola, en esta sección añadimos el método add_part, el cual es el encargado de subir una parte del archivo al S3.

        while len(chunk) > 0:
            proc = multiprocessing.Process(target=add_part, args=(
                proc_queue, chunk, bucket, key, part_num, upload_id))
            part_procs.append(proc)
            part_num += 1
            chunk = file_upload.read(chunk_size)
    


    Realiza agrupación de procesamiento según número de processs simultáneos, por ejemplo, un archivo de 421MB, tendrá 85 partes de 5MB aproximadamente. Como resultado se tendrá 43 ejecuciones con 2 procesos simultáneos, en la última ejecución parte tendré 1 parte

        part_procs = [part_procs[i * processes:(i + 1) * processes]
                      for i in range((len(part_procs) + (processes - 1)) //   processes)]
    


    Ejecutamos cada "n"process en simultaneo y guardamos los resultados. Ordenamos la lista basada en los 'PartNumber' los cuales son los resultados de carga por cada parte, para finalmente completar la carga con el método end_upload

        for i in range(len(part_procs)):
            for p in part_procs[i]:
                p.start()
            for p in part_procs[i]:
                p.join()
            for p in part_procs[i]:
                queue_returns.append(proc_queue.get())
    
        queue_returns = sorted(queue_returns, key=lambda i: i['PartNumber'])
        response = end_upload(
            bucket, key, upload_id, queue_returns)
    print(json.dumps(response, sort_keys=True, indent=4))
    


    Si todo cargo bien veremos lo siguientes resultados:



    5. 보너스: Cargar un objeto en partes usando upload_file este método es manejado por S3TransferManager.
    Esto significa que automáticamente manejará las cargas multiparte por nosotros, si es necesario. put_object 실현 방법은 S3의 저수준 API를 지시합니다. No maneja cargas multiparte por nosotros. Intentará enviar todo en una sola solicitud

          try:
                s3_client.upload_file(self.file, self.bucket, self.key)
                print("Subida exitosa")
                return True
            except FileNotFoundError:
                print("Archivo no encontrado")
                return False
            except Exception as e:
                print(str(e))
                return False
    


    Un detalle importe, como buena práctica estamos usando una variable del perfil el ambiente que tengamos a AWS:

    session = boto3.Session(profile_name='aadev')
    Un ejempplo para la invocacion seria el siguiente
    



    if __name__ == '__main__':
        s3_client = session.client('s3')
        obj = S3Uploader(r'ruta\video2.mp4',
                         "video2.mp4", "aa-dev-test123", 5, 3)
        #Carga de archivos multiparte
        multipart_upload(obj.file, obj.key, obj.bucket,
                         obj.chunk_size, obj.processes)
        #Carga de archivos con upload_file                      
        obj.upload_to_aws(s3_client)
        print(obj)
    


    Y eso es todo por ahora, he querido compartir algunas de las formas con las que se pueden subir archivos en s3 y a esto se nos abre una gamma de posibles casos de usos, el codigo es mejorable. 하스타 라 프록시마!
    Si deseas ver más contenido puedes verlo en mi sitio: bigdateros.com

    La url del repositorio se encuentra en: https://github.com/bigdateros/AWS-S3

    좋은 웹페이지 즐겨찾기