Python

Python 첨부 파일 메일 전송

비번변경 2021. 6. 21. 22:43

2021.06.20 - Python 텍스트 메일 전송

 

지난 글에 이어 이 글에서는 첨부파일을 포함한 메일을 전송할 수 있는 코드를 다룬다.

마찬가지로 코드 전체를 복사해서 사용한다면, MAIN 아래의 email_sender부터 attachment_filepath까지의 값을 잘 넣어주면 된다.

 

전체 코드

import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.mime.base import MIMEBase
from email import encoders
import os
import time

class MailSender:
    def __init__(self, email_sender, sender_passwd, email_recipient, email_server, email_server_port):
        self.msg = MIMEMultipart()
        self.sender = email_sender
        self.passwd = sender_passwd
        self.recipient = email_recipient
        self.email_server = email_server
        self.email_server_port = email_server_port
        self.subject = ""
        self.body = ""

    def context(self, subject, body):
        self.subject = subject
        self.body = body

    def attachment(self, exist_attachment, attachment_filepath):
        if exist_attachment:
            attachment = open(attachment_filepath, 'rb')
            part = MIMEBase('application', 'octet-stream')
            part.set_payload((attachment).read())
            encoders.encode_base64(part)
            part.add_header('Content-Disposition', "attachment", filename=os.path.basename(attachment_filepath))
            self.msg.attach(part)

    def write(self, exist_attachment, attachment_filepath):
        self.msg['From'] = self.sender
        self.msg['To'] = self.recipient
        self.msg['Subject'] = self.subject

        self.msg.attach(MIMEText(self.body, 'plain'))
        self.attachment(exist_attachment, attachment_filepath)

    def send(self):
        server = smtplib.SMTP(self.email_server, self.email_server_port)
        server.ehlo()
        server.starttls()
        server.login(self.sender, self.passwd)
        server.sendmail(self.sender, self.recipient, self.msg.as_string())
        server.quit()

#################### MAIN ####################
# sender/recipient info
email_sender = '보내는 사람 메일 주소'
sender_passwd = '메일 서버 접속에 사용하는 비밀번호'
email_recipient = '받는 사람 메일 주소'
email_server = '메일 서버 주소'
email_server_port = 587 # 메일 서버 접속에 사용하는 포트

# mail context
subject = "제목"
body = "내용"

# attachment info
exist_attachment = True
attachment_filepath = '파일 경로'

# init Mail essentail info
mail = MailSender(email_sender, sender_passwd, email_recipient, email_server, email_server_port)

# writing subject/body of mail
mail.context(subject, body)
mail.write(exist_attachment, attachment_filepath)

# sending mail
mail.send()

 

아래에는 MailSender 클래스에서 텍스트 파일 전송 코드와 다른 부분에 대해서만 적어둔다.

 

달라진 게 있긴 한가

1. import 부분

import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.mime.base import MIMEBase # MIME 클래스의 부모 클래스
from email import encoders # 이진 파일을 텍스트로 인코딩
import os
import time

첨부파일을 처리하기 위한 모듈을 import 한다.

 

2. attachment 함수

def attachment(self, exist_attachment, attachment_filepath):
	if exist_attachment:
		attachment = open(attachment_filepath, 'rb') # 첨부 파일 열기
		part = MIMEBase('application', 'octet-stream')
		part.set_payload((attachment).read()) # 첨부 파일 읽기
		encoders.encode_base64(part) # 텍스트로 인코딩
		part.add_header('Content-Disposition', "attachment", filename=os.path.basename(attachment_filepath)) # 헤더 속성 명시
		self.msg.attach(part) # 파일 첨부

첨부 파일 전송 여부와 파일 경로를 매개변수로 받아, 첨부 파일을 전송할 경우에만 첨부 파일 처리를 진행하는 함수다.

MIMEBase는 인스턴스 생성 시 내용 포맷/내용 형식(maintype/subtype)을 지정하는데, application/octet-stream은 이진 파일을 보낼 때 사용한다. 어떤 파일이든 이진 파일이면 첨부할 수 있다.

 

3. write 함수

def write(self, exist_attachment, attachment_filepath):
	self.msg['From'] = self.sender
	self.msg['To'] = self.recipient
	self.msg['Subject'] = self.subject

	self.msg.attach(MIMEText(self.body, 'plain'))
	self.attachment(exist_attachment, attachment_filepath)

기존과 달리 첨부 파일 전송 여부와 파일 경로를 매개변수로 받는다.

파일 첨부도 msg 객체에 처리가 들어가기 때문에 msg 객체의 값을 초기화하는 write 함수에서 attachment 함수를 호출하게 하였다.

 

이 외의 코드는 동일하다.


코드 수정 시 수정 부분을 줄이고, main 부분을 간결하게 작성해보자 싶어서, 오랜만에 코드를 만져봤는데…… 목적은 달성했지만 좀 엉망으로 나온 것 같다.

python으로 클래스는 어떻게 작성하는지에 대해 전혀 공부를 안 하고 진행한 탓인 듯?

다들 파이썬 쉽댔는데…… 난 왜 어렵지……?