Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
510 views
in Technique[技术] by (71.8m points)

python - Error 10053 When Sending Large Attachments using Gmail API

I'm trying to send emails of various sizes using the Gmail API and the functions below.

Generally this works perfectly, however for attachments over around 10MB (which are rare but will happen) I recieve Errno 10053 which I think is because I timeout when sending the message including the large attachment.

Is there a way around this by say, specifying size or increasing the timeout limit? There's reference to size in the Gmail API docs, but I'm struggling to understand how to use in Python or whether it would even help.

def CreateMessageWithAttachment(sender, to, cc, subject,
                                message_text, file_dir, filename):
  """Create a message for an email.

  Args:
    sender: Email address of the sender.
    to: Email address of the receiver.
    subject: The subject of the email message.
    message_text: The text of the email message.
    file_dir: The directory containing the file to be attached.
    filename: The name of the file to be attached.

  Returns:
    An object containing a base64url encoded email object.
  """
  message = MIMEMultipart()
  message['to'] = to
  if cc != None:
    message['cc'] = cc
  message['from'] = sender
  message['subject'] = subject

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

  path = os.path.join(file_dir, filename)
  content_type, encoding = mimetypes.guess_type(path)

  QCoreApplication.processEvents()

  if content_type is None or encoding is not None:
    content_type = 'application/octet-stream'
  main_type, sub_type = content_type.split('/', 1)
  if main_type == 'text':
    fp = open(path, 'rb')
    msg = MIMEText(fp.read(), _subtype=sub_type)
    fp.close()
  elif main_type == 'image':
    fp = open(path, 'rb')
    msg = MIMEImage(fp.read(), _subtype=sub_type)
    fp.close()
  elif main_type == 'audio':
    fp = open(path, 'rb')
    msg = MIMEAudio(fp.read(), _subtype=sub_type)
    fp.close()
  else:
    fp = open(path, 'rb')
    msg = MIMEBase(main_type, sub_type)
    msg.set_payload(fp.read())
    fp.close()
  QCoreApplication.processEvents()

  msg.add_header('Content-Disposition', 'attachment', filename=filename)
  message.attach(msg)
  return {'raw': base64.urlsafe_b64encode(message.as_string())}



def SendMessage(service, user_id, message, size):
  """Send an email message.

  Args:
    service: Authorized Gmail API service instance.
    user_id: User's email address. The special value "me"
    can be used to indicate the authenticated user.
    message: Message to be sent.

  Returns:
    Sent Message.
  """

  try:
    message = (service.users().messages().send(userId=user_id, body=message)
               .execute())
    QCoreApplication.processEvents()
    return message
  except errors.HttpError, error:
    pass
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

I succeed to insert/send message with large file, pythons code. The google api documentations is not friendly for developers, and the "/upload" issue is totally unclear and not well documented, and it confusing a lot of developers.

The final line do the magic :)

def insert_message(service, message):
        try:
                if message['sizeEstimate'] > 6000000:
                        insert_large_message(service, message)
                else:
                        insert_small_message(service, message)
        except:
                print ('Error: ----type: %s, ----value: %s, ----traceback: %s ************' % (sys.exc_info()[0],sys.exc_info()[1],sys.exc_info()[2]))

def insert_small_message(service, message):
        body = {'raw': message['raw'],'labelIds':message['labelIds'],'internalDateSource':'dateHeader'}
        message = service.users().messages().insert(userId='me',body=body).execute()

def insert_large_message(service, message):
        b = io.BytesIO()
        message_bytes = base64.urlsafe_b64decode(str(message['raw']))
        b.write(message_bytes)
        body = {'labelIds':message['labelIds'],'internalDateSource':'dateHeader'}
        media_body = googleapiclient.http.MediaIoBaseUpload(b, mimetype='message/rfc822' )
        print('load big data!')
        message = service.users().messages().insert(userId='me',body=body,media_body=media_body).execute()

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...