【Azure 應(yīng)用服務(wù)】Python flask 應(yīng)用部署在Aure App Service中作為一個(gè)子項(xiàng)目時(shí)粥帚,解決遇見的404 Not Found問題

問題描述

在成功的部署Python flask應(yīng)用到App Service (Windows)后漆撞,如果需要把當(dāng)前項(xiàng)目(如:hiflask)作為一個(gè)子項(xiàng)目(子站點(diǎn)),把web.config文件從wwwroot中移動(dòng)到項(xiàng)目文件夾中挚歧。訪問時(shí)扛稽,確遇見了404 Not Found的錯(cuò)誤。


No alt text provided for this image

查看flask項(xiàng)目的啟動(dòng)日志滑负,可以看見項(xiàng)目啟動(dòng)已經(jīng)成功庇绽。但是為什么請(qǐng)求一直都是404的問題呢?

2021-09-10 05:29:58.224796: wfastcgi.py will restart when files in D:\home\site\wwwroot\hiflask\ are changed: .*((\.py)|(\.config))$
2021-09-10 05:29:58.240445: wfastcgi.py 3.0.0 initialized

問題解決

在搜索 flask return 404問題后橙困,發(fā)現(xiàn)是因?yàn)?URL前綴(prefixed )的問題。因?yàn)楫?dāng)前的flask應(yīng)用訪問路徑不再是根目錄(/)耕餐,而是(/hiflask)凡傅。 所以需要 flask項(xiàng)目中使用 中間件 來(lái)處理 url前綴的問題。


原文內(nèi)容為:https://stackoverflow.com/questions/18967441/add-a-prefix-to-all-flask-routes/36033627#36033627

You have to do is to write a middleware to make the following changes:

  1. modify PATH_INFO to handle the prefixed url.
  2. modify SCRIPT_NAME to generate the prefixed url.

Like this:

class PrefixMiddleware(object):

    def __init__(self, app, prefix=''):
        self.app = app
        self.prefix = prefix

    def __call__(self, environ, start_response):

        if environ['PATH_INFO'].startswith(self.prefix):
            environ['PATH_INFO'] = environ['PATH_INFO'][len(self.prefix):]
            environ['SCRIPT_NAME'] = self.prefix
            return self.app(environ, start_response)
        else:
            start_response('404', [('Content-Type', 'text/plain')])
            return ["This url does not belong to the app.".encode()]

Wrap your app with the middleware, like this:

from flask import Flask, url_for

app = Flask(__name__)
app.debug = True
app.wsgi_app = PrefixMiddleware(app.wsgi_app, prefix='/foo')

@app.route('/bar')
def bar():
    return "The URL for this page is {}".format(url_for('bar'))

if __name__ == '__main__':
    app.run('0.0.0.0', 9010)

Visit http://localhost:9010/foo/bar,

You will get the right result: The URL for this page is /foo/bar


而在App Service中的解決方式就是添加了 PrefixMiddleware肠缔,并指定prefix為 /hiflask 夏跷。 附上完成的hiflask/app.py 代碼和web.config內(nèi)容。

hiflask/app.py

from flask import Flask
from datetime import datetime
from flask import render_template

import re

class PrefixMiddleware(object):
    def __init__(self, app, prefix=''):
        self.app = app
        self.prefix = prefix

    def __call__(self, environ, start_response):
        if environ['PATH_INFO'].startswith(self.prefix):
            environ['PATH_INFO'] = environ['PATH_INFO'][len(self.prefix):]
            environ['SCRIPT_NAME'] = self.prefix
            return self.app(environ, start_response)
        else:
            start_response('404', [('Content-Type', 'text/plain')])
            return ["This url does not belong to the app.".encode()]

#if __name__ =="__name__"
app = Flask(__name__)
app.debug = True
app.wsgi_app = PrefixMiddleware(app.wsgi_app, prefix='/hiflask')
# @app.route("/")
# def home():
#     return "Hello, Flask!"

print("flask applicaiton started and running..." +datetime.now().strftime("%m/%d/%Y, %H:%M:%S"))

