smtplib — SMTP 프로토콜 클라이언트
smtplib — SMTP 프로토콜 클라이언트
smtplib 모듈은 SMTP 또는 ESMTP 리스너 데몬이 있는 모든 인터넷 머신으로 메일을 보내는 데 사용할 수 있는 SMTP 클라이언트 세션 객체를 정의합니다. SMTP와 ESMTP 운영에 대한 자세한 내용은 RFC 821(Simple Mail Transfer Protocol)과 RFC 1869(SMTP Service Extensions)를 참고하세요.
본문
availability: not WASI.
이 모듈은 WebAssembly에서 작동하지 않거나 사용할 수 없습니다.
smtplib.SMTP(host='', port=0, local_hostname=None, [timeout, ]source_address=None)
SMTP 인스턴스는 SMTP 연결을 캡슐화합니다. 전체 SMTP와 ESMTP 연산을 지원하는 메서드를 가집니다. 선택적 host와 port 매개변수가 주어지면 초기화 중에 SMTP connect() 메서드가 그 매개변수로 호출됩니다. 지정하면 local_hostname이 HELO/EHLO 명령에서 로컬 호스트의 FQDN으로 사용됩니다. 그렇지 않으면 socket.getfqdn()을 사용하여 로컬 호스트 이름을 찾습니다. connect() 호출이 성공 코드 이외의 것을 반환하면 SMTPConnectError가 발생합니다. 선택적 timeout 매개변수는 연결 시도와 같은 블로킹 연산에 대한 시간(초)을 지정합니다(지정하지 않으면 전역 기본 타임아웃 설정이 사용됩니다). 타임아웃이 만료되면 TimeoutError가 발생합니다. 선택적 source_address 매개변수는 여러 네트워크 인터페이스가 있는 머신의 특정 소스 주소 및/또는 특정 소스 TCP 포트에 바인딩할 수 있게 합니다. 소켓이 연결 전에 소스 주소로 바인딩할 (host, port) 2-튜플을 받습니다. 생략하면(또는 host나 port가 각각 '' 및/또는 0이면) OS 기본 동작이 사용됩니다.
일반적인 사용에서는 초기화/연결, sendmail(), SMTP.quit() 메서드만 필요해야 합니다. 예제가 아래에 포함되어 있습니다.
SMTP 클래스는 with 문을 지원합니다. 이렇게 사용하면 with 문이 종료될 때 SMTP QUIT 명령이 자동으로 발행됩니다. 예:
>>> from smtplib import SMTP
>>> with SMTP("domain.org") as smtp:
... smtp.noop()
...
(250, b'Ok')
>>>
모든 명령은 감사 이벤트 smtplib.SMTP.send를 인자 self와 data로 발생시킵니다. 여기서 data는 원격 호스트로 보내질 바이트입니다.
versionchanged: 3.3에서
with문 지원이 추가되었습니다.versionchanged: 3.3에서
source_address인자가 추가되었습니다.versionadded: 3.5에서 SMTPUTF8 확장(RFC 6531)이 지원됩니다.
versionchanged: 3.9에서
timeout매개변수가 0으로 설정되면 논블로킹 소켓 생성을 방지하기 위해ValueError가 발생합니다.
*smtplib.SMTP_SSL(host='', port=0, local_hostname=None, , [timeout, ]context=None, source_address=None)
SMTP_SSL 인스턴스는 SMTP 인스턴스와 정확히 동일하게 동작합니다. SMTP_SSL은 연결 시작부터 SSL이 필요하고 starttls()를 사용하는 것이 적절하지 않은 상황에 사용해야 합니다. host가 지정되지 않으면 로컬 호스트가 사용됩니다. port가 0이면 표준 SMTP-over-SSL 포트(465)가 사용됩니다. 선택적 인자 local_hostname, timeout, source_address는 SMTP 클래스에서와 같은 의미를 가집니다. 또한 선택적인 context는 SSLContext를 포함할 수 있으며 보안 연결의 다양한 측면을 구성할 수 있게 합니다. 모범 사례는 보안 고려 사항을 읽으세요.
versionchanged: 3.3에서
context가 추가되었습니다.versionchanged: 3.3에서
source_address인자가 추가되었습니다.versionchanged: 3.4에서 이 클래스는
ssl.SSLContext.check_hostname과 Server Name Indication(ssl.HAS_SNI참고)으로 호스트 이름 검사를 지원합니다.versionchanged: 3.9에서
timeout이 0으로 설정되면 논블로킹 소켓 생성을 방지하기 위해ValueError가 발생합니다.versionchanged: 3.12에서 폐기된
keyfile과certfile매개변수가 제거되었습니다.
smtplib.LMTP(host='', port=LMTP_PORT, local_hostname=None, source_address=None[, timeout])
ESMTP와 매우 유사한 LMTP 프로토콜은 표준 SMTP 클라이언트에 크게 기반합니다. LMTP에는 Unix 소켓을 사용하는 것이 일반적이므로 connect() 메서드는 일반적인 host:port 서버뿐만 아니라 Unix 소켓도 지원해야 합니다. 선택적 인자 local_hostname과 source_address는 SMTP 클래스에서와 같은 의미를 가집니다. Unix 소켓을 지정하려면 '/'로 시작하는 host의 절대 경로를 사용해야 합니다.
인증은 일반 SMTP 메커니즘을 사용하여 지원됩니다. Unix 소켓을 사용할 때 LMTP는 일반적으로 인증을 지원하거나 요구하지 않지만 환경에 따라 다를 수 있습니다.
versionchanged: 3.9에서 선택적
timeout매개변수가 추가되었습니다.
좋은 예외 선택도 정의되어 있습니다.
- smtplib.SMTPException — 이 모듈이 제공하는 다른 모든 예외의 기본 예외 클래스인
OSError의 하위 클래스.versionchanged: 3.4에서
SMTPException이OSError의 하위 클래스가 되었습니다. - smtplib.SMTPServerDisconnected — 서버가 예기치 않게 연결을 끊거나, 서버에 연결하기 전에
SMTP인스턴스를 사용하려고 할 때 발생하는 예외. - smtplib.SMTPResponseException — SMTP 오류 코드를 포함하는 모든 예외의 기본 클래스. SMTP 서버가 오류 코드를 반환할 때 일부 인스턴스에서 생성됩니다.
- smtp_code — 오류 코드.
- smtp_error — 오류 메시지.
- smtplib.SMTPSenderRefused — 보낸 사람 주소가 거부됨. 모든
SMTPResponseException예외에 설정된 속성 외에 SMTP 서버가 거부한 문자열로'sender'를 설정합니다. - smtplib.SMTPRecipientsRefused — 모든 수신자 주소가 거부됨.
- recipients — 각 수신자의 오류를 포함하는
SMTP.sendmail()이 반환하는 것과 정확히 같은 종류의 사전.
- recipients — 각 수신자의 오류를 포함하는
- smtplib.SMTPDataError — SMTP 서버가 메시지 데이터를 수락하지 않음.
- smtplib.SMTPConnectError — 서버와의 연결 설정 중 오류 발생.
- smtplib.SMTPHeloError — 서버가 HELO 메시지를 거부함.
- smtplib.SMTPNotSupportedError — 시도한 명령이나 옵션을 서버가 지원하지 않음.
versionadded: 3.5.
- smtplib.SMTPAuthenticationError — SMTP 인증이 잘못됨. 아마도 서버가 제공된 사용자 이름/비밀번호 조합을 수락하지 않았습니다.
See also
- RFC 821 - Simple Mail Transfer Protocol — SMTP의 프로토콜 정의. 이 문서는 SMTP의 모델, 운영 절차 및 프로토콜 세부 사항을 다룹니다.
- RFC 1869 - SMTP Service Extensions — SMTP의 ESMTP 확장 정의. 이것은 새 명령으로 SMTP를 확장하기 위한 프레임워크를 설명하고, 서버가 제공하는 명령의 동적 발견을 지원하며, 몇 가지 추가 명령을 정의합니다.
SMTP 객체
SMTP 인스턴스는 다음 메서드를 가집니다.
- SMTP.set_debuglevel(level) — 디버그 출력 수준을 설정합니다.
level에 대해 1 또는True값은 연결 및 서버로 보내고 서버에서 받는 모든 메시지에 대한 디버그 메시지를 생성합니다.level에 대해 2 값은 이 메시지에 타임스탬프를 찍습니다.versionchanged: 3.5에서 debuglevel 2가 추가되었습니다.
- SMTP.docmd(cmd, args='') — 명령
cmd를 서버로 보냅니다. 선택적 인자args는 공백으로 구분되어 명령에 단순히 연결됩니다. 이것은 숫자 응답 코드와 실제 응답 줄로 구성된 2-튜플을 반환합니다(여러 줄 응답은 하나의 긴 줄로 결합됩니다). 정상 운영에서 이 메서드를 명시적으로 호출할 필요는 없어야 합니다. 다른 메서드를 구현하는 데 사용되며 개인 확장 테스트에 유용할 수 있습니다. 서버에 대한 연결이 응답을 기다리는 동안 끊어지면SMTPServerDisconnected가 발생합니다. - SMTP.connect(host='localhost', port=0) — 주어진 포트의 호스트에 연결합니다. 기본값은 표준 SMTP 포트(25)의 로컬 호스트에 연결하는 것입니다. 호스트 이름이 콜론(
:) 뒤에 숫자로 끝나면 해당 접미사가 제거되고 그 숫자가 사용할 포트 번호로 해석됩니다. 이 메서드는 인스턴스화 중에 호스트가 지정되면 생성자가 자동으로 호출합니다. 연결 응답에서 서버가 보낸 응답 코드와 메시지의 2-튜플을 반환합니다. 감사 이벤트smtplib.connect를 인자self, host, port로 발생시킵니다. - SMTP.helo(name='') — HELO를 사용하여 SMTP 서버에 자신을 식별합니다.
hostname인자는 기본적으로 로컬 호스트의 완전한 도메인 이름입니다. 서버가 반환한 메시지는 객체의helo_resp속성으로 저장됩니다. 정상 운영에서 이 메서드를 명시적으로 호출할 필요는 없어야 합니다. 필요할 때sendmail()이 암시적으로 호출합니다. - SMTP.ehlo(name='') — EHLO를 사용하여 ESMTP 서버에 자신을 식별합니다.
hostname인자는 기본적으로 로컬 호스트의 완전한 도메인 이름입니다. ESMTP 옵션에 대한 응답을 검사하고has_extn()에서 사용하도록 저장합니다. 또한 몇 가지 정보 속성을 설정합니다: 서버가 반환한 메시지는ehlo_resp속성으로 저장되고,does_esmtp는 서버가 ESMTP를 지원하는지 여부에 따라True또는False로 설정되며,esmtp_features는 이 서버가 지원하는 SMTP 서비스 확장의 이름과 그 매개변수(있는 경우)를 포함하는 사전이 됩니다. 메일을 보내기 전에has_extn()을 사용하려는 경우가 아니라면 이 메서드를 명시적으로 호출할 필요는 없어야 합니다. 필요할 때sendmail()이 암시적으로 호출합니다. - SMTP.ehlo_or_helo_if_needed() — 이 세션에서 이전 EHLO 또는 HELO 명령이 없었다면 이 메서드는
ehlo()및/또는helo()를 호출합니다. 먼저 ESMTP EHLO를 시도합니다.- SMTPHeloError — 서버가 HELO 인사에 제대로 응답하지 않음.
- SMTP.has_extn(name) —
name이 서버가 반환한 SMTP 서비스 확장 집합에 있으면True, 그렇지 않으면False를 반환합니다. 대소문자는 무시됩니다. - SMTP.verify(address) — SMTP VRFY를 사용하여 이 서버에서 주소의 유효성을 확인합니다. 사용자 주소가 유효하면 코드 250과 전체 RFC 822 주소(사람 이름 포함)로 구성된 튜플을 반환합니다. 그렇지 않으면 400 이상의 SMTP 오류 코드와 오류 문자열을 반환합니다.
Note 스팸 발송자를 막기 위해 많은 사이트에서 SMTP VRFY를 비활성화합니다.
- *SMTP.login(user, password, , initial_response_ok=True) — 인증이 필요한 SMTP 서버에 로그인합니다. 인자는 인증에 사용할 사용자 이름과 비밀번호입니다. 이 세션에서 이전 EHLO 또는 HELO 명령이 없었다면 이 메서드는 먼저 ESMTP EHLO를 시도합니다. 인증이 성공하면 이 메서드는 정상적으로 반환하거나 다음 예외를 발생시킬 수 있습니다:
- SMTPHeloError — 서버가 HELO 인사에 제대로 응답하지 않음.
- SMTPAuthenticationError — 서버가 사용자 이름/비밀번호 조합을 수락하지 않음.
- SMTPNotSupportedError — AUTH 명령을 서버가 지원하지 않음.
- SMTPException — 적합한 인증 방법이 없음.
smtplib이 지원하는 각 인증 방법은 서버가 지원한다고 광고하면 차례로 시도됩니다. 지원되는 인증 방법 목록은
auth()를 참고하세요.initial_response_ok는auth()로 전달됩니다. 선택적 키워드 인자initial_response_ok는 RFC 4954에 지정된 "초기 응답(initial response)"을 challenge/response를 요구하는 대신 AUTH 명령과 함께 보낼 수 있는지 여부를 지정합니다.
versionchanged: 3.5에서
SMTPNotSupportedError가 발생할 수 있고initial_response_ok매개변수가 추가되었습니다. - *SMTP.auth(mechanism, authobject, , initial_response_ok=True) — 지정된 인증 메커니즘에 대해 SMTP AUTH 명령을 발행하고
authobject를 통해 challenge 응답을 처리합니다.mechanism은 AUTH 명령의 인자로 사용될 인증 메커니즘을 지정합니다. 유효한 값은esmtp_features의auth요소에 나열된 값입니다.authobject는 선택적 단일 인자를 받는 호출 가능한 객체여야 합니다:
선택적 키워드 인자data = authobject(challenge=None)initial_response_ok가 참이면authobject()가 먼저 인자 없이 호출됩니다. RFC 4954 "초기 응답" ASCII str을 반환할 수 있으며, 아래와 같이 인코딩되어 AUTH 명령과 함께 보내집니다.authobject()가 초기 응답을 지원하지 않으면(예: challenge가 필요해서)challenge=None으로 호출될 때None을 반환해야 합니다.initial_response_ok가 거짓이면authobject()는None으로 먼저 호출되지 않습니다. 초기 응답 검사가None을 반환하거나initial_response_ok가 거짓이면,authobject()가 서버의 challenge 응답을 처리하도록 호출됩니다. 전달되는challenge인자는bytes가 됩니다. base64로 인코딩되어 서버로 보내질 ASCII strdata를 반환해야 합니다.SMTP클래스는 CRAM-MD5, PLAIN, LOGIN 메커니즘을 위한 authobject를 제공합니다. 각각SMTP.auth_cram_md5,SMTP.auth_plain,SMTP.auth_login이라고 합니다. 모두SMTP인스턴스의user와password속성이 적절한 값으로 설정되어 있어야 합니다. 사용자 코드는 일반적으로auth를 직접 호출할 필요가 없으며, 대신 위 메커니즘을 나열된 순서대로 차례로 시도하는login()메서드를 호출할 수 있습니다.auth는 smtplib이 직접 지원하지 않는(또는 아직 지원하지 않는) 인증 방법의 구현을 용이하게 하기 위해 노출됩니다.versionadded: 3.5.
- SMTP.starttls(*, context=None) — SMTP 연결을 TLS(Transport Layer Security) 모드로 전환합니다. 뒤따르는 모든 SMTP 명령이 암호화됩니다. 그런 다음
ehlo()를 다시 호출해야 합니다.keyfile과certfile이 제공되면ssl.SSLContext를 만드는 데 사용됩니다. 선택적context매개변수는ssl.SSLContext객체입니다. 이것은keyfile과certfile을 사용하는 대안이며, 지정되면keyfile과certfile은 둘 다None이어야 합니다. 이 세션에서 이전 EHLO 또는 HELO 명령이 없었다면 이 메서드는 먼저 ESMTP EHLO를 시도합니다.versionchanged: 3.12에서 폐기된
keyfile과certfile매개변수가 제거되었습니다.- SMTPHeloError — 서버가 HELO 인사에 제대로 응답하지 않음.
- SMTPNotSupportedError — 서버가 STARTTLS 확장을 지원하지 않음.
- RuntimeError — Python 인터프리터에서 SSL/TLS 지원을 사용할 수 없음.
versionchanged: 3.3에서
context가 추가되었습니다. versionchanged: 3.4에서 이 메서드는ssl.SSLContext.check_hostname과 Server Name Indicator(HAS_SNI 참고)로 호스트 이름 검사를 지원합니다. versionchanged: 3.5에서 STARTTLS 지원 부족으로 발생하는 오류는 이제 기본SMTPException대신SMTPNotSupportedError하위 클래스입니다. - SMTP.sendmail(from_addr, to_addrs, msg, mail_options=(), rcpt_options=()) — 메일을 보냅니다. 필수 인자는 RFC 822 보낸 사람 주소 문자열, RFC 822 받는 사람 주소 문자열 목록(단일 문자열은 1개 주소의 목록으로 취급됨), 메시지 문자열입니다. 호출자는 MAIL FROM 명령에 사용할 ESMTP 옵션 목록(예:
"8bitmime")을mail_options로 전달할 수 있습니다. 모든 RCPT 명령에 사용해야 하는 ESMTP 옵션(예: DSN 명령)은rcpt_options로 전달할 수 있습니다. 각 옵션은 잠재적 키를 포함한 옵션의 전체 텍스트를 포함하는 문자열로 전달해야 합니다(예:"NOTIFY=SUCCESS,FAILURE"). (다른 수신자에게 다른 ESMTP 옵션을 사용해야 한다면 메시지를 보내기 위해mail(),rcpt(),data()와 같은 저수준 메서드를 사용해야 합니다.)Note
from_addr과to_addrs매개변수는 전송 에이전트가 사용하는 메시지 봉투(envelope)를 구성하는 데 사용됩니다.sendmail은 메시지 헤더를 어떤 식으로든 수정하지 않습니다.msg는 ASCII 범위의 문자를 포함하는 문자열이거나 바이트 문자열일 수 있습니다. 문자열은 ascii 코덱을 사용하여 bytes로 인코딩되고, 단독\r과\n문자는\r\n문자로 변환됩니다. 바이트 문자열은 수정되지 않습니다. 이 세션에서 이전 EHLO 또는 HELO 명령이 없었다면 이 메서드는 먼저 ESMTP EHLO를 시도합니다. 서버가 ESMTP를 하면 메시지 크기와 지정된 각 옵션이 서버에 전달됩니다(옵션이 서버가 광고하는 기능 집합에 있으면). EHLO가 실패하면 HELO가 시도되고 ESMTP 옵션은 억제됩니다. 적어도 한 명의 수신자에 대해 메일이 수락되면 이 메서드는 정상적으로 반환합니다. 그렇지 않으면 예외를 발생시킵니다. 즉, 이 메서드가 예외를 발생시키지 않으면 누군가는 메일을 받아야 합니다. 이 메서드가 예외를 발생시키지 않으면 각 거부된 수신자에 대해 하나의 항목이 있는 사전을 반환합니다. 각 항목은 SMTP 오류 코드와 서버가 보낸 수반 오류 메시지의 튜플을 포함합니다.SMTPUTF8이mail_options에 포함되고 서버가 이를 지원하면from_addr과to_addrs는 비-ASCII 문자를 포함할 수 있습니다. 이 메서드는 다음 예외를 발생시킬 수 있습니다:- SMTPRecipientsRefused — 모든 수신자가 거부됨. 아무도 메일을 받지 못함.
- SMTPHeloError — 서버가 HELO 인사에 제대로 응답하지 않음.
- SMTPSenderRefused — 서버가
from_addr을 수락하지 않음. - SMTPDataError — 서버가 예기치 않은 오류 코드로 응답함(수신자 거부가 아닌).
- SMTPNotSupportedError —
mail_options에 SMTPUTF8이 주어졌지만 서버가 지원하지 않음. 달리 명시되지 않는 한, 예외가 발생한 후에도 연결은 열려 있습니다.
versionchanged: 3.2에서
msg는 바이트 문자열일 수 있습니다. versionchanged: 3.5에서 SMTPUTF8 지원이 추가되었고, SMTPUTF8이 지정되었지만 서버가 지원하지 않으면SMTPNotSupportedError가 발생할 수 있습니다. - SMTP.send_message(msg, from_addr=None, to_addrs=None, mail_options=(), rcpt_options=()) —
email.message.Message객체로 표현되는 메시지로sendmail()을 호출하기 위한 편의 메서드입니다.msg가Message객체라는 점을 제외하면 인자는sendmail()과 같은 의미를 가집니다.from_addr이None이거나to_addrs가None이면send_message는 RFC 5322에 지정된 대로msg의 헤더에서 추출한 주소로 그 인자를 채웁니다:from_addr은Sender필드가 있으면 그것으로, 그렇지 않으면From필드로 설정됩니다.to_addrs는msg의To,Cc,Bcc필드의 값(있는 경우)을 결합합니다. 메시지에 정확히 한 세트의Resent-*헤더가 나타나면 일반 헤더는 무시되고Resent-*헤더가 대신 사용됩니다. 메시지에 둘 이상의 세트의Resent-*헤더가 있으면 가장 최근 세트를 명확하게 감지할 방법이 없으므로ValueError가 발생합니다.send_message는BytesGenerator를 사용하여\r\n을 linesep으로msg를 직렬화하고,sendmail()을 호출하여 결과 메시지를 전송합니다.from_addr과to_addrs의 값과 관계없이send_message는msg에 나타날 수 있는Bcc또는Resent-Bcc헤더를 전송하지 않습니다.from_addr과to_addrs의 주소 중 하나라도 비-ASCII 문자를 포함하고 서버가 SMTPUTF8 지원을 광고하지 않으면SMTPNotSupportedError가 발생합니다. 그렇지 않으면Message는utf8속성이True로 설정된 정책의 복제본으로 직렬화되고SMTPUTF8과BODY=8BITMIME이mail_options에 추가됩니다.versionadded: 3.2. versionadded: 3.5에서 국제화 주소(SMTPUTF8) 지원.
- SMTP.quit() — SMTP 세션을 종료하고 연결을 닫습니다. SMTP QUIT 명령의 결과를 반환합니다.
표준 SMTP/ESMTP 명령 HELP, RSET, NOOP, MAIL, RCPT, DATA에 해당하는 저수준 메서드도 지원됩니다. 일반적으로 이들을 직접 호출할 필요가 없으므로 여기서 문서화하지 않습니다. 자세한 내용은 모듈 코드를 참고하세요.
또한 SMTP 인스턴스는 다음 속성을 가집니다.
- SMTP.helo_resp — HELO 명령에 대한 응답,
helo()참고. - SMTP.ehlo_resp — EHLO 명령에 대한 응답,
ehlo()참고. - SMTP.does_esmtp — 서버가 ESMTP를 지원하는지 여부를 나타내는 부울 값,
ehlo()참고. - SMTP.esmtp_features — 서버가 지원하는 SMTP 서비스 확장 이름의 사전,
ehlo()참고.
SMTP 예제
이 예제는 사용자에게 메시지 봉투에 필요한 주소('To'와 'From' 주소)와 전달할 메시지를 묻습니다. 메시지에 포함할 헤더는 입력한 대로 메시지에 포함되어야 합니다. 이 예제는 RFC 822 헤더를 처리하지 않습니다. 특히 'To'와 'From' 주소는 메시지 헤더에 명시적으로 포함되어야 합니다:
import smtplib
def prompt(title):
return input(title).strip()
from_addr = prompt("From: ")
to_addrs = prompt("To: ").split()
print("Enter message, end with ^D (Unix) or ^Z (Windows):")
# Add the From: and To: headers at the start!
lines = [f"From: {from_addr}", f"To: {', '.join(to_addrs)}", ""]
while True:
try:
line = input()
except EOFError:
break
else:
lines.append(line)
msg = "\r\n".join(lines)
print("Message length is", len(msg))
server = smtplib.SMTP("localhost")
server.set_debuglevel(1)
server.sendmail(from_addr, to_addrs, msg)
server.quit()
Note
일반적으로 email 패키지의 기능을 사용하여 이메일 메시지를 구성한 다음
send_message()를 통해 보내는 것이 좋습니다. email: 예제 참고.