Python 中有一个云函数,当文件上传到 firebase 的存储桶时,它会处理一些数据:
@storage_fn.on_object_finalized(bucket = "my-bucket", timeout_sec = timeout_sec, memory = memory, cpu = cpu, region='us-central1')
def validate_file_upload(event: storage_fn.CloudEvent[storage_fn.StorageObjectData]):
process(event)
当通过 firebase cli 部署时,该函数可以正常工作
firebase deploy --only functions:validate_file_upload
但是,当通过 gcloud 部署相同的函数时
gcloud functions deploy validate_file_upload
--gen2
--region=us-central1
.......
--entry-point=validate_file_upload
--trigger-event-filters="type=google.cloud.storage.object.v1.finalized"
--trigger-event-filters="bucket=my-bucket"
当函数被触发,失败并显示
TypeError: validate_file_upload() gets 1positional argument but 2 were generated
原因是,当通过
firebase
部署函数时,GCP 将“Eventarc”对象作为单个参数发送给云函数,但如果通过
gcloud
部署它,它会发送两个:(数据,上下文),自然会导致异常
即使在文档中,它也声明应该只有 1 个参数:
Cloud Storage 触发器被实现为CloudEvent 函数,其中 Cloud Storage 事件数据以 CloudEvents 格式传递到您的函数
https://cloud.google.com/functions/docs/calling/storage
如何确保
gcloud
部署使用正确的函数原型?
观察到的行为是由于在使用
gcloud
部署函数时指定了
--trigger-event-filters
标志。当使用此标志时,是在创建一个使用
存储触发器
(旧版)而不是
Eventarc 触发器
(推荐)的第 1 代 Cloud Function。存储触发器传递两个参数(数据,上下文),而 Eventarc 触发器传递一个 CloudEvent 对象。
要使用
gcloud
部署使用 Eventarc 触发器的第 2 代 Cloud Function(就像使用 Firebase CLI 一样),需要使用
--trigger-resource
和
--trigger-event
标志而不是
--trigger-event-filters
。
以下是使用
gcloud
部署函数的更正命令:
gcloud functions deploy validate_file_upload \
--gen2 \
--region=us-central1 \
...其他选项... \
--runtime python310 \
--entry-point=validate_file_upload \
--trigger-resource=your-bucket-name \
--trigger-event=google.cloud.storage.object.v1.finalized
请确保替换以下内容:
- your-bucket-name : 存储桶的实际名称。
此命令使用以下选项:
-
--trigger-resource
: 指定触发函数的资源,在本例中是的 Cloud Storage 存储桶。 -
--trigger-event
: 指定触发函数的事件类型,在本例中是google.cloud.storage.object.v1.finalized
。
通过使用这些选项,将创建一个使用 Eventarc 触发器的第 2 代 Cloud Function,该函数将单个 CloudEvent 对象传递给的
validate_file_upload
函数,从而解决的问题。