简体   繁体   中英

Gmail API Python: Optimize code to send email faster

The code below works. I can send emails through the Gmail API, but it takes awhile to send 10 personalized emails, based on wall time (20-30 secs). Is there a way to optimize the code below to send emails faster? There are quota limitations.

Is the max number emails one can send, a 100 per day? There seems to be a difference between number of emails one can send and the number of receipts per email. This is the documentation I am sourcing: https://developers.google.com/apps-script/guides/services/quotas

I am using the consumer version.

Feature Consumer (gmail.com)
Calendar events created 5,000
Contacts created 1,000

Documents created 250

Email recipients per day 100*

Code:

import httplib2
import os
import oauth2client
from oauth2client import client, tools
import base64
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from apiclient import errors, discovery
import mimetypes

import pandas as pd
import textwrap

SCOPES = 'https://www.googleapis.com/auth/gmail.send'
CLIENT_SECRET_FILE = 'secret.json'
APPLICATION_NAME = 'AppName'

def get_credentials():
    home_dir = os.path.expanduser('~')
    credential_dir = os.path.join(home_dir, '.credentials')
    if not os.path.exists(credential_dir):
        os.makedirs(credential_dir)
    credential_path = os.path.join(credential_dir,
                               'gmail-send.json')
    store = oauth2client.file.Storage(credential_path)
    credentials = store.get()
    if not credentials or credentials.invalid:
        flow = client.flow_from_clientsecrets(CLIENT_SECRET_FILE, SCOPES)
        flow.user_agent = APPLICATION_NAME
        credentials = tools.run_flow(flow, store)
        print 'Storing credentials to ' + credential_path
    return credentials

def SendMessage(sender, to, subject,message_text):
    credentials = get_credentials()
    http = credentials.authorize(httplib2.Http())
    service = discovery.build('gmail', 'v1', http=http)

    message1 = CreateMessageHtml(sender, to, subject, message_text)
    result = SendMessageInternal(service, "me", message1)
    return result

def CreateMessageHtml(sender, to, subject, message_text):
    msg = MIMEText(message_text)
    msg['Subject'] = subject
    msg['From'] = sender
    msg['To'] = to

    return {'raw': base64.urlsafe_b64encode(msg.as_string())}

def SendMessageInternal(service, user_id, message):
    try:
        message = (service.users().messages().send(userId=user_id, body=message).execute())
        print 'Message Id: %s' % message['id']
        return message
    except errors.HttpError, error:
        print 'An error occurred: %s' % error
        return "Error"
    return "OK"

def main():
    df = pd.read_csv('testdata.csv')
    for index,row in df.iterrows():
        to = row['Email']
        sender = "sender"
        subject = "subject"
        dedent_text = '''Hello {}, \n
thank you for your question.'''.format(row['First'])
    message_text = textwrap.dedent(dedent_text).strip()
    SendMessage(sender, to, subject, message_text)


if __name__ == '__main__':
    main()

Try caching the result of the service call, so that service is passed to SendMessage . This way, you don't take API call times to setup the API for each individual emails you send.

So at top of your main:

def main():
    # Do once
    credentials = get_credentials()
    http = credentials.authorize(httplib2.Http())
    service = discovery.build('gmail', 'v1', http=http)

    df = pd.read_csv('testdata.csv')
    for index,row in df.iterrows():
        to = row['Email']
        sender = "sender"
        subject = "subject"
        dedent_text = '''Hello {}, \n
        thank you for your question.'''.format(row['First'])
        message_text = textwrap.dedent(dedent_text).strip()

        # service is is reused here for each message
        SendMessage(service, sender, to, subject, message_text)

Also, if you need to send many messages, make sure you invoke one Python invokation per large batch, since starting up the interpreter and loading many packages can take a while each time.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM