Dav Alf
Dav Alf

Reputation: 53

AttributeError while trying to retrieve youtube comments throught the Youtube data API V3

I'm trying to retrieve the comment threads of a youtube video using Python. I've been breaking my brain and looking for a solution online for about two weeks but it seems there is none adapted to my problem. I tried to follow the examples on the Youtube data API website but it lacks a bit of clarity sometimes. Specially in adapting a request on the platform to code. In my case, I think my problem is due to the fact that I don't really know what correspond to the 'youtube' object in the folowing code.

import httplib2
import os
import sys

from apiclient.discovery import build_from_document
from apiclient.errors import HttpError
from oauth2client.client import flow_from_clientsecrets
from oauth2client.file import Storage
from oauth2client.tools import argparser, run_flow

# 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 = "../***************.json"

# This OAuth 2.0 access scope allows for full read/write access to the
# authenticated user's account and requires requests to use an SSL connection.
YOUTUBE_READ_WRITE_SSL_SCOPE = "https://www.googleapis.com/auth/youtube.force-ssl"
YOUTUBE_API_SERVICE_NAME = "youtube"
YOUTUBE_API_VERSION = "v3"

# This variable defines a message to display if the CLIENT_SECRETS_FILE is
# missing.
MISSING_CLIENT_SECRETS_MESSAGE = """
WARNING: Please configure OAuth 2.0
To make this sample run you will need to populate the client_secrets.json file
found at:
   %s
with information from the APIs Console
https://console.developers.google.com
For more information about the client_secrets.json file format, please visit:
https://developers.google.com/api-client-library/python/guide/aaa_client_secrets
""" % os.path.abspath(os.path.join(os.path.dirname(__file__),
                               CLIENT_SECRETS_FILE))

# Authorize the request and store authorization credentials.
def get_authenticated_service(args):
  flow = flow_from_clientsecrets(CLIENT_SECRETS_FILE, scope=YOUTUBE_READ_WRITE_SSL_SCOPE,
    message=MISSING_CLIENT_SECRETS_MESSAGE)

  storage = Storage("%s-oauth2.json" % sys.argv[0])
  credentials = storage.get()

  if credentials is None or credentials.invalid:
    credentials = run_flow(flow, storage, args)

  # Trusted testers can download this discovery document from the developers page
  # and it should be in the same directory with the code.
  with open("youtube-v3-discoverydocument.json", "r") as f:
    doc = f.read()
    return build_from_document(doc, http=credentials.authorize(httplib2.Http()))

# Call the API's commentThreads.list method to list the existing comments.
def get_comments(youtube, video_id, channel_id):
  results = youtube.commentThreads().list(
    part="snippet",
    videoId=video_id,
    channelId=channel_id,
    textFormat="plainText"
  ).execute()

  for item in results["items"]:
    comment = item["snippet"]["topLevelComment"]
    author = comment["snippet"]["authorDisplayName"]
    text = comment["snippet"]["textDisplay"]
    print "Comment by %s: %s" % (author, text)

  return results["items"]

get_comments("https://www.youtube.com/", "C_jByE6Cxv8", "UCww2zZWg4Cf5xcRKG-ThmXQ")

I keep getting a 'str' object has no attribute 'commentThreads' And I guess that's not the only error I'll have but I'm not able to surpass this one, so if anyone has an Idea why I'm getting this error or if anyone sees any other mistake in the code, please let me know. Thanks a lot to everyone in Stackoverflow, this is a really incredible site for newbies like me.

Upvotes: 1

Views: 492

Answers (1)

xavier
xavier

Reputation: 816

I will answer to the question of why the "Youtube object" has no attribute "commentThreads" :

It is because on the Youtube Data API V3 examples, which are uniquely demonstrated on a CLI mode program, they use "youtube" to name a variable that contains a function, which is normally the authentication function. That is why you are getting that error. You are trying to add an attribute to a variable that does not exist, but to an string object.

You want to create a function that holds the authentication block and then create a variable called "youtube" that contains the authentication function. Then it will work.

I know the examples are strictly limited to CLI style programs and are hard to follow for newbies, but it is well worth the investment. Keep on digging (c:

EDIT :

To make it a little bit more clear ( this is just pseudo-code for you to understand ) :

def get_auth():

  flow = flow_from_clientsecrets(CLIENT_SECRETS_FILE, scope=YOUTUBE_READ_WRITE_SSL_SCOPE,
    message=MISSING_CLIENT_SECRETS_MESSAGE)

  storage = Storage("%s-oauth2.json" % sys.argv[0])
  credentials = storage.get()

  if credentials is None or credentials.invalid:
    credentials = run_flow(flow, storage, args)



youtube = get_auth()

youtube.commentThreads().list

Then you will essentially be "gluing" the authentication to the request. You are basically building a request to be sent to the Youtube servers. The problem is the library is doing everything behind the scenes for you and you can't really see what is going on or how it works unless you dig in to the library code. You will have to improve your reverse engineering skills to debunk the riddle of the CLI example.

Upvotes: 1

Related Questions