question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

UnknownApiNameOrVersion when using 'googleapiclient.discovery' to build 'mybusiness'

See original GitHub issue

I’m using Google’s My Business API via Google’s API Python Client Library (v2.41.0).

Without further ado, here is a complete code example:

from dotenv import load_dotenv
from google_auth_oauthlib.flow import InstalledAppFlow
from googleapiclient.discovery import build
from os.path import exists
from pprint import pprint
import os
import pickle

load_dotenv()

API_DEVELOPER_KEY = os.getenv('API_DEVELOPER_KEY')
API_SCOPE = os.getenv('API_SCOPE')
STORED_CLIENT_CREDENTIALS = os.getenv('STORED_CLIENT_CREDENTIALS')
GOOGLE_APPLICATION_CREDENTIALS = os.getenv('GOOGLE_APPLICATION_CREDENTIALS')


def get_google_credentials(path=STORED_CLIENT_CREDENTIALS):
    '''Loads stored credentials. Gets and stores new credentials if necessary.'''
    if exists(path):
        pickle_in = open(path, 'rb')
        credentials = pickle.load(pickle_in)
    else:
        flow = InstalledAppFlow.from_GOOGLE_APPLICATION_CREDENTIALS_file(
            GOOGLE_APPLICATION_CREDENTIALS_file=GOOGLE_APPLICATION_CREDENTIALS, scopes=API_SCOPE)
        flow.run_local_server()
        credentials = flow.credentials
        store_google_credentials(credentials)
    return credentials


def store_google_credentials(credentials, path=STORED_CLIENT_CREDENTIALS):
    '''Store credentials for future reuse to avoid authenticating every time.'''
    pickle_out = open(path, 'wb')
    pickle.dump(credentials, pickle_out)
    pickle_out.close()


def get_google_api_interface(credentials, service_name, service_version, service_discovery_url=None):
    '''Get a resource object with methods for interacting with Google's API.'''
    return build(service_name,
                 service_version,
                 credentials=credentials,
                 developerKey=API_DEVELOPER_KEY,
                 discoveryServiceUrl=service_discovery_url)


def extract_dict_key(dict, key):
    '''Utility to extract particular values from a dictionary by their key.'''
    return [d[key] for d in dict]


def transform_list_to_string(list, separator=' '):
    return separator.join(map(str, list))


def get_google_account_names():
    '''Get a list of all account names (unique ids).'''
    google = get_google_api_interface(
        get_google_credentials(),
        service_name='mybusinessaccountmanagement',
        service_version='v1',
        service_discovery_url='https://mybusinessaccountmanagement.googleapis.com/$discovery/rest?version=v1')
    accounts = google.accounts().list().execute()
    return extract_dict_key(accounts['accounts'], 'name')


def get_google_store_reviews(account_name):
    '''Get all store reviews for a specific account from Google My Business.'''
    google = get_google_api_interface(
        get_google_credentials(),
        service_name='mybusiness',
        service_version='v4',
        service_discovery_url='https://mybusiness.googleapis.com/$discovery/rest?version=v4')
    return google.accounts().locations().batchGetReviews(account_name).execute()


account_names = get_google_account_names()

pprint(account_names)

first_account_name = account_names[0]

pprint(get_google_store_reviews(first_account_name))

And here is the contents of .env:

API_DEVELOPER_KEY = ********
API_SCOPE = https://www.googleapis.com/auth/business.manage
STORED_CLIENT_CREDENTIALS = secrets/credentials.pickle
GOOGLE_APPLICATION_CREDENTIALS = secrets/client_secrets.json

My function get_google_account_names() works fine and returns the expected data:

['accounts/******************020',
 'accounts/******************098',
 'accounts/******************872',
 'accounts/******************021',
 'accounts/******************112']

I have tested and validated get_google_credentials() to ensure that CLIENT_CREDENTIALS and API_DEVELOPER_KEY are indeed loaded correctly and working.

Also, in .env, I’m setting the environment variable GOOGLE_APPLICATION_CREDENTIALS to the client_secret.json path, as required some methods in Google’s Python Client Library.

