首页 > 解决方案 > 使用 IIS FastCGI 在子目录中发布 Flask API

问题描述

我想在 IIS 的子目录中托管我的 Flask API。

MYLAPTOP (IIS Server)
|
|____Sites
     |
     |____Default Web Site (Website)
          |
          |____service (Virtual Directory)
               |
               |____payrollapi (Application)

payrollapi 的 URL 是http://localhost/service/payrollapi/

我配置了 wfastcgi 和 FastCGI 设置

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <system.webServer>
        <handlers>
            <add name="FlaskHandler" path="*" verb="*" modules="FastCgiModule" scriptProcessor="c:\annaconda\envs\payroll\python.exe|c:\annaconda\envs\payroll\lib\site-packages\wfastcgi.py" resourceType="Unspecified" />
        </handlers>
    </system.webServer>
    <appSettings>
        <add key="WSGI_HANDLER" value="payroll.app" />
        <add key="PYTHONPATH" value="C:\inetpub\wwwroot\service\payrollapi" />
    </appSettings>
</configuration>

烧瓶 API 脚本:

from flask import Flask
app = Flask(__name__)

@app.route("/", methods=['GET', 'POST'])
def notes_list():
    return "Welcome to Payroll !"


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

HTTP Error 403.18 - Forbidden它在尝试访问 API 方法时返回错误代码“ ”。

我也尝试过 URL Rewrite 但没有用

<system.webServer>
  <directoryBrowse enabled="true" />
  <rewrite>
     <rules>
        <rule name="Reverse Proxy to payroll" stopProcessing="true">
            <match url="^service/payrollapi/(.*)" />
            <action type="Rewrite" url="http://localhost:5500/service/payrollapi/{R:1}" />
        </rule>
     </rules>
  </rewrite>

请帮助我如何在网站的子目录/子应用程序中部署 Flask 应用程序。

标签: pythonpython-3.xiisflaskfastcgi

解决方案


使用下面的代码,应用程序响应:http: //127.0.0.1 :5000/service/payrollapi/

此答案的代码(稍作修改):https ://stackoverflow.com/a/36033627/3845545

from flask import Flask

class PrefixMiddleware(object):

    def __init__(self, app, *prefix):
        self.app = app
        self.prefixes = []

        for i in prefix:
            self.prefixes.append(i)


    def __call__(self, environ, start_response):

        for i in self.prefixes:
            if environ['PATH_INFO'].startswith(i):
                environ['PATH_INFO'] = environ['PATH_INFO'][len(i):]
                environ['SCRIPT_NAME'] = i
                return self.app(environ, start_response)

        start_response('404', [('Content-Type', 'text/plain')])
        return ["This url does not belong to the app.".encode()]

app = Flask(__name__)
app.wsgi_app = PrefixMiddleware(app.wsgi_app, '/service/payrollapi')

@app.route("/", methods=['GET', 'POST'])
def notes_list():
    return "Welcome to Payroll !"

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

推荐阅读