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

基于Raspberry Pi 3的Alexa Skill从Google Drive下载文件报错求助

解决Lambda函数中"Read-only file system"错误的方案

问题根源

你遇到的OSError: [Errno 30] Read-only file system错误,是因为AWS Lambda的运行环境默认只有/tmp目录具备可读写权限,其他目录(比如当前工作目录/var/task)都是只读的。你的代码尝试直接在当前目录创建abc.pdf文件,自然会触发这个错误。

第一步:修改文件保存路径到/tmp目录

把文件保存路径改为Lambda允许的临时目录/tmp,修改get_file函数里的文件名定义:

# 替换原来的filename定义
filename = os.path.join('/tmp', os.path.basename(urlparse(url).path))

同时,修复语音输出里的变量引用错误(你当前的代码里filename变量没有被正确插入到字符串中):

# 替换原来的speech_output
speech_output = f'The file {os.path.basename(filename)} has been downloaded'

另外,你的代码在return时引用了未定义的reprompt_text,需要补充定义:

# 在get_file函数里添加reprompt_text的定义
reprompt_text = ""  # 或者根据需求设置合适的提示文本

第二步:修复Google Drive下载的认证问题

注意:即使解决了文件系统的问题,你当前的Google Drive下载逻辑也大概率无法成功。因为https://drive.google.com/drive/my-drive/abc.pdf是网页链接,不是直接的文件下载链接,而且Google Drive不支持通过简单的auth=(username, password)方式进行认证。

如果你的文件是公开共享的,需要把链接转换成可直接下载的格式:

  1. 找到Google Drive文件的共享链接,格式通常是https://drive.google.com/file/d/[FILE_ID]/view
  2. 转换成下载链接:https://drive.google.com/uc?export=download&id=[FILE_ID]
  3. 把这个链接替换到你的代码里,不需要auth参数,直接用requests.get(url)即可。

如果你的文件是私有文件,需要使用Google Drive API进行认证:

  • 创建Google Cloud服务账号,生成密钥文件
  • 在Lambda中加载密钥,使用google-api-python-client库进行认证和文件下载(需要在Lambda层添加对应的依赖)

修改后的完整get_file函数示例

def get_file(intent, session):
    """ Grabs the files from the path that have to be downloaded """
    card_title = intent['name']
    session_attributes = {}
    should_end_session = True
    # 替换为正确的Google Drive直接下载链接
    url = 'https://drive.google.com/uc?export=download&id=你的文件ID'
    filename = os.path.join('/tmp', os.path.basename(urlparse(url).path))
    reprompt_text = ""
    
    try:
        r = requests.get(url)
        r.raise_for_status()  # 捕获HTTP请求错误
        with open(filename, 'wb') as out:
            for bits in r.iter_content(chunk_size=1024):
                out.write(bits)
        speech_output = f'The file {os.path.basename(filename)} has been downloaded successfully to Lambda\'s /tmp directory'
    except Exception as e:
        speech_output = f'Failed to download file: {str(e)}'
    
    return build_response(session_attributes, build_speechlet_response(
        card_title, speech_output, reprompt_text, should_end_session))

额外注意事项

  • Lambda的/tmp目录最大可用空间是512MB,且会话结束后(Lambda函数执行完成)该目录的内容可能会被清理,如果需要持久化文件,建议下载后上传到S3存储。
  • 如果需要把文件下载到你的Raspberry Pi,Lambda本身无法直接操作Pi的文件系统,你需要让Lambda发送消息到Pi(比如通过MQTT、HTTP请求等),由Pi自己执行下载操作。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 06:44:39