Administración de archivos con AWS S3, Python y Flask

AWS S3 es un servicio que nos permite administrar fácilmente el almacenamiento de archivos en la nube. En este artículo, administraremos las cargas de archivos con Python y Flask

Introducción

Uno de los factores clave que impulsan el crecimiento de la tecnología son los datos. Los datos se han vuelto más importantes y cruciales en las herramientas que se construyen a medida que avanza la tecnología. Se ha convertido en el factor impulsor del crecimiento de la tecnología, cómo recopilar, almacenar, proteger y distribuir datos.

Este crecimiento de datos ha llevado a un aumento en la utilización de la arquitectura en la nube para almacenar y administrar datos y, al mismo tiempo, minimizar las molestias necesarias para mantener la coherencia y la precisión. Como consumidores de tecnología, generamos y consumimos datos y esto ha requerido el requisito de sistemas elaborados para ayudarnos a administrar los datos.

La arquitectura de la nube nos brinda la capacidad de cargar y descargar archivos desde múltiples dispositivos siempre que estemos conectados a Internet. Y eso es parte de lo que AWS nos ayuda a lograr a través de los depósitos de S3.

¿Qué es S3?

Servicio de almacenamiento simple de Amazon (S3) es una oferta de Amazon Web Services (AWS) que permite a los usuarios almacenar datos en forma de objetos . Está diseñado para atender a todo tipo de usuarios, desde empresas hasta pequeñas organizaciones o proyectos personales.

S3 se puede usar para almacenar datos que van desde imágenes, videos y audio hasta copias de seguridad o datos estáticos de sitios web, entre otros.

Un depósito de S3 es un recurso de almacenamiento con nombre que se utiliza para almacenar datos en AWS. Es similar a una carpeta que se utiliza para almacenar datos en AWS. Los cubos tienen nombres únicos y, según el nivel y el precio, los usuarios reciben diferentes niveles de redundancia y accesibilidad a diferentes precios.

Los privilegios de acceso a los depósitos de S3 también se pueden especificar a través de la consola de AWS, la herramienta de la CLI de AWS o mediante las API y bibliotecas proporcionadas.

¿Qué es Boto3?

Boto3 es un kit de desarrollo de software (SDK) proporcionado por AWS para facilitar la interacción con las API de S3 y otros servicios como Nube informática elástica (EC2). Con Boto3, podemos enumerar todos los depósitos de S3, crear instancias de EC2 o controlar cualquier cantidad de recursos de AWS.

¿Por qué usar S3?

Siempre podemos aprovisionar nuestros propios servidores para almacenar nuestros datos y hacerlos accesibles desde una variedad de dispositivos a través de Internet, entonces, ¿por qué deberíamos usar el S3 de AWS? Hay varios escenarios en los que resulta útil.

Primero, AWS S3 elimina todo el trabajo y los costos involucrados en la construcción y mantenimiento de servidores que almacenan nuestros datos. No tenemos que preocuparnos por adquirir el hardware para alojar nuestros datos o el personal necesario para mantener la infraestructura. En su lugar, podemos centrarnos únicamente en nuestro código y garantizar que nuestros servicios estén en las mejores condiciones.

Al usar S3, podemos aprovechar las impresionantes capacidades de rendimiento, disponibilidad y escalabilidad de AWS. Nuestro código podrá escalar de manera efectiva y funcionar bajo cargas pesadas y estará altamente disponible para nuestros usuarios finales. Logramos esto sin tener que construir o administrar la infraestructura detrás de esto.

AWS ofrece herramientas para ayudarnos con el análisis y la auditoría, así como con la administración y los informes sobre nuestros datos. Podemos ver y analizar cómo se accede a los datos en nuestros cubos o incluso replicar los datos en otras regiones para mejorar el acceso de los usuarios finales a los datos. Nuestros datos también están encriptados y almacenados de forma segura para que estén seguros en todo momento.

A través de AWSLambda también podemos responder a los datos que se cargan o descargan de nuestros cubos S3 y responder a los usuarios a través de alertas configuradas o informes para un experiencia más personalizada e instantánea como se espera de la tecnología.

