gcsfs 2021.4.0异步接口无法运行:执行示例代码触发异常
报错原因与修复方案
根因说明
- 你参考的示例来自gcsfs早期版本,和当前安装的2021.4.0版本API存在不兼容:
- 第一个
AttributeError:set_session方法在2020年后的版本中已被完全移除。当前版本无需手动调用该方法初始化会话,客户端会在首次发起异步请求时自动完成会话创建。 - 第二个
RuntimeError: Loop is not running:移除set_session后触发文件初始化流程时,GCSFile构造函数会同步调用fs.info()获取目标文件的元数据。由于当前文件系统实例为异步模式,该同步调用会触发fsspec框架的逻辑校验——当前事件循环已在异步任务中运行,不允许嵌套启动同步循环,因此抛出错误。
gcsfs内置了路径元数据缓存机制,提前异步查询目标路径的元数据后,文件初始化时的同步info调用会直接命中缓存,不会触发异步IO逻辑,可有效规避该循环冲突。
- 第一个
可运行的修正代码
import asyncio import gcsfs async def main(): # 无需手动传入loop参数,无需调用已废弃的set_session方法 fs = gcsfs.GCSFileSystem(project="my_project", asynchronous=True) target_path = "my_bucket/my_blob" # 提前异步查询路径元数据,触发缓存写入,避免后续文件初始化时的同步调用冲突 await fs._info(target_path) # 打开异步文件对象 async_file = await fs._open(target_path, "rb") content = await async_file.read() print(len(content)) # 释放异步HTTP客户端的会话资源 await fs._close_session() # Python3.8+ 推荐使用asyncio.run启动事件循环,替代手动获取循环的写法 asyncio.run(main())
注意事项
- 异步模式下,不要直接调用不带
_前缀的同步方法(如fs.open()、fs.info()),这类方法会触发同步/异步嵌套逻辑,大概率引发循环冲突。所有异步IO操作需使用带下划线前缀的对应异步方法。 - 操作完成后必须主动调用
fs._close_session()释放连接资源,避免异步HTTP客户端造成连接泄漏。 - 不要手动向GCSFileSystem传入自定义事件循环对象,Python3.8+的asyncio会自动将当前运行的循环绑定到异步客户端,手动传入反而可能造成循环对象不匹配的问题。
内容的提问来源于stack exchange,提问作者user5406764
相关产品推荐
相关产品推荐

