首页 > 解决方案 > Python Gmail API。socket.timeout - 尝试发送 .log 文件时无法写入错误

问题描述

在使用 Python Gmail API 发送 .log 文件时,我已经尝试了所有可能的组合。但是,当我尝试创建电子邮件消息并作为附件发送时,我收到与套接字写入相关的 socket.timeout 错误。

错误:

 File "C:\Users\MyUser\AppData\Local\Programs\Python\Python38-32\lib\http\client.py", line 1240, in request
    self._send_request(method, url, body, headers, encode_chunked)
  File "C:\Users\MyUser\AppData\Local\Programs\Python\Python38-32\lib\http\client.py", line 1286, in _send_request
    self.endheaders(body, encode_chunked=encode_chunked)
  File "C:\Users\MyUser\AppData\Local\Programs\Python\Python38-32\lib\http\client.py", line 1235, in endheaders
    self._send_output(message_body, encode_chunked=encode_chunked)
  File "C:\Users\MyUser\AppData\Local\Programs\Python\Python38-32\lib\http\client.py", line 1045, in _send_output
    self.send(chunk)
  File "C:\Users\MyUser\AppData\Local\Programs\Python\Python38-32\lib\http\client.py", line 967, in send
    self.sock.sendall(data)
  File "C:\Users\MyUser\AppData\Local\Programs\Python\Python38-32\lib\ssl.py", line 1204, in sendall
    v = self.send(byte_view[count:])
  File "C:\Users\MyUser\AppData\Local\Programs\Python\Python38-32\lib\ssl.py", line 1173, in send
    return self._sslobj.write(data)
socket.timeout: The write operation timed out

我使用此功能创建电子邮件。我返回了两封不同电子邮件的列表。第一封电子邮件是带有附件的电子邮件。第二封邮件没有附件。当带附件的电子邮件失败时,我发送不带附件的电子邮件。

创建电子邮件:

 def createMessage(self, sender , to, subject, messageBody, attachmentList):
        try:
            message = MIMEMultipart()
            message['to'] = to
            message['from'] = sender
            message['subject'] = subject

            msg = MIMEText(messageBody)
            message.attach(msg)

            raw_message = base64.urlsafe_b64encode(message.as_string().encode("utf-8"))
            regularMessage = {'raw' : raw_message.decode("utf-8")}

            totalSizeOf = 0
            for targetAttachment in attachmentList:
                targetAttachmentExtension = targetAttachment.getFileExtension()
                if targetAttachmentExtension is False:
                    logging.error("Failed to get target attachment extension.")
                    continue
                targetAttachmentFileInstance = targetAttachment.getFileInstance()
                if targetAttachmentFileInstance is False:
                    logging.error("Failed to get file instance.")
                    continue
                attachmentSizeBytes = sys.getsizeof(targetAttachmentFileInstance)
                if totalSizeOf + attachmentSizeBytes > 5000000:
                    continue
                else:
                    totalSizeOf = totalSizeOf + attachmentSizeBytes
                if targetAttachmentExtension == 'jpg':
                    msgAttachment = MIMEImage(targetAttachmentFileInstance, _subtype='jpeg')
                elif targetAttachmentExtension == 'png':
                    msgAttachment = MIMEImage(targetAttachmentFileInstance, _subtype='png')
                elif targetAttachmentExtension == 'txt' or targetAttachmentExtension =='log':
                    if type(targetAttachmentFileInstance) is bytes:
                        targetAttachmentFileInstance = targetAttachmentFileInstance.decode('utf-8')
                    msgAttachment = MIMEText(targetAttachmentFileInstance, _subtype='plain')
                else:
                    msgAttachment = MIMEBase('application', 'octet-stream')
                    msgAttachment.set_payload(targetAttachmentFileInstance)
                targetAttachmentFileName = targetAttachment.getFullFilename()
                if targetAttachmentFileName is False:
                    logging.error("Failed to get attachment filename")
                    continue
                msgAttachment.add_header('Content-Disposition', 'attachment', filename=targetAttachmentFileName)
                message.attach(msgAttachment)
            raw = base64.urlsafe_b64encode(message.as_bytes())
            raw = raw.decode()
            attachmentMessage = {'raw' : raw}

            return [attachmentMessage, regularMessage]
        except:
            self.GLogger.error("An error was encountered while attempting create an email message")
            tb = traceback.format_exc()
            self.GLogger.exception(tb)
            return False

发送功能:

    def gmailAPISendEmailAttachmentFailover(self, message, userID="me"):
        try:
            service = self.gmailAPIService
            self.GLogger.info("Attempting to send email message")

            if type(message) != list:
                self.GLogger.error(f"Expected the message to be of type list")
                return False
            if len(message) != 2:
                self.GLogger.error("Message list length not 2")
                return False
            attachmentMessage = message[0]
            regularMessage = message[1]

            try:
                response = (service.users().messages().send(userId=userID, body=attachmentMessage).execute())
            except:
                response = (service.users().messages().send(userId=userID, body=regularMessage).execute())

            responseID = str(response['id'])
            self.GLogger.info("Successfully sent email message with ID (" + responseID +")")
            return responseID
        except:
            self.GLogger.error("Failed to send email message")
            tb = traceback.format_exc()
            self.GLogger.exception(tb)
            return False

attachmentList 是附件对象的列表。这样做的唯一意义是我尝试将 .log 文件作为“rb”和“r”读入附件对象。只需 fileinstance=FID.read()。我尝试将日志文件作为 main_type = application 和 sub_type = octet-stream 发送。我还尝试将其作为 MIMEText 发送,并带有 sub_type = plain。正如您在我的创建电子邮件功能中看到的,我目前也将附件大小限制为 5MB。我把它从 15 MB 减少了,因为我认为这可能是问题所在。

我完全被难住了为什么它不起作用。请帮忙。

标签: pythonpython-3.xgmail-api

解决方案


推荐阅读