My function get_google_store_reviews(), however, results in this error:

Traceback (most recent call last):
  File "/my-project-dir/my-script.py", line 88, in <module>
    pprint(get_google_store_reviews())
  File "/my-project-dir/my-script.py", line 76, in get_google_store_reviews
    google = get_google_api_interface(
  File "/my-project-dir/my-script.py", line 46, in get_google_api_interface
    return build(service_name,
  File "/my-project-dir/.venv/lib/python3.9/site-packages/googleapiclient/_helpers.py", line 131, in positional_wrapper
    return wrapped(*args, **kwargs)
  File "/my-project-dir/.venv/lib/python3.9/site-packages/googleapiclient/discovery.py", line 324, in build
    raise UnknownApiNameOrVersion("name: %s  version: %s" % (serviceName, version))
googleapiclient.errors.UnknownApiNameOrVersion: name: mybusiness  version: v4

I have also tried v1 of the Discovery Document with the same result.

Does anyone know what’s going on here? It seems like the API mybusiness is not discoverable via the Discovery Document provided by Google, but I’m not sure how to verify my suspicion.

Note that this and this issue is related, but not exactly the same. The answers in those questions are old don’t seem to be applicable anymore after recent changes by Google.

Some parts of the mybusiness API appear to be deprecated, which might explain these issues.

But Google’s documentation also states:

“Deprecated indicates that the version of the API will continue to function […]”

Furthermore, notice that even though the top-level accounts.locations is marked as deprecated, some other the underlying methods (including batchGetReviews) are not, which adds to my confusion.

See screenshot for more details:

Google's Deprecation Dchedule Documentation

This issue has also been posted as a question on Stack Overflow.

Issue Analytics

  • State:closed
  • Created a year ago
  • Reactions:1
  • Comments:12 (5 by maintainers)

github_iconTop GitHub Comments

1reaction
busunkim96commented, Mar 31, 2022

The engineer shared https://developers.google.com/my-business/samples/previousVersions with me. https://developers.google.com/my-business/samples/mybusiness_google_rest_v4p9.json appears to be the last copy of the discovery document for mybusiness v4.

Could you try setting discoveryServiceUrl to that and see if you’re able to successfully make calls?

service = discovery.build(
    "mybusiness",
    "v4",
    static_discovery=False,
    discoveryServiceUrl='https://developers.google.com/my-business/samples/mybusiness_google_rest_v4p9.json',
    developerKey=os.getenv('API_DEVELOPER_KEY')
)
1reaction
busunkim96commented, Mar 30, 2022

@leifericf Oops yes, that was definitely a typo.

mybusiness v4 and mybusinessaccountmanagement have a very different onboarding process and are different APIs. For eg: mybusinessaccountmanagement is public by default and mybusiness v4 is private. So if the key works on one, there is no guarantee it will work on another.

The My Business API engineer responded hat the two APIs you’re using are different in some ways, so the API key working for one might not necessarily mean it works on the other.

I just shared the NOT_FOUND response with them, hopefully they’ll be able to point to the steps needed to access the API.

Read more comments on GitHub >

github_iconTop Results From Across the Web

UnknownApiNameOrVersion from Google's My Business API ...
It seems like the API mybusiness is not discoverable via the Discovery Document provided by Google, but I'm not sure how to verify...
Read more >
googleapiclient.errors.UnknownApiNameOrVersion: name ...
I was able to re-create the issue. The correct url for the discovery artifact is https://blogger.googleapis.com/$discovery/rest?version=v3 ...
Read more >
Libraries | Google Business Profile APIs - Google Developers
API Client library Client library reference Code samples Account Management API Discovery doc Java Reference docs View on Git... Account Management API Discovery doc Python...
Read more >
import "googleapiclient.discovery" could not be resolved - You.com ...
Additional context, I am trying to build a Python script which accesses Google Slides to perform some processing on slide content. I am...
Read more >
discovery.py - Google Git
from googleapiclient.errors import UnknownApiNameOrVersion ... Same as `build()`, but constructs the Resource object from a discovery.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found