Python: when sending email, always blocked in the clause: smtpserver = smtplib.SMTP(“smtp.gmail.com”,587)

前端 未结 4 1939
轮回少年
轮回少年 2021-01-19 08:40

I am writing a Python program to send an email. But every time when executing the clause:

smtpserver = smtplib.SMTP(\"smtp.gmail.com\",587)

相关标签:
4条回答
  • 2021-01-19 08:58

    For reference, cpython smtplib is blocking. That is, it blocks the GIL (ie Python) while connecting. Despite the claims the GIL is released on I/O, it is only released on some I/O, and SMTP connections are not such. To make it async, you need to hand the mail send to another process or thread, depending on your situation.

    0 讨论(0)
  • 2021-01-19 09:02

    There may be some issue with the connection (maybe it is being blocked by your proxy or firewall?) and the timeout may be pretty big for you to do not see it going further.

    The documentation of smtplib.SMTP says:

    class smtplib.SMTP([host[, port[, local_hostname[, timeout]]]])

    (...) An SMTPConnectError is raised if the specified host doesn’t respond correctly. The optional timeout parameter specifies a timeout in seconds for blocking operations like the connection attempt (if not specified, the global default timeout setting will be used).

    Try specifying the timeout yourself:

    smtpserver = smtplib.SMTP("smtp.gmail.com", 587, timeout=30)
    
    0 讨论(0)
  • 2021-01-19 09:13

    Maybe I am 4 years late, but this is what worked for me and might help someone else!

    server = smtplib.SMTP("smtp.gmail.com", 587, None, 30)
    
    0 讨论(0)
  • 2021-01-19 09:18

    I ran into a similar issue and none of the answers above worked for me. My problem was that since my smtp server uses SSL. I needed to use smtplib.SMTP_SSL instead of smtplib.SMTP. I just posting my full working code below. Make sure to change values of req and email_config before executing.

        req = {
            "email": "to@something.com",
            "subject": "new e-mail from python",
            "body": "Hi,\nI am a bot",
        }
    
        email_config = {
            "server": "smtp.orange.fr",
            "port": 465,
            "username": "username@orange.fr",
            "password": "mypassword",
            "email": "fromwhichemail@orange.fr",
        }
    
    
    #!/usr/bin/env python3
    import smtplib
    
    from email import encoders
    from email.mime.base import MIMEBase
    from email.mime.multipart import MIMEMultipart
    from email.mime.text import MIMEText
    
    class Mail(object):
        def __init__(self, email_config):
            self.email = email_config["email"]
            self.password = email_config["password"]
            self.server = email_config["server"]
            self.port = email_config["port"]
            print(f"Logging to {self.server}:{self.port}")
            session = smtplib.SMTP_SSL(self.server, self.port)
            print(f"Calling ehlo")
            session.ehlo()
            print(f"Calling login")
            session.login(self.email, self.password)
            self.session = session
    
        def send_message(self, subject, to, body, filename):
            # Create a multipart message and set headers
            message = MIMEMultipart()
            message["From"] = self.email
            message["To"] = to
            message["Subject"] = subject
            message["Bcc"] = ""
            # Add body to email
            message.attach(MIMEText(body, "plain"))
            print(f"tot: {to}")
            print(f"subject: {subject}")
            print(f"body: {body}")
    
            if filename is not None:
                # Open PDF file in binary mode
                with open(filename, "rb") as attachment:
                    part = MIMEBase("application", "octet-stream")
                    part.set_payload(attachment.read())
                # Encode file in ASCII characters to send by email
                encoders.encode_base64(part)
                # Add header as key/value pair to attachment part
                part.add_header(
                    "Content-Disposition",
                    f"attachment; filename= {filename}",)
                # Add attachment to message and convert message to string
                message.attach(part)
    
            # Send e-mail
            print(f"Sending e-mail...")
            self.session.sendmail(self.email, to, message.as_string())
    
    if __name__ == "__main__":
        req = {
            "email": "to@something.com",
            "subject": "new e-mail from python",
            "body": "Hi,\nI am a bot",
        }
    
        email_config = {
            "server": "smtp.orange.fr",
            "port": 465,
            "username": "username@orange.fr",
            "password": "mypassword",
            "email": "fromwhichemail@orange.fr",
        }
        m = Mail(email_config)
        if "pdf_file" in req:
            m.send_message(req["subject"], req["email"], req["body"], req["pdf_file"])
        else:
            m.send_message(req["subject"], req["email"], req["body"], None)
    
    
    
    
    0 讨论(0)
提交回复
热议问题