Configuración de AWS

Para comenzar con S3, debemos configurar una cuenta en AWS o iniciar sesión en una cuenta existente.

También necesitaremos configurar la herramienta AWS CLI para poder interactuar con nuestros recursos desde la línea de comandos, que está disponible para Mac, Linux y Windows.

Podemos instalarlo ejecutando:

1
$ pip install awscli

Una vez que se configura la herramienta CLI, podemos generar nuestras credenciales en el menú desplegable de nuestro perfil y usarlas para configurar nuestra herramienta CLI de la siguiente manera:

1
$ aws configure

Este comando nos pedirá que proporcionemos nuestra ID de clave de acceso, Clave de acceso secreta, regiones predeterminadas y formatos de salida. Se pueden encontrar más detalles sobre la configuración de la herramienta CLI de AWS aquí.

Nuestra aplicación - FlaskDrive

Configuración

Construyamos una aplicación Flask que permita a los usuarios cargar y descargar archivos hacia y desde nuestros depósitos S3, alojados en AWS.

Usaremos el SDK de Boto3 para facilitar estas operaciones y construiremos un front-end simple para permitir a los usuarios cargar y ver los archivos alojados en línea.

Es recomendable usar un entorno virtual cuando se trabaja en proyectos de Python, y para este usaremos la herramienta Pipenv para crear y gestionar nuestro entorno. Una vez configurado, creamos y activamos nuestro entorno con Python3 de la siguiente manera:

1
2
$ pipenv install --three
$ pipenv shell

Ahora necesitamos instalar Boto3 y Flask ​​que son necesarios para construir nuestra aplicación FlaskDrive de la siguiente manera:

1
2
$ pipenv install flask
$ pipenv install boto3

Implementación

Después de la configuración, necesitamos crear los depósitos para almacenar nuestros datos y podemos lograrlo dirigiéndonos a la consola de AWS y eligiendo S3 en el menú Servicios.

Después de crear un depósito, podemos usar la herramienta CLI para ver los depósitos que tenemos disponibles:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
$ aws s3api list-buckets
{
    "Owner": {
        "DisplayName": "robley",
        "ID": "##########################################"
    },
    "Buckets": [
        {
            "CreationDate": "2019-09-25T10:33:40.000Z",
            "Name": "flaskdrive"
        }
    ]
}

Ahora crearemos las funciones para cargar, descargar y listar archivos en nuestros cubos S3 usando el SDK de Boto3, comenzando con la función upload_file:

1
2
3
4
5
6
7
8
9
def upload_file(file_name, bucket):
    """
    Function to upload a file to an S3 bucket
    """
    object_name = file_name
    s3_client = boto3.client('s3')
    response = s3_client.upload_file(file_name, bucket, object_name)

    return response

La función upload_file toma un archivo y el nombre del depósito y carga el archivo dado a nuestro depósito S3 en AWS.

1
2
3
4
5
6
7
8
9
def download_file(file_name, bucket):
    """
    Function to download a given file from an S3 bucket
    """
    s3 = boto3.resource('s3')
    output = f"downloads/{file_name}"
    s3.Bucket(bucket).download_file(file_name, output)

    return output

La función download_file toma un nombre de archivo y un depósito y lo descarga a una carpeta que especifiquemos.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
def list_files(bucket):
    """
    Function to list files in a given S3 bucket
    """
    s3 = boto3.client('s3')
    contents = []
    for item in s3.list_objects(Bucket=bucket)['Contents']:
        contents.append(item)

    return contents

La función list_files se usa para recuperar los archivos en nuestro depósito S3 y enumerar sus nombres. Usaremos estos nombres para descargar los archivos de nuestros cubos S3.

Con nuestro archivo de interacción S3 en su lugar, podemos construir nuestra aplicación Flask para proporcionar la interfaz basada en web para la interacción. La aplicación será una aplicación Flask simple de un solo archivo con fines de demostración con la siguiente estructura:

1
2
3
4
5
6
7
8
9
.
├── Pipfile       # stores our application requirements
├── __init__.py
├── app.py        # our main Flask application
├── downloads     # folder to store our downloaded files
├── s3_demo.py    # S3 interaction code
├── templates
   └── storage.html
