Azure use python flask framework for function app Azure use python flask framework for function app flask flask

Azure use python flask framework for function app


I tried different ways to integrate Azure Functions for Python with Flask framework. Finally, I did it success in my HttpTrigger function named TryFlask via app.test_client().

Here is my sample code, as below.

import loggingimport azure.functions as funcfrom flask import Flask, requestapp = 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')

For testing on local and Azure, to access the urls /, '/hi' and /hello via the url http(s)://<localhost:7071 or azurefunchost>/api/TryFlask with query string ?uri=/, ?uri=/hi and ?uri=/hello/peter-pan in browser, and to do the POST method for the same url above with query string ?uri=/hello/peter-pan, these are all work. Please see the results as the figures locally below, the same on cloud.

enter image description here

enter image description here

enter image description here

enter image description here

enter image description here

Note: In my solution, the url must have to be 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>.


Flask app is just an WSGI application. WSGI is a rather simple interface (see http://ivory.idyll.org/articles/wsgi-intro/what-is-wsgi.html. So instead of using test_client() as middleware to connect to the Azure function environment, a proper wsgi wrapper implementation should be used, which calls the app=Flask() object.

There is a nice Azure Python wsgi wrapper implementation "azf-wsgi" available in https://github.com/vtbassmatt/azf-wsgi.

In order to use the azf-wsgi wrapper with Flask, I found it useful to use a middleware to rewrite the URL:s from /api/app to / so when developing, I don't need to know where my Flask app gets mounted. Additional benefit is that my main.py is just a normal Flask application, which I can run locally without using Azure functions environment (way faster).

My HttpTriggerApp/__init__.py of Azure function is attached. The myFlaskApp-folder is located under the HttpTriggerApp. Remember to use rlative import in the http-trigger as well as main.py (from . import myHelperFooBar).

For host.json and function.json, follow the azf-wsgi instructions.

import loggingimport 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 DispatcherMiddlewareapp.config["APPLICATION_ROOT"] = "/api/app"     # Flask app configuration so it knows correct endpoint urlsapplication = DispatcherMiddleware(None, {    '/api/app': app,})# Wrap the Flask app as WSGI applicationdef main(req: func.HttpRequest, context: func.Context) -> func.HttpResponse:    return AzureFunctionsWsgi(application).main(req, context)