# 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")

if __name__ == '__main__':
    app.run(debug=True)

hiflask/web.config

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <appSettings>
    <add key="WSGI_HANDLER" value="app.app"/>
    <add key="PYTHONPATH" value="D:\home\site\wwwroot\hiflask"/>
    <add key="WSGI_LOG" value="D:\home\site\wwwroot\hiflask\hiflasklogs.log"/>
  </appSettings>
  <system.webServer>
    <handlers>
    <add name="PythonHandler" path="*" verb="*" modules="FastCgiModule" scriptProcessor="D:\home\python364x64\python.exe|D:\home\python364x64\wfastcgi.py" resourceType="Unspecified" requireAccess="Script"/>
    </handlers>
  </system.webServer>
</configuration>

最終效果(作為子項(xiàng)目部署完成成功明未,所以一個(gè)app service就可以部署多個(gè)站點(diǎn))


No alt text provided for this image

提醒一點(diǎn):App Service中如果要部署多站點(diǎn)槽华,需要在Configration 中配置 Virtual Applications。

No alt text provided for this image

參考資料:

https://stackoverflow.com/questions/18967441/add-a-prefix-to-all-flask-routes/36033627#36033627

https://www.cnblogs.com/lulight/p/15220297.html

https://www.cnblogs.com/lulight/p/15227028.html

當(dāng)在復(fù)雜的環(huán)境中面臨問題趟妥,格物之道需:濁而靜之徐清猫态,安以動(dòng)之徐生。 云中披摄,恰是如此!

分類: 【Azure 應(yīng)用服務(wù)】

標(biāo)簽: flask項(xiàng)目作為子應(yīng)用的404問題, 使用Flask框架部署Python應(yīng)用, Python web.config, App Service, Python Flask 404 Not Found

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末亲雪,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子疚膊,更是在濱河造成了極大的恐慌义辕,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,607評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件寓盗,死亡現(xiàn)場(chǎng)離奇詭異灌砖,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)傀蚌,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,239評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門基显,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人喳张,你說我怎么就攤上這事续镇。” “怎么了销部?”我有些...
    開封第一講書人閱讀 164,960評(píng)論 0 355
  • 文/不壞的土叔 我叫張陵摸航,是天一觀的道長(zhǎng)制跟。 經(jīng)常有香客問我,道長(zhǎng)酱虎,這世上最難降的妖魔是什么空郊? 我笑而不...
    開封第一講書人閱讀 58,750評(píng)論 1 294
  • 正文 為了忘掉前任,我火速辦了婚禮奕翔,結(jié)果婚禮上秸苗,老公的妹妹穿的比我還像新娘。我一直安慰自己恢暖,他們只是感情好排监,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,764評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著杰捂,像睡著了一般舆床。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上嫁佳,一...
    開封第一講書人閱讀 51,604評(píng)論 1 305
  • 那天挨队,我揣著相機(jī)與錄音,去河邊找鬼蒿往。 笑死盛垦,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的瓤漏。 我是一名探鬼主播腾夯,決...
    沈念sama閱讀 40,347評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼赌蔑!你這毒婦竟也來(lái)了俯在?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,253評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤娃惯,失蹤者是張志新(化名)和其女友劉穎跷乐,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體趾浅,經(jīng)...
    沈念sama閱讀 45,702評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡愕提,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,893評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了皿哨。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片浅侨。...
    茶點(diǎn)故事閱讀 40,015評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖证膨,靈堂內(nèi)的尸體忽然破棺而出如输,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 35,734評(píng)論 5 346
  • 正文 年R本政府宣布不见,位于F島的核電站澳化,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏稳吮。R本人自食惡果不足惜缎谷,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,352評(píng)論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望灶似。 院中可真熱鬧列林,春花似錦、人聲如沸酪惭。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,934評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)春感。三九已至润梯,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間甥厦,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,052評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工寇钉, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留刀疙,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,216評(píng)論 3 371
  • 正文 我出身青樓扫倡,卻偏偏與公主長(zhǎng)得像谦秧,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子撵溃,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,969評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容