└── uploads       # folder to store the uploaded files

La funcionalidad central de nuestra aplicación Flask residirá en el archivo app.py:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
import os
from flask import Flask, render_template, request, redirect, send_file
from s3_demo import list_files, download_file, upload_file

app = Flask(__name__)
UPLOAD_FOLDER = "uploads"
BUCKET = "flaskdrive"

@app.route('/')
def entry_point():
    return 'Hello World!'

@app.route("/storage")
def storage():
    contents = list_files("flaskdrive")
    return render_template('storage.html', contents=contents)

@app.route("/upload", methods=['POST'])
def upload():
    if request.method == "POST":
        f = request.files['file']
        f.save(os.path.join(UPLOAD_FOLDER, f.filename))
        upload_file(f"uploads/{f.filename}", BUCKET)

        return redirect("/storage")

@app.route("/download/<filename>", methods=['GET'])
def download(filename):
    if request.method == 'GET':
        output = download_file(filename, BUCKET)

        return send_file(output, as_attachment=True)

if __name__ == '__main__':
    app.run(debug=True)

Esta es una aplicación Flask simple con 4 puntos finales:

  • El punto final /almacenamiento será la página de inicio donde mostraremos los archivos actuales en nuestro depósito S3 para descargar, y también una entrada para que los usuarios carguen un archivo en nuestro depósito S3,
  • El punto final /upload se usará para recibir un archivo y luego llamar al método upload_file() que carga un archivo en un depósito S3
  • El punto final /download recibirá un nombre de archivo y utilizará el método download_file() para descargar el archivo en el dispositivo del usuario.

Y finalmente, nuestra plantilla HTML será tan simple como:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<!DOCTYPE html>
<html>
  <head>
    <title>FlaskDrive</title>
  </head>
  <body>
    <div class="content">
        <h3>Flask Drive: S3 Flask Demo</h3>
        <p>Welcome to this AWS S3 Demo</p>
        <div>
          <h3>Upload your file here:</h3>
          <form method="POST" action="/upload" enctype=multipart/form-data>
            <input type=file name=file>
            <input type=submit value=Upload>
          </form>
        </div>
        <div>
          <h3>These are your uploaded files:</h3>
          <p>Click on the filename to download it.</p>
          <ul>
            {% for item in contents %}
              <li>
                <a href="/download/{{ item.Key }}"> {{ item.Key }} </a>
              </li>
            {% endfor %}
          </ul>
        </div>
    </div>
  </body>
</html>

Con nuestro código y carpetas configurados, comenzamos nuestra aplicación con:

1
$ python app.py

Cuando navegamos a http://localhost:5000/storage nos da la bienvenida la siguiente página de destino:

flask_drive_landing_1

Subamos ahora un archivo usando el campo de entrada y este es el resultado:

flask_drive_landing_2

Podemos confirmar la carga revisando nuestro tablero S3, y podemos encontrar nuestra imagen allí:

flask_drive_s3_dashboard

Nuestro archivo se cargó con éxito desde nuestra máquina al almacenamiento S3 de AWS.

En nuestra página de inicio de FlaskDrive, podemos descargar el archivo simplemente haciendo clic en el nombre del archivo y luego recibimos el mensaje para guardar el archivo en nuestras máquinas.

Conclusión

En esta publicación, hemos creado una aplicación Flask que almacena archivos en el S3 de AWS y nos permite descargar los mismos archivos desde nuestra aplicación. Usamos la biblioteca Boto3 junto con la herramienta AWS CLI para manejar la interacción entre nuestra aplicación y AWS.

Eliminamos la necesidad de tener nuestros propios servidores para manejar el almacenamiento de nuestros archivos y aprovechamos la infraestructura de Amazon para manejarlo por nosotros a través del Servicio de almacenamiento simple de AWS. Nos tomó poco tiempo desarrollar, implementar y hacer que nuestra aplicación esté disponible para los usuarios finales y ahora podemos mejorarla para agregar permisos, entre otras funciones.

El código fuente de este proyecto está disponible aquí en Github. ve).