【问题标题】:Google Cloud Functions Python3: Wrapping HTTP trigger functions with endpointsGoogle Cloud Functions Python3:使用端点包装 HTTP 触发器函数
【发布时间】:2020-04-05 12:53:51
【问题描述】:

我正在探索 Python 中的 Google Cloud Functions 以编写 HTTP 触发函数。我有一个main.py,我的所有触发函数的结构都类似于post,但希望能够包含在一些端点中。在 nodejs 上,可以像在这个 post 中那样使用 Express,在 Python 上,非常类似地使用 Flask

我曾尝试使用 Flask 包装我的 Cloud Functions,但 Google 会将我带到 Google 的身份验证页面。我的代码如下:

from flask import Flask, jsonify, request

# Initialize Flask application
application = Flask(__name__)

@application.route('/some/endpoint/path', methods=['GET'])
def predict():
    inputs = request.args.get('inputs')

    //Some logic...
    response_object = {}
    response_object['statusCode'] = 200
    response_object['results'] = results

    return jsonify(response_object)

有没有办法以这样的方式包装 python 云函数来实现这样的目标?

https://us-central1-my-project.cloudfunctions.net/some
https://us-central1-my-project.cloudfunctions.net/some/endpoint
https://us-central1-my-project.cloudfunctions.net/some/endpoint/path

【问题讨论】:

标签: python-3.x google-cloud-platform google-cloud-functions


【解决方案1】:

我相信您正在获得身份验证 Google 屏幕,因为您正在尝试访问项目中 Cloud Functions 的基本 URL。

对于 HTTP 云函数,触发 url 通常是 https://[REGION]-[PROJECT_ID].cloudfunctions.net/[FUNCTION_NAME],因此任何路由都需要在函数名称后跟另一个斜杠。

话虽如此,我发现这个post 提供的解决方案设法在同一个 main.py 文件中设置路由以从单个 Cloud Function 访问端点。我不得不调整一些东西,但最终它对我有用。

以下是我最后测试的源代码:

import flask
import werkzeug.datastructures

app = flask.Flask(__name__)


@app.route('/')
def root():
    return 'Hello World!'


@app.route('/hi')
def hi():
    return 'Hi there'


@app.route('/hi/<username>')
def hi_user(username):
    return 'Hi there, {}'.format(username)


@app.route('/hi/<username>/congrats', methods=['POST'])
def hi_user_congrat(username):
    achievement = flask.request.form['achievement']
    return 'Hi there {}, congrats on {}!'.format(username, achievement)


def main(request):
    with app.app_context():
        headers = werkzeug.datastructures.Headers()
        for key, value in request.headers.items():
            headers.add(key, value)
        with app.test_request_context(method=request.method, base_url=request.base_url, path=request.path, query_string=request.query_string, headers=headers, data=request.form):
            try:
                rv = app.preprocess_request()
                if rv is None:
                    rv = app.dispatch_request()
            except Exception as e:
                rv = app.handle_user_exception(e)
            response = app.make_response(rv)
            return app.process_response(response)

这在单个 Cloud Function 中定义了以下路由:

https://[REGION]-[PROJECT_ID].cloudfunctions.net/[FUNCTION_NAME]
https://[REGION]-[PROJECT_ID].cloudfunctions.net/[FUNCTION_NAME]/hi
https://[REGION]-[PROJECT_ID].cloudfunctions.net/[FUNCTION_NAME]/hi/<username>
https://[REGION]-[PROJECT_ID].cloudfunctions.net/[FUNCTION_NAME]/hi/<username>/congrats

以下是用于部署此功能的命令:

gcloud functions deploy flask_function --entry-point main --runtime python37 --trigger-http --allow-unauthenticated

【讨论】:

    【解决方案2】:

    Cloud Functions 旨在用作单个端点。您可以考虑改用 Cloud Run,因为它更适合具有多个路由的应用程序,并且具有许多与 Cloud Functions 相同的优点。

    如果您一心想使用 Cloud Functions,类似Injecting a Flask Request into another Flask App 的答案应该可以,但并不理想。

    【讨论】:

      猜你喜欢
      • 2019-04-12
      • 2020-08-15
      • 2017-11-26
      • 1970-01-01
      • 2021-07-15
      • 2023-03-08
      • 2021-02-04
      • 2021-09-24
      • 2018-11-18
      相关资源
      最近更新 更多