Email

Tutorial de Python: cómo ImgPage te permite subir fotos de 25 MB a S3 y Cloud Files con solo un email

Este artículo está escrito por Paul Finn. Paul es desarrollador de Python en Portsmouth (New Hampshire), propietario de un negocio (http://route3software.com/) y entusiasta de la cerveza (https://hoppypress.com/beer-art). Sigue su blog en http://www.pfinn.net/, sus tuits en @paulfinn y su código en https://github.com/pfinn
Imagen para Tutorial de Python: cómo ImgPage te permite subir fotos de 25 MB a S3 y Cloud Files con solo un email

Este artículo está escrito por Paul Finn. Paul es desarrollador de Python en Portsmouth (New Hampshire), propietario de un negocio (http://route3software.com/) y entusiasta de la cerveza (https://hoppypress.com/beer-art). Sigue su blog en http://www.pfinn.net/, sus tuits en @paulfinn y su código en https://github.com/pfinn

Mis proyectos de desarrollo web favoritos siempre consisten en crear una herramienta en torno a una API recién descubierta y desde hace tiempo me encanta Mailgun. Su API no solo resuelve una de las tareas más difíciles de hacer bien (el análisis de emails), sino que lo hace de maravilla. Es un gran ejemplo de lo que debería ser una API moderna y fácil de usar para el equipo de desarrollo: es RESTful, resuelve un problema real, tiene una documentación sólida y es rápida de implementar.

Creación de una aplicación de alojamiento y subida de imágenes fácil de usar

Recurrí a Mailgun hace unas semanas cuando decidí crear un host de imágenes rápido que pudiera recibir imágenes por email y no dependiera de un proceso tradicional de subida en el lado del cliente. Muchos de los smartphones de hoy en día no cuentan con asistencia nativa para las subidas en el navegador, por lo que puede ser un poco complicado encontrar una manera de sacar las fotos del teléfono y compartirlas con solo un enlace (y sin pasar por ninguna red social).

He creado ImgPage (“Image Page”) para resolver ese problema: solo tienes que adjuntar una foto (o varias) a un email y enviarlo a inbox@imgpage.com. Espera unos segundos y recibirás una respuesta por email de ImgPage con un enlace único a una página limpia y ordenada en la que solo aparecerán tus imágenes, como se muestra a continuación.

A continuación, muestro un código de muestra simplificado sobre cómo ImgPage utiliza Mailgun para subir estas imágenes a la nube.

Análisis de emails entrantes con la API de enrutamiento de Mailgun

Después de crear un repositorio de git para ImgPage, el siguiente paso fue crear la bandeja de entrada inbox@imgpage.com ruta dentro de Mailgun. Una ruta es como Mailgun llama a la lógica que indica a su sistema qué hacer con cada email entrante que recibe. Para ImgPage, configuré Mailgun para analizar cada email entrante recibido en inbox@imgpage.com y enviar los detalles a mi servidor mediante POST.

                                

                                        requests.post("https://api.mailgun.net/v2/routes", 
    auth=("api", os.environ.get("MAILGUN_KEY", "your-api-key"))), 
    data=MultiDict([("description", "ImgPage Inbox Processing"), 
                    ("expression", "match_recipient('inbox@imgpage.com')"), 
                    ("action", "forward('http://imgpage.com/mailgun-endpoint/')"), 
                    ("action", "stop()")
                  ]))
                                
                            

Un truco genial de Mailgun: no te limitas a buscar coincidencias solo en el destinatario de email. Puedes buscar coincidencias en los encabezados de email, como la línea de asunto, y también usar expresiones regulares. Puedes crear rutas mediante programación, como se ha demostrado anteriormente, o usar el panel de control de Mailgun tras iniciar sesión. Aquí tienes todas las especificaciones de la API de análisis de emails entrantes.

En lo que respecta a los adjuntos, Mailgun hace el trabajo pesado por nosotros y enviará mediante POST la información que necesitamos sobre todos y cada uno de los adjuntos de hasta 25 MB (en realidad, el tamaño máximo es 1 o 2 KB menor a 25 MB, ya que se debe reservar espacio para los encabezados de email). En este ejemplo simplificado, compruebo la solicitud para verificar que hay al menos un adjunto y que el adjunto tiene una extensión de archivo de foto común que esperamos (si no es así, devuelve un error HTTP 415).

@app.route(‘/mailgun-endpoint’, methods=[‘POST’]) def mailgun_endpoint(): if(len(request.files) > 0): for attachment in request.files.values(): file_name, file_extension = os.path.splitext(attachment.filename) if file_extension.lower() not in [‘.jpg’, ‘.gif’, ‘.png’, ‘.bmp’]: abort(415) #Tipo de medios no admitido

                                

                                        @app.route('/mailgun-endpoint', methods=['POST'])
    def mailgun_endpoint(): 
      if(len(request.files) > 0): 
         for attachment in request.files.values(): 
           file_name, file_extension = os.path.splitext(attachment.filename) 
           if file_extension.lower() not in ['.jpg', '.gif', '.png', '.bmp']: 
             abort(415) #Unsupported Media Type
                                
                            

Subida de fotos a Rackspace Cloud Files & Amazon S3

Ahora tenía varias opciones de almacenamiento fiable en la nube, siendo Amazon S3 la más popular. Siempre estoy dispuesto a probar un nuevo servicio y aprender una nueva API, así que también decidí darle una oportunidad a Rackspace Cloud Files (Rackspace ha adquirido Mailgun recientemente, por lo que con el tiempo probablemente crearán algunas integraciones nativas). Tenía mucha experiencia con S3 y me sorprendió gratamente lo fácil que fue empezar con Cloud Files. Los conceptos básicos, como los contenedores y los buckets, son bastante similares entre ambos servicios.

                                

                                    image_attachment.public_uri() 
    'http://c1234.cdn.cloudfiles.rackspacecloud.com/6a8f43...ab3cb7.jpg'
                                
                            

En el caso de ImgPage, es importante que todo lo que esté dentro del contenedor de imágenes sea accesible públicamente con una URL única. Tras la subida, puedes solicitar el URI público desde Cloud Files.

Como puedes ver, es muy sencillo y fácil trabajar con Cloud Files. Si quieres seguir utilizando Amazon S3, aquí tienes cómo podrías gestionar la subida de los adjuntos con la biblioteca boto de Python.

                                

                                    from boto.s3.key import Key 
from boto.s3.connection import S3Connection 

conn = S3Connection(my-access-key, my-secret-key) 
bucket = conn.get_bucket('images') 
key = Key(bucket) 
key = ('%s%s') % (str(uuid.uuid4()), file_extension) 
key.set_contents_from_filename(attachment.filename)
                                
                            

(Cuando hayas terminado de gestionar el POST, Mailgun espera ver una respuesta HTTP 200 OK. De lo contrario, esta acción quedará registrada como un error en tus registros de Mailgun).

Conclusión

El enrutamiento de emails entrantes y el análisis de adjuntos es muy fácil con Mailgun. Pude combinar la coincidencia de destinatarios y las acciones de reenvío de Mailgun tanto con Cloud Files como con Amazon S3 para crear ImgPage. Si no hubiera tenido Mailgun, probablemente ni siquiera habría abordado este proyecto, debido a las dificultades de analizar el email entrante. Mailgun tiene toda mi aprobación por resolver un problema difícil y crear una API estable y bien documentada para acompañarlo.