Apache 中的 Pygal 导入失败

Pygal import failure in apache

我正在尝试 运行 一个显示 pygal 图的简单 Flask 网络应用程序。当我 运行 它与 python 开发服务器一起使用时,应用程序 运行 没问题。但是,当我尝试在 apache2 中 运行 它时,出现以下错误:

[Thu Dec 10 19:55:22.745469 2020] [wsgi:error] [pid 17741] [client ::1:34366] mod_wsgi (pid=17741): Failed to exec Python script file '/var/www/FlaskApp/FlaskApp.wsgi'.
[Thu Dec 10 19:55:22.745521 2020] [wsgi:error] [pid 17741] [client ::1:34366] mod_wsgi (pid=17741): Exception occurred processing WSGI script '/var/www/FlaskApp/FlaskApp.wsgi'.
[Thu Dec 10 19:55:22.745553 2020] [wsgi:error] [pid 17741] [client ::1:34366] Traceback (most recent call last):
[Thu Dec 10 19:55:22.745586 2020] [wsgi:error] [pid 17741] [client ::1:34366]   File "/var/www/FlaskApp/FlaskApp.wsgi", line 8, in <module>
[Thu Dec 10 19:55:22.745650 2020] [wsgi:error] [pid 17741] [client ::1:34366]     from FlaskApp import app as application
[Thu Dec 10 19:55:22.745665 2020] [wsgi:error] [pid 17741] [client ::1:34366]   File "/var/www/FlaskApp/FlaskApp/__init__.py", line 2, in <module>
[Thu Dec 10 19:55:22.745707 2020] [wsgi:error] [pid 17741] [client ::1:34366]     import pygal
[Thu Dec 10 19:55:22.745723 2020] [wsgi:error] [pid 17741] [client ::1:34366]   File "/var/www/FlaskApp/FlaskApp/venv/lib/python3.8/site-packages/pygal/__init__.py", line 28, in <module>
[Thu Dec 10 19:55:22.745786 2020] [wsgi:error] [pid 17741] [client ::1:34366]     import pkg_resources
[Thu Dec 10 19:55:22.745838 2020] [wsgi:error] [pid 17741] [client ::1:34366]   File "/var/www/FlaskApp/FlaskApp/venv/lib/python3.8/site-packages/pkg_resources/__init__.py", line 1365
[Thu Dec 10 19:55:22.745850 2020] [wsgi:error] [pid 17741] [client ::1:34366]     raise SyntaxError(e) from e
[Thu Dec 10 19:55:22.745857 2020] [wsgi:error] [pid 17741] [client ::1:34366]                             ^
[Thu Dec 10 19:55:22.745864 2020] [wsgi:error] [pid 17741] [client ::1:34366] SyntaxError: invalid syntax

这是我运行宁

的代码
# -*- coding: utf-8 -*-
import pygal
from flask import Flask, Response


app = Flask(__name__)


@app.route('/')
def index():
    """ render svg on html """
    return """
<html>
    <body>
        <h1>hello pygal</h1>
        <figure>
        <embed type="image/svg+xml" src="/graph/" />
        </figure>
    </body>
</html>'
"""


@app.route('/graph/')
def graph():
    """ render svg graph """
    bar_chart = pygal.Bar()
    bar_chart.add('Fibonacci', [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55])
    return Response(response=bar_chart.render(), content_type='image/svg+xml')


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

(请注意,此代码只是从 github 复制的示例)

这是我的 apache 站点配置:

<VirtualHost *:443>
    ServerName flaskapp.localhost
    ServerAdmin me@email.com
    WSGIScriptAlias / /var/www/FlaskApp/FlaskApp.wsgi
    
    <Directory /var/www/FlaskApp/FlaskApp/>
        Order allow,deny
        Allow from all
    </Directory>
    Alias /static /var/www/FlaskApp/FlaskApp/static
    <Directory /var/www/FlaskApp/FlaskApp/static/>
        Order allow,deny
        Allow from all
    </Directory>

    DocumentRoot /var/www/FlaskApp

    SSLEngine on
    SSLCertificateFile /etc/ssl/certs/apache-selfsigned.crt
    SSLCertificateKeyFile /etc/ssl/private/apache-selfsigned.key

    ErrorLog ${APACHE_LOG_DIR}/FlaskApp-error.log
    LogLevel warn
    CustomLog ${APACHE_LOG_DIR}/FlaskApp-access.log combined

    AddDefaultCharset utf-8

</VirtualHost>

这是我的 wsgi 文件:

python_home = '/var/www/FlaskApp/FlaskApp/venv'

activate_this = python_home + '/bin/activate_this.py'
execfile(activate_this, dict(__file__=activate_this))

import sys
import logging
logging.basicConfig(stream=sys.stderr)
sys.path.insert(0,"/var/www/FlaskApp/")
sys.path.insert(0,"/var/www/FlaskApp/FlaskApp/venv/lib/python3.8/site-packages/")

from FlaskApp import app as application
application.secret_key = 'secret key stuff'

以下是有关我的环境的一些详细信息:
Ubuntu 20.04.1 LTS
Apache/2.4.41 (Ubuntu)
Python3.8.5(安装在虚拟环境中)

如有任何想法,我们将不胜感激!

似乎 python 解释器被编译到 mod_wsgi.so 文件中。 Apache 指向一个旧版本,其中包括 python2。为了修复它,我做了以下操作:

  1. 通过执行 sudo apt-get remove libapache2-mod-wsgi
  2. 删除了旧版本的 mod_wsgi
  3. 修改 /etc/apache2/mods-available/mod_wsgi.load 以指向我的虚拟环境中的库 (.so) 文件。 mod_wsgi 的内容如下所示:
LoadModule wsgi_module /var/www/FlaskApp/FlaskApp/venv/lib/python3.8/site-packages/mod_wsgi/server/mod_wsgi-py38.cpython-38-x86_64-linux-gnu.so

我怀疑在这里修改它会将所有 Apache 虚拟主机指向这个 python 虚拟环境,这并不是很理想。如果每个 Apache 虚拟主机都指向自己的 python 环境就更好了。

  1. 修改了我的 wsgi 文件以使用新版本的 python。内容如下:
import sys
import logging
logging.basicConfig(stream=sys.stderr)
sys.path.insert(0,"/var/www/FlaskApp/")
sys.path.insert(0,"/var/www/FlaskApp/FlaskApp/venv/lib/python3.8/site-packages/")

from FlaskApp import app as application
application.secret_key = 'secret key stuff'
  1. 将我的 __init__.py 文件中的本地导入更改为前面有一个点 (.)

经过这些更改后,网站现在可以按预期运行。