Email

Tutoriel Python : comment ImgPage vous permet d’importer des photos de 25 Mo sur S3 et Cloud Files avec un simple email

Cet article a été écrit par Paul Finn. Paul est un développeur Python basé à Portsmouth (New Hampshire), chef d'entreprise (http://route3software.com/) et amateur de bière (https://hoppypress.com/beer-art). Suivez son blog sur http://www.pfinn.net/, ses tweets sur @paulfinn et son code sur https://github.com/pfinn
Image pour Tutoriel Python : comment ImgPage vous permet d’importer des photos de 25 Mo sur S3 et Cloud Files avec un simple email

Cet article a été écrit par Paul Finn. Paul est un développeur Python basé à Portsmouth (New Hampshire), chef d’entreprise (http://route3software.com/) et amateur de bière (https://hoppypress.com/beer-art). Suivez son blog sur http://www.pfinn.net/, ses tweets sur @paulfinn et son code sur https://github.com/pfinn

Mes projets de développement web préférés impliquent toujours de créer un outil autour d’une API récemment découverte, et je suis un grand fan de Mailgun depuis un certain temps déjà. Non seulement leur API s’attaque à l’une des choses les plus difficiles à maîtriser, l’analyse d’emails, mais elle le fait très bien. C’est un excellent exemple de ce que devrait être une API moderne et adaptée aux équipes de développement : elle est RESTful, résout un problème réel, dispose d’une documentation solide et permet de démarrer rapidement.

Créer une application d’hébergement et d’importation d’images facile à utiliser

Je me suis tourné vers Mailgun il y a quelques semaines lorsque j’ai décidé de créer un hébergeur d’images rapide, capable de recevoir des images par email et de ne pas dépendre d’un processus d’importation traditionnel côté client. De nombreux smartphones actuels n’ont pas de support natif pour les importations dans le navigateur. Il peut donc être un peu difficile de trouver un moyen d’extraire des photos de votre téléphone et de les partager avec un simple lien (en contournant les réseaux sociaux).

J’ai créé ImgPage (« Image Page ») pour résoudre ce problème : il suffit de joindre une ou plusieurs photos à un email et de l’envoyer à l’adresse inbox@imgpage.com. Patientez quelques secondes et vous recevrez une réponse par email d’ImgPage avec un lien unique vers une page épurée et sans superflu, présentant uniquement votre ou vos images comme ci-dessous.

Ci-dessous, je vais vous montrer un exemple de code simplifié sur la façon dont ImgPage utilise Mailgun pour importer ces images dans le cloud.

Analyser les emails entrants à l’aide de l’API Mailgun Routes

Après avoir créé un dépôt git pour ImgPage, l’étape suivante a consisté à créer la boîte de réception inbox@imgpage.com route dans Mailgun. Une route est le terme utilisé par Mailgun pour désigner la logique indiquant à son système quoi faire de chaque email entrant reçu. Pour ImgPage, j’ai configuré Mailgun afin d’analyser chaque email entrant reçu sur inbox@imgpage.com et d’envoyer les détails en POST vers mon serveur.

                                

                                        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()")
                  ]))
                                
                            

Une fonctionnalité intéressante de Mailgun : vous n’êtes pas limité à une simple correspondance avec les destinataires de l’email. Vous pouvez faire correspondre des en-têtes d’email comme l’objet d’email et utiliser également des expressions régulières. Vous pouvez créer des routes par programmation, comme illustré ci-dessus, ou bien depuis le tableau de bord Mailgun après vous être connecté. Voici l’intégralité des spécifications de l’API d’analyse d’emails entrants.

En ce qui concerne les pièces jointes, Mailgun fait le plus gros du travail pour nous et envoie via POST les informations dont nous avons besoin sur l’ensemble des pièces jointes jusqu’à 25 Mo (en réalité, la taille max. est de 1 ou 2 Ko de moins que 25 Mo, car de l’espace doit être réservé pour les en-têtes d’email). Dans cet exemple simplifié, je vérifie la requête pour m’assurer qu’il y a au moins une pièce jointe et qu’elle possède une extension de fichier photo courante que nous attendons (sinon, cela renvoie une erreur 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) #Type de média non pris en charge

                                

                                        @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
                                
                            

Importer des photos vers Rackspace Cloud Files et Amazon S3

J’avais alors quelques options pour un stockage cloud fiable, la plus populaire étant Amazon S3. Je suis toujours prêt à essayer un nouveau service et à apprendre une nouvelle API. J’ai donc décidé de donner aussi sa chance à Rackspace Cloud Files (Rackspace a récemment acquis Mailgun, ils vont donc probablement développer des intégrations natives au fil du temps). J’avais beaucoup d’expérience avec S3 et j’ai été agréablement surpris de voir à quel point il était facile de démarrer avec Cloud Files. Les concepts de base, comme les conteneurs et les buckets, sont assez similaires entre les deux services.

                                

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

Dans le cas d’ImgPage, il est important que tout ce qui se trouve dans le conteneur d’images soit accessible publiquement avec une URL unique. Après l’importation, vous pouvez demander l’URI publique à Cloud Files.

Comme vous pouvez le constater, il est simple et facile de travailler avec Cloud Files. Si vous préférez en rester à Amazon S3, voici comment vous pouvez gérer l’importation des pièces jointes à l’aide de la bibliothèque Python boto.

                                

                                    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)
                                
                            

(Lorsque vous avez terminé de traiter le POST, Mailgun s’attend à recevoir une réponse HTTP 200 OK. Dans le cas contraire, cette action sera enregistrée comme une erreur dans vos journaux Mailgun.)

Conclusion

Le routage des emails entrants et l’analyse des pièces jointes sont un jeu d’enfant avec Mailgun. J’ai pu associer les actions de correspondance de destinataire et de transfert de Mailgun avec Cloud Files et Amazon S3 pour créer ImgPage. Sans Mailgun, je ne me serais probablement pas attaqué à ce projet pour commencer, en raison des difficultés liées à l’analyse d’emails entrants. Je tire mon chapeau à Mailgun pour avoir résolu un problème difficile et créé une API stable et bien documentée pour l’accompagner.