无法在云函数中使用 gcp 云调度程序的 json 主体作为参数值?

Posted

技术标签:

【中文标题】无法在云函数中使用 gcp 云调度程序的 json 主体作为参数值?【英文标题】:Unable to use json body of gcp cloud scheduler in cloud function as parameter value? 【发布时间】:2020-01-25 00:04:43 【问题描述】:

我有一个云调度程序,我用它来触发我的云功能作为 http 调用,在我的云功能中我想形成一个查询(应该是动态的)。为此,我从云调度程序(Json Body)传递了一些参数,但是当我触发我的云函数时,它不会将来自云调度程序的参数值作为 json 主体。谁能帮我解决这个问题。

来自云调度程序的 json 正文:

 
   "unit":"QA",
   "interval":"3"

云功能代码:

def main(request):

    request_json = request.get_json(silent=True)
    request_args = request.args

    if request_json and 'unit' in request_json:
        retail_unit = request_json['unit']
    elif request_args and 'unit' in request_args:
        retail_unit = request_args['unit']
    else:
        unit = 'UAT'

    if request_json and 'interval' in request_json:
        interval = request_json['interval']
    elif request_args and 'interval' in request_args:
        interval = request_args['interval']
    else:
        interval = 1

    query = "select * from `myproject.mydataset.mytable` where unit='' and interval =".format(                                                                                                    
    unit,interval)
    client = bigquery.Client()
    job_config = bigquery.QueryJobConfig()
    dest_dataset = client.dataset(destination_dataset, destination_project)
    dest_table = dest_dataset.table(destination_table)
    job_config.destination = dest_table
    job_config.create_disposition = 'CREATE_IF_NEEDED'
    job_config.write_disposition = 'WRITE_APPEND'
    job = client.query(query, location='US', job_config=job_config)
    job.result()

注意:当我将来自云调度程序的相同变量作为 http url (https://my-region-test-project.cloudfunctions.net/mycloudfunction?unit=QA&interval=3) 中的参数值传递时,它会起作用

【问题讨论】:

这可能是 ether utf-8 问题,或者您需要解析原始输出,有关提示,请参阅这些其他答案:***.com/questions/53216177/… @Pentium10 提到的链接对我有用,你说得对,问题出在 utf-8 上,现在已经解决了。太感谢了。我在我的代码中进行了以下更改: raw_request_data = request.data string_request_data = raw_request_data.decode("utf-8") request_json: dict = json.loads(string_request_data) 【参考方案1】:

您可以使用带有标志--headers Content-Type=application/jsongcloud 将creating the cron job 覆盖默认的Content-Type

例如:

gcloud scheduler jobs create http my_cron_job \
  --schedule="every 5 hours" \
  --uri="https://$ZONE-$PROJECT_ID.cloudfunctions.net/$FUNCTION_NAME" \
  --http-method=POST \
  --message-body='"foo": "bar"' \
  --headers Content-Type=application/json

这在 GCP Console 级别似乎还没有。 08/2021 更新:现在似乎已经在 UI 中实现了:


或者,如果您使用 Flask,使用 force=True 似乎会有所帮助:

request.get_json(force=True)

这是因为 Cloud Scheduler 似乎将默认的 Content-Type 标头设置为 application/octet-stream。见doc

【讨论】:

【参考方案2】:

最好的提示是 UTF-8 问题。

还请查看其他线程中描述的情况: HTTP Triggering Cloud Function with Cloud Scheduler

【讨论】:

以上是关于无法在云函数中使用 gcp 云调度程序的 json 主体作为参数值?的主要内容,如果未能解决你的问题,请参考以下文章

如何防止云调度器多次触发一个函数?

GCP容器推送不起作用 - “拒绝:请在云控制台中启用Google容器注册表API ...”

在 GCP 中调度多个依赖 ETL

气流 mysql 到 gcp Dag 错误

GCP 云功能无法连接到 GCP SQL 实例

我如何确认客户端(安卓应用程序)数据已由 GCP 云功能完成处理?