【问题标题】:Why does `flask_bootstrap` fail to import?为什么`flask_bootstrap`导入失败?
【发布时间】:2018-10-14 02:34:02
【问题描述】:

运行烧瓶应用时,Apache2 的error.log 显示找不到flask_bootstrap 模块:

[wsgi:warn] mod_wsgi: Compiled for Python/2.7.11.
[wsgi:warn] mod_wsgi: Runtime using Python/2.7.12.
[mpm_event:notice] AH00489: Apache/2.4.18 (Ubuntu) mod_wsgi/4.3.0 Python/2.7.12 configured -- resuming normal operations
[core:notice] AH00094: Command line: '/usr/sbin/apache2'
[wsgi:error] mod_wsgi (pid=18587): Target WSGI script '/var/www/myapp/myapp.wsgi' cannot be loaded as Python module.
[wsgi:error] mod_wsgi (pid=18587): Exception occurred processing WSGI script '/var/www/myapp/myapp.wsgi'.
[wsgi:error] Traceback (most recent call last):
[wsgi:error]   File "/var/www/myapp/myapp.wsgi", line 7, in <module>
[wsgi:error]     from myapp import app as application 
[wsgi:error]   File "/var/www/myapp/myapp/__init__.py", line 2, in <module>
[wsgi:error]     from flask_bootstrap import Bootstrap
[wsgi:error] ImportError: No module named flask_bootstrap

我已经按照myapp.conf配置了venv

<VirtualHost *:80>
ServerName yourdomain.com
ServerAdmin youemail@email.com

WSGIProcessGroup myapp
WSGIApplicationGroup %{GLOBAL}

WSGIScriptAlias / /var/www/myapp/myapp.wsgi
WSGIDaemonProcess myapp python-home=/var/www/myapp/myapp/venv

<Directory /var/www/myapp/myapp/>
    Order allow,deny
    Allow from all
</Directory>

ErrorLog ${APACHE_LOG_DIR}/error.log
LogLevel warn
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>

该模块在系统范围和 venv 中都可用:

root@host:/var/www/myapp# python
Python 2.7.12 (default, Dec  4 2017, 14:50:18) 
[GCC 5.4.0 20160609] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from flask_bootstrap import Bootstrap
>>> Bootstrap
<class 'flask_bootstrap.Bootstrap'>

还有……

root@host:/var/www/myapp# source myapp/venv/bin/activate
(venv) root@host:/var/www/myapp# python
Python 2.7.12 (default, Dec  4 2017, 14:50:18) 
[GCC 5.4.0 20160609] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from flask_bootstrap import Bootstrap
>>> Bootstrap
<class 'flask_bootstrap.Bootstrap'>

我注意到有一个关于 2.7.11 与 2.7.12 不匹配的警告,但次要版本真的是问题吗?

编辑 1

根据the docs,将以下内容添加到myapp.wsgi

activate_this = '/var/www/myapp/myapp/venv/bin/activate_this.py'
execfile(activate_this, dict(__file__=activate_this))

没有任何区别。

【问题讨论】:

  • 补丁级别版本差异无关紧要。 modwsgi.readthedocs.io/en/develop/user-guides/…
  • 由于您正在以root 测试导入,我会担心安装的包是否具有正确的权限,并且可以被运行 Apache 的用户找到。另外,你从 Python 解释器中得到什么 sys.prefix 来激活虚拟环境?这应该与您提供给 python-home 选项的内容相匹配。
  • 是的,sys.prefix 确实与 python-home 匹配:/
  • 不推荐使用activate_this。如何在 mod_wsgi 中使用虚拟环境在modwsgi.readthedocs.io/en/develop/user-guides/… 中有描述
  • 我还建议将 LogLevel 设置为 info 以便 mod_wsgi 记录更多关于它正在做什么的信息。它在第一次加载 WSGI 脚本时输出的日志消息可能有助于验证实际是否以守护模式正确加载。

标签: python python-2.7 apache virtualenv mod-wsgi


【解决方案1】:

因此,在格雷厄姆说服我我的“修复”(将两行移到 &lt;Directory&gt; 指令中)并不是真正的修复并且可能是其他问题的迹象之后,我决定深入挖掘。

按照文档,特别是 confirming the location of the virtual environment,我惊讶地发现在我的本地机器上激活虚拟环境时(不是通过 wsgi 应用程序):

sys.prefix = '/usr'

当我期望它是:

sys.prefix = '/var/www/myapp/myapp/venv'

我不知道这是怎么发生的。可能是作为root 完成所有初始工作的结果。

不过,很高兴的说,删除并重新制作虚拟环境,这次作为普通用户,一切似乎都很好。

【讨论】:

    【解决方案2】:

    原来问题出在这两行:

    WSGIProcessGroup myapp
    WSGIApplicationGroup %{GLOBAL}
    

    应该在&lt;Directory&gt;里面!

    所以,myapp.conf 现在看起来像这样:

    <VirtualHost *:80>
            ServerName yourdomain.com
    
            WSGIDaemonProcess myapp python-home=/var/www/myapp/myapp/venv
            WSGIScriptAlias / /var/www/myapp/myapp.wsgi
    
            <Directory /var/www/myapp/myapp>
                    WSGIProcessGroup myapp
                    WSGIApplicationGroup %{GLOBAL}
                    Order deny,allow
                    Allow from all
            </Directory>
    
            ErrorLog ${APACHE_LOG_DIR}/error.log
            LogLevel warn
            CustomLog ${APACHE_LOG_DIR}/access.log combined
    </VirtualHost>
    

    公平地说,这与the docs 中的示例相同。

    非常感谢所有评论的人:)

    【讨论】:

    • 这不可能是原因,他们会在原来的地方工作。通过将它们移动到内部,它们现在实际上被忽略了,因为您将错误的目录路径作为 Directory 的参数。使用modwsgi.readthedocs.io/en/develop/user-guides/… 中的检查,您现在可能会发现您的 WSGI 应用程序实际上不再以守护程序模式运行。
    • 嘿格雷厄姆,你为什么认为目录路径是错误的?该应用程序的 Python 脚本确实位于 /var/www/myapp/myapp - 是的,2 x myapp。谢谢!
    • WSGIScriptAlias中WSGI脚本的路径是/var/www/myapp/myapp.wsgi。这意味着目录是/var/www/myappmyapp.wsgi 是文件名组件。您似乎将它指向的文件与 Django wsgi.py 文件不同,该文件位于 /var/www/myapp/myapp 中。 IOW,重要的是WSGIScriptAlias 中的路径,而不是Django wsgi.py 文件所在的位置。
    • 嘿 Graham,这不是 Django - 这是一个完全定制的 Flask 应用程序。 myapp.wsgi 知道从 myapp 子目录导入。查看文档,我没有看到任何说 &lt;Directory&gt; 指令必须指向包含 .wsgi 文件的同一目录。谢谢!
    • 请参阅modwsgi.readthedocs.io/en/develop/user-guides/… 忽略有关 Django 的 cmets,同样的问题仍然适用。使用Directory 的作用域也适用于WSGIProcessGroup 之类的指令。这是 Apache 工作方式的基本部分。 httpd.apache.org/docs/2.4/mod/core.html#directory
    猜你喜欢
    • 2018-12-25
    • 2021-07-25
    • 1970-01-01
    • 1970-01-01
    • 2015-03-21
    • 2021-09-14
    • 1970-01-01
    • 2019-12-21
    • 2017-09-18
    相关资源
    最近更新 更多