gcloud 将事件触发器误认为是存储触发器

问题描述 投票:0回答:1

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() 需要 1 个位置参数,但给出了 2 个

原因是,当通过

firebase
部署函数时,GCP将“Eventarc”对象作为单个参数发送给云函数,但如果通过
gcloud
部署,它会发送两个:(数据,上下文),自然会导致异常

即使在文档中也指出应该只有 1 个参数:

Cloud Storage 触发器作为 CloudEvent 函数实现,其中 Cloud Storage 事件数据以 CloudEvents 格式传递到您的函数

https://cloud.google.com/functions/docs/calling/storage

如何确保

gcloud
部署使用正确的函数原型?

python firebase google-cloud-functions google-cloud-storage gcloud
1个回答
0
投票

答案是使用双装饰器:

import functions_framework
from cloudevents.http import CloudEvent

from firebase_functions import storage_fn, options

@functions_framework.cloud_event
@storage_fn.on_object_finalized(bucket = "my-bucket", timeout_sec = timeout_sec, memory = memory, cpu = cpu, region='us-central1')
def decode_and_process_metrics_fsdb_us(event: CloudEvent):
    process(event)

这样,无论是通过 gcloud 还是 firebase 部署,它都可以工作。

我还注意到,如果该函数最初是使用 HTTP 触发器而不是“存储桶”触发器部署的,那么它在 GCP 中会保持标记为 HTTP,直到您删除它并重新部署。简单的重新部署会将此函数标记为 HTTP(尽管在“触发器”选项卡中,它将按预期显示存储桶的事件)

screenshot of Cloud Functions overview showing Bucket and HTTP trigger types

© www.soinside.com 2019 - 2024. All rights reserved.