pythongoogle-cloud-platformgoogle-apigoogle-cloud-nl

Why am I getting the fiollowing error when calling the language_v1 API


I'm trying to call the language_v1 API but get the following error message:

google.api_core.exceptions.Unauthenticated: 401 Request had invalid authentication credentials. Expected OAuth 2 access token, login cookie or other valid authentication credential. See
https://developers.google.com/identity/sign-in/web/devconsole-project.

This is my code:

from google.cloud import language_v1
from google.oauth2 import service_account

SCOPES = 'https://www.googleapis.com/auth/cloud-language'
SERVICE_ACCOUNT_FILE = 'service_account.json'
credentials = service_account.Credentials.from_service_account_file(SERVICE_ACCOUNT_FILE, scopes=SCOPES)

client = language_v1.LanguageServiceClient(credentials=credentials)
type_ = language_v1.Document.Type.PLAIN_TEXT
language = "en"
text = "I love life!"
document = {"content": text, "type_": type_, "language": language}
encoding_type = language_v1.EncodingType.UTF8
response = client.analyze_sentiment(request={'document': document, 'encoding_type': encoding_type})
score = response.document_sentiment.score
print(score)

What could be the reason for the error?


Solution

  • You're using from_service_account_file incorrectly.

    See the Service Account private key files

    from google.cloud import language_v1
    from google.oauth2 import service_account
    
    SERVICE_ACCOUNT_FILE = 'service_account.json'
    
    # A list not a string
    SCOPES = ['https://www.googleapis.com/auth/cloud-language']
    
    credentials = service_account.Credentials.from_service_account_file(
        SERVICE_ACCOUNT_FILE
    )
    credentials=credentials.with_scopes(SCOPES)
    
    client = language_v1.LanguageServiceClient(credentials=credentials)
    type_ = language_v1.Document.Type.PLAIN_TEXT
    language = "en"
    text = "I love life!"
    document = {"content": text, "type_": type_, "language": language}
    encoding_type = language_v1.EncodingType.UTF8
    response = client.analyze_sentiment(request={
        'document': document,
        'encoding_type': encoding_type
    })
    score = response.document_sentiment.score
    print(score)
    

    It's almost always better to use Application Default Credentials:

    export GOOGLE_APPLICATION_CREDENTIALS=./service_account.json
    
    from google.cloud import language_v1
    
    import google.auth
    
    credentials, project = google.auth.default()
    
    SCOPES = ['https://www.googleapis.com/auth/cloud-language']
    credentials, project = google.auth.default(scopes=SCOPES)
    
    client = language_v1.LanguageServiceClient(credentials=credentials)
    
    type_ = language_v1.Document.Type.PLAIN_TEXT
    language = "en"
    text = "I love life!"
    document = {"content": text, "type_": type_, "language": language}
    encoding_type = language_v1.EncodingType.UTF8
    response = client.analyze_sentiment(request={
        'document': document,
        'encoding_type': encoding_type
    })
    score = response.document_sentiment.score
    print(score)
    

    And, in this case, because documents.analyzeSentiment accepts cloud-platform as a scope, you don't even need to rescope the credentials:

    from google.cloud import language_v1
    
    client = language_v1.LanguageServiceClient()
    
    type_ = language_v1.Document.Type.PLAIN_TEXT
    language = "en"
    text = "I love life!"
    document = {"content": text, "type_": type_, "language": language}
    encoding_type = language_v1.EncodingType.UTF8
    response = client.analyze_sentiment(request={
        'document': document,
        'encoding_type': encoding_type
    })
    score = response.document_sentiment.score
    print(score)