zoukankan      html  css  js  c++  java
  • 【Azure 应用服务】Python flask 应用部署在Aure App Service 遇见的 3 个问题

    在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-32python.exe|c:python36-32wfastcgi.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文件。否则,在LogFileswfastcgi.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:Python34Scriptswfastcgi.py", line 711, in main
        env, handler = read_wsgi_handler(response.physical_path)
      File "D:Python34Scriptswfastcgi.py", line 568, in read_wsgi_handler
        return env, get_wsgi_handler(handler_name)
      File "D:Python34Scriptswfastcgi.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:Python34Scriptswfastcgi.py", line 711, in main
        env, handler = read_wsgi_handler(response.physical_path)
      File "D:Python34Scriptswfastcgi.py", line 568, in read_wsgi_handler
        return env, get_wsgi_handler(handler_name)
      File "D:Python34Scriptswfastcgi.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:homepython364x64wfastcgi.py", line 791, in main
        env, handler = read_wsgi_handler(response.physical_path)
      File "D:homepython364x64wfastcgi.py", line 633, in read_wsgi_handler
        handler = get_wsgi_handler(os.getenv("WSGI_HANDLER"))
      File "D:homepython364x64wfastcgi.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:homepython364x64wfastcgi.py", line 600, in get_wsgi_handler
        handler = __import__(module_name, fromlist=[name_list[0][0]])
      File ".himyappapp.py", line 1, in <module>
        from flask import Flask
    ModuleNotFoundError: No module named 'flask'

    在Web.config文件中,配置的python路径为D:homepython364x64python.exe,所以也需要把flask模块安装在此版本python中的lib/site-package中。 requirements.txt文件中的其他模块也是同样的道理

    安装步骤:

    1) 通过Kudu Console页面,进入 D:homepython364x64  目录

    2) 执行升级 flask模块指令  

    C:homepython364x64>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:homepython364x64wfastcgi.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

    当在复杂的环境中面临问题,格物之道需:浊而静之徐清,安以动之徐生。 云中,恰是如此!

  • 相关阅读:
    45
    布里斯班初体验
    走出你的舒适区
    Homebrew- MAC上的包管理利器
    Java经典类库-Guava中的函数式编程讲解
    使用WebDriver遇到的那些坑
    CheckStyle, 强制你遵循编码规范
    利用php的register_shutdown_function来记录php的输出日志
    PHP-redis中文文档
    php中set_time_limit()函数运用
  • 原文地址:https://www.cnblogs.com/lulight/p/15227028.html
Copyright © 2011-2022 走看看