Mitch97
Mitch97

Reputation: 150

Google Gmail API, works fine as .py but throws "googleapiclient.errors.UnknownApiNameOrVersion: name: gmail version: v1" when ran as .exe

The code runs perfectly in Pycharm, or when running the .py file but I need the app to be a .exe file to be ran on devices without python.

I am trying to allow a user to report a bug/give feedback in the app from a tkinter window. The feedback is then sent to me via the gmail-api.

The .exe file is made from pyinstaller (being ran from inside the virtual environment) When running the exe file everything works fine up until:

service = build(serviceName='gmail',
                        version='v1',
                        credentials=creds,
                        discoveryServiceUrl="https://gmail.googleapis.com/$discovery/rest?version=v1")

Where it produces

  File "googleapiclient\_helpers.py", line 134, in positional_wrapper
  File "googleapiclient\discovery.py", line 273, in build
  File "googleapiclient\discovery.py", line 387, in _retrieve_discovery_doc
googleapiclient.errors.UnknownApiNameOrVersion: name: gmail  version: v1

The code below is executed when a tkinter button is clicked.

The gmail code is almost completely copied from the google gmail api example.

Small code snippet:

from googleapiclient.discovery import build
from google_auth_oauthlib.flow import InstalledAppFlow
from google.auth.transport.requests import Request
from google.oauth2.credentials import Credentials
SCOPES = ['https://www.googleapis.com/auth/gmail.send']
def process_report():
        creds = None
        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(
                    'client_id.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())

        service = build(serviceName='gmail',
                        version='v1',
                        credentials=creds,
                        discoveryServiceUrl="https://gmail.googleapis.com/$discovery/rest?version=v1")

        msg = create_message("[email protected]",
                       "[email protected]",
                       subject, message)

        send_message(service, "me", msg)

Any help or suggestions is much appreciated.

Upvotes: 4

Views: 2833

Answers (3)

Niclas
Niclas

Reputation: 41

Downgrading google-api-python-client to 1.8.0 as suggested here worked for me as well.

Here is another solution which worked for me as well and seems to be the more elegant solution as no downgrade is necessary:

adding static_discovery=False in your build function solves this.

Your build function will sort of look like this build('drive', 'v3', credentials=creds, static_discovery=False)

Source: Python: Google Drive API v3 Can't Work After Converted to .exe Using Pyinstaller

Upvotes: 4

Eric Wu
Eric Wu

Reputation: 56

Had the exact same problem with Google classroom api. Worked as .py, didn't work as .exe when converted with pyinstaller. Exact same error, except with Google classroom api.

Exact same solution worked (revert google-api-python-client). I would've put a comment but I don't have enough points to comment.

Upvotes: 2

Mitch97
Mitch97

Reputation: 150

Resolved the issue by reverting the google-api-python-client to 1.8.0

pip install google-api-python-client==1.8.0

Upvotes: 6

Related Questions