Azure使用Python Flask框架作为函数应用程序。

6

我看到Azure现在支持在函数应用中使用Python (preview)。我有一个现有的Flask应用程序,想知道是否可以在不进行重大更改的情况下将其部署为函数应用程序?

我已经阅读了使用Python在函数应用程序中的Azure教程(https://learn.microsoft.com/en-us/azure/azure-functions/functions-reference-python),但没有涉及到Flask框架...

有人有相关的经验吗?

3个回答

13

我尝试了多种方法将Azure Functions for Python与Flask框架集成。最终,我在名为TryFlask的HttpTrigger函数中通过app.test_client()成功实现了它。

以下是我的示例代码。

import logging
import azure.functions as func
from flask import Flask, request

app = Flask(__name__)

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

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

@app.route('/hello')
@app.route('/hello/<name>', methods=['POST', 'GET'])
def hello(name=None):
    return name != None and 'Hello, '+name or 'Hello, '+request.args.get('name')

def main(req: func.HttpRequest) -> func.HttpResponse:
    logging.info('Python HTTP trigger function processed a request.')
    uri=req.params['uri']
    with app.test_client() as c:
        doAction = {
            "GET": c.get(uri).data,
            "POST": c.post(uri).data
        }
        resp = doAction.get(req.method).decode()
        return func.HttpResponse(resp, mimetype='text/html')

为了在本地和Azure上进行测试,可以通过带有查询字符串的URL ?uri=/?uri=/hi?uri=/hello/peter-pan 访问 //hi/hello,并且可以使用相同的URL进行 POST 方法,查询字符串为 ?uri=/hello/peter-pan。请查看下面本地和云端的结果截图。

enter image description here

enter image description here

enter image description here

enter image description here

enter image description here

注意:在我的解决方案中,URL必须为 http(s)://<localhost:7071 or azurefunchost>/<routePrefix defined in host.json, default is api>/<function name>?uri=<uri defined in app.route, like / or /hi or /hello, even /hello/peter-pan?name=peter>


这个对于简单情况可以工作,但是不能处理POST请求的JSON负载!main()-wrapper不完整。 - Tmu
@Peter Pan,我有一个与这篇文章相关的问题。你有一分钟吗?如果需要,我很乐意发布新的问题。谢谢。 - wwnde
@PeterPan,你能帮我回答以下问题吗?https://stackoverflow.com/questions/68121920/azure-function-apps-integration-of-flask-framework-with-azure-functions - Stark

9

Flask应用只是一个WSGI应用程序。WSGI是一个相当简单的接口(请参见http://ivory.idyll.org/articles/wsgi-intro/what-is-wsgi.html)。因此,不要使用test_client()作为中间件连接到Azure函数环境,应该使用适当的wsgi包装器实现,该包装器调用app=Flask()对象。

有一个很好的Azure Python wsgi包装器实现“azf-wsgi”,可在https://github.com/vtbassmatt/azf-wsgi上获得。

为了与Flask一起使用azf-wsgi包装器,我发现使用中间件将URL从/api/app重写为/非常有用,这样在开发时,我不需要知道我的Flask应用程序挂载在哪里。另一个好处是,我的main.py只是一个普通的Flask应用程序,我可以在本地运行它而不使用Azure函数环境(更快)。

我的Azure函数的HttpTriggerApp/__init__.py已附在下面。myFlaskApp文件夹位于HttpTriggerApp下。请记住在http-trigger以及main.py中使用相对导入(from. import myHelperFooBar)。

对于host.json和function.json,请遵循azf-wsgi的说明。

import logging
import azure.functions as func

# note that the package is "azf-wsgi" but the import is "azf_wsgi"
from azf_wsgi import AzureFunctionsWsgi

# Import the Flask wsgi app (note relative import from the folder under the httpTrigger-folder.
from .myFlaskAppFolder.main import app

# rewrite URL:s to Azure function mount point (you can configure this in host.json and function.json)
from werkzeug.middleware.dispatcher import DispatcherMiddleware
app.config["APPLICATION_ROOT"] = "/api/app"     # Flask app configuration so it knows correct endpoint urls
application = DispatcherMiddleware(None, {
    '/api/app': app,
})

# Wrap the Flask app as WSGI application
def main(req: func.HttpRequest, context: func.Context) -> func.HttpResponse:
    return AzureFunctionsWsgi(application).main(req, context)

8

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接