You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PyInstaller打包Google Analytics依赖时出现UnknownApiNameOrVersion错误

问题描述

使用以下导入语句:

from apiclient import discovery
from oauth2client.service_account import ServiceAccountCredentials

尝试用PyInstaller将脚本打包为单文件exe,命令如下:

pyinstaller --onefile -w --icon=icon.ico --add-data client_secrets.json;. main.py  --collect-data "google-api-python-client" --collect-data "oauth2client";

也试过:

pyinstaller --onefile -w --icon=icon.ico --add-data client_secrets.json;. main.py  --collect-data google-api-python-client --collect-data oauth2client;

但运行生成的exe时出现错误:

Failed to execute script 'main' due to unhandled exception: name analytics version: v3
File "main.py", line 81, in <module>
File "main.py", line 32, in get_service
File "googleapiclient\_helpers.py", line 130, in positional_wrapper
File "googleapiclient\discovery.py", line 287, in build
File "googleapiclient\discovery.py", line 404, in _retrieve_discovery_doc
googleapiclient.errors.UnknownApiNameOrVersion: name: analytics  version: v3

原Python脚本运行正常,复现代码如下:

from apiclient import discovery
from oauth2client.service_account import ServiceAccountCredentials
import os

dir_path = os.path.dirname(os.path.realpath(__file__))

def get_service(api_name, api_version, scopes, key_file_location):
    credentials = ServiceAccountCredentials.from_json_keyfile_name(
            key_file_location, scopes=scopes)

    # Build the service object.
    # service = build(api_name, api_version, credentials=credentials)
    service = discovery.build(api_name, api_version, credentials=credentials)
    return service

if __name__ == '__main__':
    scope = 'https://www.googleapis.com/auth/analytics.edit'
    # client_secret from console.cloud.google.com
    key_file_location = f'{dir_path}/client_secrets.json'

    # Authenticate and construct service.
    service = get_service(
            api_name='analytics',
            api_version='v3',
            scopes=[scope],
            key_file_location=key_file_location)
解决方法

这个错误核心是PyInstaller打包时未完整包含Google API客户端的发现文档——discovery.build默认依赖本地缓存或网络获取的API描述文件,打包后的单文件exe无法正常访问这些资源。以下是几种可靠的解决方式:

方法1:改用--collect-all强制完整打包依赖

--collect-data可能没覆盖到google-api-python-client的所有必要文件,用--collect-all强制收集整个依赖包的全部内容:

pyinstaller --onefile -w --icon=icon.ico --add-data "client_secrets.json;." --collect-all google-api-python-client --collect-all oauth2client main.py

方法2:手动使用本地发现文档构建服务

  1. 获取Analytics v3的API发现文档JSON,保存为analytics_v3.json,放在脚本同级目录。
  2. 修改代码,让discovery.build读取本地文档而非发起网络请求:
def get_service(api_name, api_version, scopes, key_file_location):
    credentials = ServiceAccountCredentials.from_json_keyfile_name(
            key_file_location, scopes=scopes)
    
    # 读取本地的Analytics v3发现文档
    import json
    with open(f'{dir_path}/analytics_v3.json', 'r') as f:
        discovery_doc = json.load(f)
    
    # 基于本地文档构建服务对象
    service = discovery.build_from_document(discovery_doc, credentials=credentials)
    return service
  1. 打包时将新增的JSON文件也加入资源列表:
pyinstaller --onefile -w --icon=icon.ico --add-data "client_secrets.json;." --add-data "analytics_v3.json;." main.py

方法3:确保缓存路径可访问(备选)

先运行一次脚本,让Google API客户端将发现文档缓存到本地默认路径,然后打包时将缓存目录的文件加入--add-data,同时在代码中设置discovery.build的cache_discovery=True。这种方法依赖系统缓存路径,稳定性不如前两种,优先推荐方法1或2。

内容的提问来源于stack exchange,提问作者squidg

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 09:55:24