Google Cloud Functions Python3:使用端点包装HTTP触发函数

时间:2019-12-12 07:08:24

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

我正在探索使用Python编写Google触发函数的Google Cloud Functions。我有一个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

2 个答案:

答案 0 :(得分:0)

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

使用HTTP Cloud Functions时,触发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

答案 1 :(得分:0)

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

如果您对使用Cloud Functions感到无所适从,Injecting a Flask Request into another Flask App之类的答案应该可以使用,但这并不理想。