为啥在 Zapier 中使用此代码时会出现 Runtime.MarshalError?

Posted

技术标签:

【中文标题】为啥在 Zapier 中使用此代码时会出现 Runtime.MarshalError?【英文标题】:Why am I getting a Runtime.MarshalError when using this code in Zapier?为什么在 Zapier 中使用此代码时会出现 Runtime.MarshalError? 【发布时间】:2019-06-21 18:27:08 【问题描述】:

下面的代码给了我:

Runtime.MarshalError:无法编组响应:'Yes' 不是 JSON 可序列化的

from calendar import monthrange

def time_remaining_less_than_fourteen(year, month, day):
    a_year = int(input['year'])
    b_month = int(input['month'])
    c_day = int(input['day'])
    days_in_month = monthrange(int(a_year), int(b_month))[1]
    time_remaining = ""

    if (days_in_month - c_day) < 14:
        time_remaining = "No"
        return time_remaining

    else:
        time_remaining = "Yes"
        return time_remaining


output = time_remaining_less_than_fourteen((input['year']), (input['month']), (input['day']))

#print(output)

当我删除 ... 时,它会抛出:'unicode' object has no attribute 'copy'

【问题讨论】:

【参考方案1】:

我在为 Kinesis Firehose 使用 lambda 转换蓝图 kinesis-firehose-process-record-python 时遇到了这个问题,这让我来到了这里。因此,我将向任何在遇到 lambda 问题时也发现此问题的人发布解决方案。

蓝图是:

from __future__ import print_function

import base64

print('Loading function')


def lambda_handler(event, context):
    output = []

    for record in event['records']:
        print(record['recordId'])
        payload = base64.b64decode(record['data'])

        # Do custom processing on the payload here

        output_record = 
            'recordId': record['recordId'],
            'result': 'Ok',
            'data': base64.b64encode(payload)
        
        output.append(output_record)

    print('Successfully processed  records.'.format(len(event['records'])))

    return 'records': output

需要注意的是,AWS 提供的 Firehose lambda 蓝图适用于 Python 2.7,不适用于 Python 3。原因是在 Python 3 中,字符串和字节数组是不同的。

使其与由 Python 3.x 运行时支持的 lambda 配合使用的关键更改是:

改变

'data': base64.b64encode(payload)

进入

'data': base64.b64encode(payload).decode("utf-8")

否则,由于无法使用从base64.b64encode 返回的字节数组序列化 JSON,lambda 出现错误。

【讨论】:

谢谢 Marcin,我遇到了同样的问题,你的回答让我省了很多麻烦。 Python 2.7 蓝图让我相信 Kinesis 期望 bytes 作为记录的数据。我什至没有想到转换为str。快速建议:base64.b64encode(payload).decode("utf-8") 可能只是 base64.b64encode(payload).decode()。根据定义,Base64 数据是 ASCII。 ASCII 本身是 UTF-8,这是 Python 3 中编码参数的默认值。在那里指定编解码器只是多余的。 @Rafa 很高兴我的回答对您有所帮助,并感谢您的好建议。 不确定你是从字面上还是在比喻上救了我的命,但无论哪种方式都感谢您的回答。^^ +1 感谢您节省我的时间@Marcin。有同样的问题,您的解决方案有效。【参考方案2】:

David 来自 Zapier 平台团队。

每the docs:

output:字典或字典列表将成为此代码的“返回值”。如果你愿意,你可以明确地提前返回。 这必须是 JSON 可序列化的!

在你的情况下,output 是一个集合:

>>> output = 'Yes'
>>> type(output)
<class 'set'>
>>> json.dumps(output)
Object of type set is not JSON serializable

要可序列化,您需要一个 dict(具有键和值)。更改你的最后一行以包含一个键,它会像你期望的那样工作:

#         \ here /
output = 'result': time_remaining_less_than_fourteen((input['year']), (input['month']), (input['day']))

【讨论】:

以上是关于为啥在 Zapier 中使用此代码时会出现 Runtime.MarshalError?的主要内容,如果未能解决你的问题,请参考以下文章

为啥在使用 Python/C API 时会出现此段错误?

为啥存储此向量时会出现分段错误?

为啥在控制台应用程序中使用 CommonOpenFileDialog 时会出现此异常?

为啥我使用 react-native juspay 开始付款时会出现此错误?

为啥使用 SingleAsync 时会出现此错误?

为啥 MySQL 在创建触发器时会出现此错误?