title: What are the firewall requirements (Port and Sites) for the python Gmail API and OAuth2.0?
body: <p>I am planning to use the Gmail API for sending emails.</p>
  <p>I will also be using OAuth 2.0 authentication.</p>
  <p>The mechanism for authenticating is indicated in the quickstart guide:</p>
  <pre><code>from __future__ import print_function
  
  import os.path
  
  from google.auth.transport.requests import Request
  from google.oauth2.credentials import Credentials
  from google_auth_oauthlib.flow import InstalledAppFlow
  from googleapiclient.discovery import build
  from googleapiclient.errors import HttpError
  
  # If modifying these scopes, delete the file token.json.
  SCOPES = ['https://www.googleapis.com/auth/gmail.readonly']
  
  
  def main():
      &quot;&quot;&quot;Shows basic usage of the Gmail API.
      Lists the user's Gmail labels.
      &quot;&quot;&quot;
      creds = None
      # The file token.json stores the user's access and refresh tokens, and is
      # created automatically when the authorization flow completes for the first
      # time.
      if os.path.exists('token.json'):
          creds = Credentials.from_authorized_user_file('token.json', SCOPES)
      # If there are no (valid) credentials available, let the user log in.
      if not creds or not creds.valid:
          if creds and creds.expired and creds.refresh_token:
              creds.refresh(Request())
          else:
              flow = InstalledAppFlow.from_client_secrets_file(
                  'credentials.json', SCOPES)
              creds = flow.run_local_server(port=0)
          # Save the credentials for the next run
          with open('token.json', 'w') as token:
              token.write(creds.to_json())
  
      try:
          # Call the Gmail API
          service = build('gmail', 'v1', credentials=creds)
          results = service.users().labels().list(userId='me').execute()
          labels = results.get('labels', [])
  
          if not labels:
              print('No labels found.')
              return
          print('Labels:')
          for label in labels:
              print(label['name'])
  
      except HttpError as error:
          # TODO(developer) - Handle errors from gmail API.
          print(f'An error occurred: {error}')
  
  
  if __name__ == '__main__':
      main()
  </code></pre>
  <p>One example of sending an email:</p>
  <pre><code>def gmailAPISendEmail(self, message, userID=&quot;me&quot;):
      try:
          service = self.gmailAPIService
          self.GLogger.info(&quot;Attempting to send email message&quot;)
          try: 
              response = service.users().messages().send(userId=userID, body=message).execute()
          except socket.timeout: 
              pass
          except: 
              self.GLogger.error(&quot;Failed to send email message&quot;)
              tb = traceback.format_exc()
              self.GLogger.exception(tb)
  
          try: 
              responseID = str(response['id'])
          except: 
              responseID = &quot;CouldNotParseID&quot;
          
          self.GLogger.info(&quot;Successfully sent email message with ID (&quot; + responseID +&quot;)&quot;)
          return responseID
      except:
          self.GLogger.error(&quot;Failed to send email message&quot;)
          tb = traceback.format_exc()
          self.GLogger.exception(tb)
          return False
  </code></pre>
  <p>An example of creating an email:</p>
  <pre><code>def createEmaiLWithAttachments(self,sendTo, sendFrom, subject,emailMsg , attachments, html=False): 
      try: 
          mimeMessage = MIMEMultipart()
          mimeMessage['to'] = sendTo
          mimeMessage['from'] = sendFrom
          mimeMessage['subject'] = subject
          if html: 
              msg= MIMEText(emailMsg, 'html')
          else: 
              msg= MIMEText(emailMsg)
          mimeMessage.attach(msg)
  
          for attachment in attachments: 
              attachment_name = attachment[0]
              attachment_instance = attachment[1]
              content_type, encoding = mimetypes.guess_type(attachment_name)
              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': 
                  msg = MIMEText(attachment_instance, _subtype=sub_type)
              elif main_type == 'image':
                  msg = MIMEImage(attachment_instance, _subtype=sub_type)
              elif main_type == 'audio':
                  msg = MIMEAudio(attachment_instance, _subtype=sub_type)
              else:
                  msg = MIMEBase(main_type, sub_type)
                  msg.set_payload(attachment_instance) 
              msg.add_header('Content-Disposition', 'attachment', filename=attachment_name)
              mimeMessage.attach(msg) 
  
          raw_string = base64.urlsafe_b64encode(mimeMessage.as_string().encode()).decode()
          theMessage = {'raw': raw_string}
          return theMessage
      except: 
          self.GLogger.error(&quot;An error occurred in createEmaiLWithAttachments&quot;)
          tb = traceback.format_exc()
          self.GLogger.exception(tb)
          return False  
  </code></pre>
  <p>I would like to know what the <code>firewall</code> requirements are?</p>
  <ul>
  <li>Site/domain requirements</li>
  <li>Port requirements</li>
  <li>Protocol type (UDP or TCP)</li>
  </ul>
  <p>I tried searching for the port requirements and the site/domain requirements, but I didn't find any information for the <code>Gmail API</code>.</p>
  <p>I would need to know the <code>firewall</code> requirements for things such as:</p>
  <ul>
  <li>Authentication</li>
  <li>Refresh credentials</li>
  <li>Send email</li>
  <li>Fetch emails (messages.list, messages.get, threads.list etc.)</li>
  </ul>