在App Service(Windows)中部署Flask應用時的注意事項:
● 新增Python擴充套件外掛,Python 3.6.4 x64:
●● 配置 FastCGI 處理程式,新增Web.config:
FastCGI 是在請求級別工作的介面。 IIS 接收傳入的連線,並將每個請求轉發到在一個或多個持久 Python 程式中執行的 WSGI 應用。將應用的 web.config 檔案修改為,在 PythonHandler
鍵中新增 python.exe 和 wfastcgi.py 的完整路徑。修改 web.config 中的 PythonHandler
條目,讓路徑與 Python 安裝位置一致
<system.webServer> <handlers> <add name="PythonHandler" path="*" verb="*" modules="FastCgiModule" scriptProcessor="c:\python36-32\python.exe|c:\python36-32\wfastcgi.py" resourceType="Unspecified" requireAccess="Script"/> </handlers> </system.webServer>
●●● 配置WSGI_HANDLER 引數:
Flask:將 WSGI_HANDLER
值更改為 <project_name>.app
,其中 <project_name>
與專案名稱匹配。 可通過檢視 runserver.py 中的 from <project_name> import app
語句,找到準確的識別符號。 例如,如果專案命名為“FlaskAzurePublishExample”,則該條目如下所示:
<!-- Flask apps only: change the project name to match your app --> <add key="WSGI_HANDLER" value="flask_iis_example.app"/>
問題描述
問題一:根據參考文件,配置了web.config中的 WSGI_HANDLER 和 PythonHandler 後,但是如何知道正確的專案名呢?因為 WSGI_HANDLER 值需要根據 flask的專案名稱來啟動app.py檔案。否則,在LogFiles\wfastcgi.log檔案中,則一直報:ValueError: "app.app" could not be imported
問題二:啟動應用時,一直出現 ModuleNotFoundError: No module named 'flask' 的問題
問題三:wfastcgi 一直丟擲 TypeError: 'module' object is not callable 的問題
在未能解決以上三個問題時,訪問App Service 一直是 500 錯誤。
問題解決
問題一:如何配置正確的 WSGI_HANDLER 值?
在不知到flask如何配置正確的專案名稱時,如果把所有的py檔案都部署在wwwroot目錄下,使用app.py為啟動檔案,那麼不管設定的值 是 <add key="WSGI_HANDLER" value="youappservicename.app"/> 或者是 <add key="WSGI_HANDLER" value="app.app"/>等,都會出現如下錯誤:
StdErr: 2021-09-03 09:33:26.892105: Unhandled exception in wfastcgi.py: Traceback (most recent call last): File "D:\Python34\Scripts\wfastcgi.py", line 711, in main env, handler = read_wsgi_handler(response.physical_path) File "D:\Python34\Scripts\wfastcgi.py", line 568, in read_wsgi_handler return env, get_wsgi_handler(handler_name) File "D:\Python34\Scripts\wfastcgi.py", line 551, in get_wsgi_handler raise ValueError('"%s" could not be imported' % handler_name) ValueError: "lbpython01.app" could not be imported 2021-09-03 09:33:26.892105: wfastcgi.py 2.1.1 closed StdErr: 2021-09-03 09:38:15.094780: Unhandled exception in wfastcgi.py: Traceback (most recent call last): File "D:\Python34\Scripts\wfastcgi.py", line 711, in main env, handler = read_wsgi_handler(response.physical_path) File "D:\Python34\Scripts\wfastcgi.py", line 568, in read_wsgi_handler return env, get_wsgi_handler(handler_name) File "D:\Python34\Scripts\wfastcgi.py", line 551, in get_wsgi_handler raise ValueError('"%s" could not be imported' % handler_name) ValueError: "app.app" could not be imported
在沒有更好的辦法之前,如下的方式可以暫時解決 flask 專案的名稱問題:
1) 在wwwroot中新建一個folder,取名為 hiflask,作為flask專案的專案名。並把 flask的所有專案檔案轉移到新建的folder中。
2) 在修改WSGI_HANDLER的值,用第#1中的hiflask作為專案名。如:<add key="WSGI_HANDLER" value="hiflask.app"/>
修改完成後,專案檔案結構和web.confi設定如下:
在次啟動後,遇見問題二, flask 模組沒有安裝。
問題二:啟動應用時,一直出現 ModuleNotFoundError: No module named 'flask' 的問題
全部錯誤資訊:
Traceback (most recent call last):
File "D:\home\python364x64\wfastcgi.py", line 791, in main
env, handler = read_wsgi_handler(response.physical_path)
File "D:\home\python364x64\wfastcgi.py", line 633, in read_wsgi_handler
handler = get_wsgi_handler(os.getenv("WSGI_HANDLER"))
File "D:\home\python364x64\wfastcgi.py", line 616, in get_wsgi_handler
raise ValueError('"%s" could not be imported%s' % (handler_name, last_tb))
ValueError: "himyapp.app" could not be imported: Traceback (most recent call last):
File "D:\home\python364x64\wfastcgi.py", line 600, in get_wsgi_handler
handler = __import__(module_name, fromlist=[name_list[0][0]])
File ".\himyapp\app.py", line 1, in <module>
from flask import Flask
ModuleNotFoundError: No module named 'flask'
在Web.config檔案中,配置的python路徑為D:\home\python364x64\python.exe,所以也需要把flask模組安裝在此版本python中的lib/site-package中。 requirements.txt檔案中的其他模組也是同樣的道理
安裝步驟:
1) 通過Kudu Console頁面,進入 D:\home\python364x64\ 目錄
2) 執行升級 flask模組指令
C:\home\python364x64>python.exe -m pip install --upgrade flask
3) 檢視 python364x64 目錄中是否已經包含了 flask 模組
問題三:wfastcgi 一直丟擲 TypeError: 'module' object is not callable 的問題
全部錯誤資訊:
StdOut:
StdErr:
2021-09-03 11:25:21.822491: Error occurred:
Traceback (most recent call last):
File "D:\home\python364x64\wfastcgi.py", line 847, in main
result = handler(record.params, response.start)
TypeError: 'module' object is not callable
這個問題很是困擾,module? 是什麼module呢? 難道是第一步中,把專案放入 hiflask 資料夾後, wfastcgi 在載入專案檔案的時候把它認為是一個模組,而根據Python模組的定義,都需要一個 __init__.py的檔案放在資料夾下用以標識。
所以嘗試修改步驟為:
1)在hiflask中新增__init__.py檔案
2)在檔案中輸入以下內容:定義了一個flask的app
from flask import Flask app = Flask(__name__)
雖然以上兩個步驟能解決 TypeError: 'module' object is not callable 問題,但是在訪問 App Service時,出現的不在是500的錯誤,而是404 Not Found錯誤。
根據__init__.py中的程式碼分析,應該是啟動hiflask模組時定義了app,而app為空,沒有任何輸出和route配置。 而hiflask資料夾中的 app.py 中的內容,不知何原因沒有生效。所以解決辦法就是把 app.py 中的內容複製到__init__.py中。
解決問題後,__init__.py 中的內容為:
from flask import Flask from datetime import datetime from flask import render_template import re app = Flask(__name__) # @app.route("/") # def home(): # return "Hello, Flask!" # Replace the existing home function with the one below @app.route("/") def home(): return render_template("home.html") # New functions @app.route("/about/") def about(): return render_template("about.html") @app.route("/contact/") def contact(): return render_template("contact.html") @app.route("/hello/") @app.route("/hello/<name>") def hello_there(name = None): return render_template( "hello_there.html", name=name, date=datetime.now() ) @app.route("/api/data") def get_data(): return app.send_static_file("data.json")
訪問效果為:
參考資料
為 Python Web 應用配置 IIS:https://docs.microsoft.com/zh-cn/visualstudio/python/configure-web-apps-for-iis-windows?view=vs-2019#configure-the-fastcgi-handler