AWS Lambda Python - 返回 BytesIO 文件?

8
我正在使用Python 3.7在AWS Lambda中设置一个函数,但它不允许我返回字节类型。
请注意,这并不是API Gateway的问题,我是直接调用lambda。
错误是:Runtime.MarshalError,... 不可JSON序列化。
output = BytesIO()
#Code that puts an excel file into output...
return {
        'Content-Disposition': 'attachment; filename="export.xlsx"',
        'Content-Type': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
        'body' : output.getvalue()
    }

如果我执行:

'body' : str(output.getvalue())

由于在字符串后面添加了b'',导致输出一个损坏的文件。

如果我这样做:

'body' : base64.b64encode(output.getvalue()).decode()

此外,它还会输出一个损坏的文件,可能是因为它改变了文件的二进制表示。

也许我需要上传到S3?但它不符合我的流程,这是一次性文件创建,而且文件将停留在"S3 Limbo"中直到TTL。


output.getvalue().decode('utf-8') 可以解决“不可JSON序列化”的问题。这样做有帮助吗? - Martin Valgur
@MartinValgur,它不是,它是一个二进制字节流,它会给出“utf-8”编解码器无法解码第16个位置的0xda字节:无效的连续字节。 - Mojimi
@MartinValgur,不是的,那个问题与API网关有关,我已经提到我没有使用它。 - Mojimi
你尝试过使用output.read()吗? - Jan Giacomelli
朋友们,这是不可能的。 - Erik
1个回答

2

无法从直接调用的AWS Lambda函数返回未编码的二进制数据。

根据文档

如果处理程序返回无法通过json.dumps序列化的对象,则运行时会返回错误。

您可以使用API Gateway实现此操作的原因是,API Gateway正在将函数返回的base64 JSON内容转换为二进制。 (请参见此处的文档)

我需要更多了解您如何调用Lambda才能确定,但我怀疑您可以将相同的base64解码逻辑实现到直接调用的客户端中。或者,如果您想尽可能简化客户端,请使用S3并使用生命周期钩子来防止存储桶填满临时文件。


1
Downvotes很有趣。抱歉,但是无论你有多不喜欢,都不能从直接调用的lambda函数中返回未编码的二进制流。 - Erik
这个答案现在是否已经过时了?你的链接现在指向一个名为“通过API网关启用二进制支持”的页面。 - maxwell
哦,进一步阅读后,似乎只有通过传递到S3存储桶而不是使用Lambda作为集成类型才可能实现。 - maxwell

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接