OAuth2client属性错误导致YouTube上传认证服务获取失败
问题
按照YouTube官方指南编写代码上传视频,三周前首次运行正常,通过浏览器完成OAuth2登录;如今凭证过期,无法重新上传。
相关代码片段:
def get_authenticated_service(): flow = flow_from_clientsecrets(CLIENT_SECRETS_FILE, scope=YOUTUBE_UPLOAD_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, []) return build(YOUTUBE_API_SERVICE_NAME, YOUTUBE_API_VERSION, http=credentials.authorize(httplib2.Http()))
遇到的错误:
/usr/local/lib/python3.11/site-packages/oauth2client/_helpers.py:255: UserWarning: Cannot access upload_youtube.py-oauth2.json: No such file or directory warnings.warn(_MISSING_FILE_MESSAGE.format(filename)) Traceback (most recent call last): File "~/upload_youtube.py", line 291, in <module> youtube = get_authenticated_service() ^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "~/upload_youtube.py", line 92, in get_authenticated_service credentials = run_flow(flow, storage, []) ^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/local/lib/python3.11/site-packages/oauth2client/_helpers.py", line 133, in positional_wrapper return wrapped(*args, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/local/lib/python3.11/site-packages/oauth2client/tools.py", line 195, in run_flow logging.getLogger().setLevel(getattr(logging, flags.logging_level)) ^^^^^^^^^^^^^^^^^^^ AttributeError: 'list' object has no attribute 'logging_level'
已卸载重装google-api-python-client和oauth2client,问题仍存在。
说明:
upload_youtube.py-oauth2.json是认证缓存文件,有效期1-2周,文件缺失时会出现警告(首次运行或删除文件时)。
解决方案
错误核心是run_flow函数的第三个参数传入了空列表[],但该函数需要的是包含logging_level属性的命令行参数对象,而非列表。修改方式如下:
方法一:使用官方命令行参数解析
- 确保导入
oauth2client.tools的argparser - 将
run_flow的第三个参数替换为解析后的命令行参数
修改后的代码:
from oauth2client import tools def get_authenticated_service(): flow = flow_from_clientsecrets(CLIENT_SECRETS_FILE, scope=YOUTUBE_UPLOAD_SCOPE, message=MISSING_CLIENT_SECRETS_MESSAGE) storage = Storage("%s-oauth2.json" % sys.argv[0]) credentials = storage.get() if credentials is None or credentials.invalid: # 解析命令行参数,替代原有的空列表 flags = tools.argparser.parse_args() credentials = run_flow(flow, storage, flags) return build(YOUTUBE_API_SERVICE_NAME, YOUTUBE_API_VERSION, http=credentials.authorize(httplib2.Http()))
方法二:手动构造参数对象(无需命令行参数)
如果不需要处理命令行参数,可以手动构造一个包含logging_level属性的对象:
def get_authenticated_service(): flow = flow_from_clientsecrets(CLIENT_SECRETS_FILE, scope=YOUTUBE_UPLOAD_SCOPE, message=MISSING_CLIENT_SECRETS_MESSAGE) storage = Storage("%s-oauth2.json" % sys.argv[0]) credentials = storage.get() if credentials is None or credentials.invalid: # 手动构造flags对象,设置默认日志级别 class Flags: logging_level = 'INFO' flags = Flags() credentials = run_flow(flow, storage, flags) return build(YOUTUBE_API_SERVICE_NAME, YOUTUBE_API_VERSION, http=credentials.authorize(httplib2.Http()))
修改后运行代码,会重新触发浏览器OAuth2登录流程,生成新的upload_youtube.py-oauth2.json缓存文件,之后即可正常上传视频。
内容的提问来源于stack exchange,提问作者ginjaemocoes
相关产品推荐
相关产品推荐

