title: Python 2to3 conversion of imported Google libraries
body: <p>I have succesfully run the <a href="https://github.com/youtube/api-samples/blob/master/python/upload_video.py" rel="nofollow noreferrer">Python2 Google Example Youtube upload code.</a> Now, i want to try converting this code to Python3. When i convert it with 2to3 tool, the result is like below. And if i try to run it with Python3 i get an error such below. I use Rasbian OS. Which Python3 libraries am i have to import instead of <code>google.oauth2.credentials</code>, <code>google_auth_oauthlib.flow</code>, <code>google_auth_oauthlib.flow</code>?</p>
  <h3>Converted Python3 code:</h3>
  <pre><code>import argparse
  import http.client
  import httplib2
  import os
  import random
  import time
  
  import google.oauth2.credentials
  import google_auth_oauthlib.flow
  from googleapiclient.discovery import build
  from googleapiclient.errors import HttpError
  from googleapiclient.http import MediaFileUpload
  from google_auth_oauthlib.flow import InstalledAppFlow
  
  
  # Explicitly tell the underlying HTTP transport library not to retry, since
  # we are handling retry logic ourselves.
  httplib2.RETRIES = 1
  
  # Maximum number of times to retry before giving up.
  MAX_RETRIES = 10
  
  # Always retry when these exceptions are raised.
  RETRIABLE_EXCEPTIONS = (httplib2.HttpLib2Error, IOError, http.client.NotConnected,
    http.client.IncompleteRead, http.client.ImproperConnectionState,
    http.client.CannotSendRequest, http.client.CannotSendHeader,
    http.client.ResponseNotReady, http.client.BadStatusLine)
  
  # Always retry when an apiclient.errors.HttpError with one of these status
  # codes is raised.
  RETRIABLE_STATUS_CODES = [500, 502, 503, 504]
  
  # The CLIENT_SECRETS_FILE variable specifies the name of a file that contains
  # the OAuth 2.0 information for this application, including its client_id and
  # client_secret. You can acquire an OAuth 2.0 client ID and client secret from
  # the {{ Google Cloud Console }} at
  # {{ https://cloud.google.com/console }}.
  # Please ensure that you have enabled the YouTube Data API for your project.
  # For more information about using OAuth2 to access the YouTube Data API, see:
  #   https://developers.google.com/youtube/v3/guides/authentication
  # For more information about the client_secrets.json file format, see:
  #   https://developers.google.com/api-client-library/python/guide/aaa_client_secrets
  CLIENT_SECRETS_FILE = 'client_secret.json'
  
  # This OAuth 2.0 access scope allows an application to upload files to the
  # authenticated user's YouTube channel, but doesn't allow other types of access.
  SCOPES = ['https://www.googleapis.com/auth/youtube.upload']
  API_SERVICE_NAME = 'youtube'
  API_VERSION = 'v3'
  
  VALID_PRIVACY_STATUSES = ('public', 'private', 'unlisted')
  
  
  # Authorize the request and store authorization credentials.
  def get_authenticated_service():
    flow = InstalledAppFlow.from_client_secrets_file(CLIENT_SECRETS_FILE, SCOPES)
    credentials = flow.run_console()
    return build(API_SERVICE_NAME, API_VERSION, credentials = credentials)
  
  def initialize_upload(youtube, options):
    tags = None
    if options.keywords:
      tags = options.keywords.split(',')
  
    body=dict(
      snippet=dict(
        title=options.title,
        description=options.description,
        tags=tags,
        categoryId=options.category
      ),
      status=dict(
        privacyStatus=options.privacyStatus
      )
    )
  
    # Call the API's videos.insert method to create and upload the video.
    insert_request = youtube.videos().insert(
      part=','.join(list(body.keys())),
      body=body,
      # The chunksize parameter specifies the size of each chunk of data, in
      # bytes, that will be uploaded at a time. Set a higher value for
      # reliable connections as fewer chunks lead to faster uploads. Set a lower
      # value for better recovery on less reliable connections.
      #
      # Setting 'chunksize' equal to -1 in the code below means that the entire
      # file will be uploaded in a single HTTP request. (If the upload fails,
      # it will still be retried where it left off.) This is usually a best
      # practice, but if you're using Python older than 2.6 or if you're
      # running on App Engine, you should set the chunksize to something like
      # 1024 * 1024 (1 megabyte).
      media_body=MediaFileUpload(options.file, chunksize=-1, resumable=True)
    )
  
    resumable_upload(insert_request)
  
  # This method implements an exponential backoff strategy to resume a
  # failed upload.
  def resumable_upload(request):
    response = None
    error = None
    retry = 0
    while response is None:
      try:
        print('Uploading file...')
        status, response = request.next_chunk()
        if response is not None:
          if 'id' in response:
            print('Video id &quot;%s&quot; was successfully uploaded.' % response['id'])
          else:
            exit('The upload failed with an unexpected response: %s' % response)
      except HttpError as e:
        if e.resp.status in RETRIABLE_STATUS_CODES:
          error = 'A retriable HTTP error %d occurred:\n%s' % (e.resp.status,
                                                               e.content)
        else:
          raise
      except RETRIABLE_EXCEPTIONS as e:
        error = 'A retriable error occurred: %s' % e
  
      if error is not None:
        print(error)
        retry += 1
        if retry &gt; MAX_RETRIES:
          exit('No longer attempting to retry.')
  
        max_sleep = 2 ** retry
        sleep_seconds = random.random() * max_sleep
        print('Sleeping %f seconds and then retrying...' % sleep_seconds)
        time.sleep(sleep_seconds)
  
  def uploadvideo(file, title, description, category, keywords, privacy_status):
      parser = argparse.ArgumentParser()
      parser.add_argument('--file', required=False, help='Video file to upload', default=file)
      parser.add_argument('--title', help='Video title', default=title)
      parser.add_argument('--description', help='Video description', default=description)
      parser.add_argument('--category', default=category,
      help='Numeric video category. ' +
        'See https://developers.google.com/youtube/v3/docs/videoCategories/list')
      parser.add_argument('--keywords', help='Video keywords, comma separated',
      default=keywords)
      parser.add_argument('--privacyStatus', choices=VALID_PRIVACY_STATUSES,
      default=privacy_status, help='Video privacy status.')
      args = parser.parse_args()
  
      youtube = get_authenticated_service()
  
      try:
          initialize_upload(youtube, args)
      except HttpError as e:
          print('An HTTP error %d occurred:\n%s' % (e.resp.status, e.content))
  </code></pre>
  <h2>Error:</h2>
  <pre><code>(venv) pi@raspberrypi:/var/www/html/GetVideo $ python3 upload_main.py
  Traceback (most recent call last):
    File &quot;upload_main.py&quot;, line 1, in &lt;module&gt;
      import upload_video as upload_video
    File &quot;/var/www/html/GetVideo/upload_video.py&quot;, line 10, in &lt;module&gt;
      import google.oauth2.credentials
  ImportError: No module named 'google'
  </code></pre>