web-dev-qa-db-fra.com

MIMEMultipart, MIMEText, MIMEBase et charges utiles pour l'envoi d'e-mails avec pièce jointe en Python

Sans beaucoup de connaissances préalables de MIME, j'ai essayé d'apprendre à écrire un script Python pour envoyer un e-mail avec une pièce jointe. Après le référencement croisé Python , Questions de débordement de pile et recherche générale sur le Web, je me suis installé avec le code suivant [1] et l'a testé pour fonctionner.

import smtplib
from email.MIMEMultipart import MIMEMultipart
from email.MIMEText import MIMEText
from email.MIMEBase import MIMEBase
from email import encoders

fromaddr = "YOUR EMAIL"
toaddr = "EMAIL ADDRESS YOU SEND TO"

msg = MIMEMultipart()

msg['From'] = fromaddr
msg['To'] = toaddr
msg['Subject'] = "SUBJECT OF THE EMAIL"

body = "TEXT YOU WANT TO SEND"

msg.attach(MIMEText(body, 'plain'))

filename = "NAME OF THE FILE WITH ITS EXTENSION"
attachment = open("PATH OF THE FILE", "rb")

part = MIMEBase('application', 'octet-stream')
part.set_payload((attachment).read())
encoders.encode_base64(part)
part.add_header('Content-Disposition', "attachment; filename= %s" % filename)

msg.attach(part)

server = smtplib.SMTP('smtp.gmail.com', 587)
server.starttls()
server.login(fromaddr, "YOUR PASSWORD")
text = msg.as_string()
server.sendmail(fromaddr, toaddr, text)
server.quit()
  1. J'ai une idée approximative de la façon dont ce script fonctionne maintenant et j'ai élaboré le flux de travail suivant. Veuillez me faire savoir à quel point mon organigramme (?) Est précis.

     as.string()  
     |
     +------------MIMEMultipart  
                  |                                                |---content-type  
                  |                                   +---header---+---content disposition  
                  +----.attach()-----+----MIMEBase----|  
                                     |                +---payload (to be encoded in Base64)
                                     +----MIMEText
    
  2. Comment savoir quand utiliser MIMEMultipart, MIMEText et MIMEBase? Cela semble être une question compliquée, alors peut-être me proposer simplement quelques règles générales?

  3. J'ai lu que MIME a une structure arborescente[2] , cela signifie-t-il que MIMEMultipart est toujours au sommet?
  4. Dans le premier bloc de code, MIMEMultipart code ['From'], ['To'] et ['Subject'], mais dans la documentation Python, MIMEText peut également être utilisé pour coder [ 'De'], ['À'] et ['Sujet']. Comment puis-je choisir celui que j'utilise?
  5. Qu'est-ce qu'une "charge utile" exactement? Est-ce du contenu à transporter? Si oui, quel type de contenu cela inclut-il (j'ai remarqué que le corps du texte et les pièces jointes sont traités comme des charges utiles)? Je pensais que ce serait une question facile, mais je ne pouvais tout simplement pas trouver une réponse satisfaisante, fiable et simple.
  6. Est-il vrai que même si MIME peut joindre des formats de fichiers beaucoup plus simples que certains textes, à la fin, tous les encodages, informations d'en-tête et charges utiles sont tous transformés en chaînes afin de pouvoir être passés dans .sendmail ()?

[1] http://naelshiab.com/tutorial-send-email-python/
[2] http://blog.magiksys.net/generate-and-send-mail-with-python-tutorial

20
Ken Lin

Messages électroniques

Un message électronique se compose d'en-têtes (par exemple "De", "À", "Objet" etc.) et du corps (voir RFC 822, section 3.1 ).

Le corps du message est, par défaut, traité comme un simple texte ASCII texte. MIME ( RFC 2045 , RFC 2046 , RFC 2047 , RFC 2048 , RFC 2049 ) définit des extensions qui permettent de spécifier différents types de contenu de courrier électronique.

Une chose très utile que vous pouvez faire avec MIME est de spécifier un type de contenu (par exemple text/html ou application/octet-stream).

Une autre chose utile est que vous pouvez créer un message en plusieurs parties (par exemple, si vous voulez avoir à la fois du HTML et une image dans le HTML). Cela se fait en spécifiant un type de contenu multipart ( RFC 2046, section 5.1 ).

Messages en plusieurs parties

Si un message a un type de contenu multipart, cela signifie qu'il se compose de plusieurs messages et chacun d'eux définit son propre type de contenu (qui peut à nouveau être en plusieurs parties ou autre). Les messages en plusieurs parties sont dans la classe Python représentée par MIMEMultipart .

Donc, pour répondre à la question 3 : Lorsque MIMEMultipart est utilisé, alors oui, c'est une structure arborescente, mais si seulement - MIMEText est utilisé, alors ce n'est pas un arbre.

La question 4 demande sur quelle classe définir les en-têtes ("À", "De" etc.) - cela se fait le Message classe, mais toutes les classes MIME héritent de Message, donc cela peut être fait sur chacune d'elles, mais ces en-têtes n'ont de sens que sur la partie racine d'un message en plusieurs parties.

En d'autres termes, si un message se compose d'une seule partie MIME, spécifiez des en-têtes sur cette partie. S'il se compose de plusieurs parties, la racine est un MIMEMultipart - spécifiez les en-têtes de cette partie.

La question 2 demande "quand utiliser MIMEMultipart, MIMEText et MIMEBase". - MIMEBase n'est qu'une classe de base. Comme le dit spécification : "Normalement, vous ne créerez pas d'instances spécifiquement de MIMEBase" - MIMEText est pour le texte (par exemple text/plain ou text/html), si tout le message est au format texte, ou si une partie de celui-ci l'est. - MIMEMultipart est pour dire "J'ai plus d'une pièce", puis lister les pièces - vous faites cela si vous avez des pièces jointes, vous le faites aussi pour fournir des versions alternatives du même contenu (par exemple, une version en texte brut plus une version HTML)

Question 5 "Qu'est-ce qu'une" charge utile "?" - c'est juste un mot de fantaisie pour le contenu de le message (ou la partie du message)

Question 6 Il y a une limitation à utiliser seulement 7 bits en SMTP. Voir cette réponse pour plus de détails.

Je n'ai pas complètement compris Question 1 , mais il semble que le graphique soit plus ou moins correct. BTW, je n'utiliserais pas MIMEBase ici, car il y a MIMEApplication qui semble plus approprié pour l'usage prévu.

6
zvone