본문 바로가기

일::개발

Python으로 Azure에 Serverless 웹 구축하기 - 3. Flask

앞에서 Visual Studio Code 가 만들어주는 샘플 코드를 Azure에 올려서 Functions App 을 만드는 것까지는 해봤으니 이제 Flask 어플리케이션을 올려보도록 하자!

 

Request URL : host.json 과 function.json

그 전에 몇 가지 설정파일에 대해 좀 더 알아볼 필요가 있다.

 

앞에서 VSC가 만들어준 function 샘플의 URL은 http://localhost:7071/api/flask-sample 이었다.

어떻게 이 URL이 만들어졌는지 좀 살펴보자면, 일단 host.json 파일을 봐야 한다.

host.json 파일에 대한 자세한 설명은 https://docs.microsoft.com/en-us/azure/azure-functions/functions-host-json 를 참조하면 되는데, 여기서 URL 과 관련된 부분만 보자면

{
    "http": {
        "routePrefix": "api",
        "maxOutstandingRequests": 200,
        "maxConcurrentRequests": 100,
        "dynamicThrottlesEnabled": true
    }
}

routePrefix 항목의 default 값은 "api" 다. 즉, 모든 HTTP를 통한 요청 "api" 라는 prefix 를 붙여서 들어와야 한다는 의미가 된다.

 

다음으로 flask-sample function의 function.json 파일을 보면

{
    "scriptFile": "__init__.py",
    "disabled": false,    
    "bindings": [
        {
            "authLevel": "function",
            "type": "httpTrigger",
            "direction": "in",
            "name": "req"
        },
        {
            "type": "http",
            "direction": "out",
            "name": "res"
        }
    ]
}

이렇게 되어 있고, https://docs.microsoft.com/en-us/azure/azure-functions/functions-bindings-http-webhook#trigger---configuration 문서에 따르면 여기에 빠져 있는 "route" property 로 function이 응답할 URL 라우팅을 정의하며, 기본 값은 <functionname> 이 된다.

결국 host.json 에 routePrefix 를 정의하지 않고, function.json에 route 값을 정의하지 않았기 때문에 각각의 기본 값인 api, flask-sample(function 이름) 이 들어와야 flask-sample/__init__.py 로 연결되는 것이다.

 

"routePrefix": "", "route": "{*:alpha}" 로 설정하면 request URL 은 http://localhost:7071 이 된다.

{*:alpha} 부분에 대해서는 https://docs.microsoft.com/en-us/aspnet/web-api/overview/web-api-routing-and-actions/attribute-routing-in-web-api-2#route-constraints 문서 참조.

 

WSGI 연동

Django나 Flask와 같은 WSGI 앱을 Azure Functions App 으로 만들기 위해서는 데이터 바인딩을 WSGI와 연동해줘야 한다.

 

다행히 훌륭하신 분들이 우리가 필요한 것을 다 만들어놓으셔서 우리는 설치만 하면 Azure Functions의 API와 WSGI 프로토콜이 휙 하고 연결되어버린다. azf-wsgi(https://github.com/vtbassmatt/azf-wsgi) 를 이용해서 해보자.

 

일단 설치 설치.

(functions-flask) pfaf-sample uaremine$ pip install flask
...... 잔뜩 설치 ......

(functions-flask) pfaf-sample uaremine$ pip install azf-wsgi
Collecting azf-wsgi
...... 또 설치 ......

(functions-flask) pfaf-sample uaremine$ pip list
Package         Version
--------------- -------
azf-wsgi        0.3.0
azure-functions 1.0.0b5
Click           7.0
Flask           1.0.3
itsdangerous    1.1.0
Jinja2          2.10.1
MarkupSafe      1.1.1
pip             18.1
setuptools      40.6.2
Werkzeug        0.15.4

Flask 와 azf-wsgi 를 설치한 후에 확인해보면 필요한 패키지들이 잘 설치되어 있다. virtualenv 환경에서 설치되었는지 다시 한번 잘 확인하고 다음으로 진행.

 

일단 우리는 되는지 확인부터 할 것이니, 아주아주 간단한 Flask app을 하나 만들어보자. Flask 문서에 있는 첫번째 샘플로.

from flask import Flask
app = Flask(__name__)

@app.route("/")
def hello():
    return "Hello World!"

전에 VSC가 만들어줬던 flask-sample와 같은 depth에 helloWorld 라는 디렉토리를 만들고, hello.py 안에 위의 코드를 넣는다. 디렉토리에 __init__.py 파일 만들어놓는 것도 잊지 말고.

자, Flask app 은 됐으니 이제 azf-wsgi 문서에서 시키는대로 flask-sample/__init__.py를 수정해본다.

문서는 django 기준으로 되어 있어서 flask 기준으로 살짝 고치면

import logging
import azure.functions as func
from azf_wsgi import AzureFunctionsWsgi

from helloWorld.hello import app

def main(req: func.HttpRequest, context: func.Context) -> func.HttpResponse:
    return AzureFunctionsWsgi(app).main(req, context)

위에서 설명한 대로 host.json과 function.json을 수정하고 실행하면

 

짜잔~ 

아. 혹시 afz_wsgi 를 찾을 수 없다고 에러가 나면 

(functions-flask) pfaf-sample uaremine$ pip freeze > requirements.txt

이렇게 해놓고 다시 시도해보기.