Flask 应用程序与 WSGI 和 Apache 一起出现错误 500



我只有一个大文件为我的应用程序提供服务 app.py 但现在,我决定分成几个文件来分离代码。在此分离之后,WSGI 不再启动与导入函数相关的错误。

ImportError: cannot import name month_string_to_number

代码现在分为 3 个主要文件:app.py、views.pymodels.py。这里有一些代码,以及Apache和WSGI配置。

app.py

import sqlite3
import json
import os
import csv
import codecs
from flask import Flask, jsonify, g, request, abort, render_template, redirect, url_for, flash
from flask_sqlalchemy import Model, SQLAlchemy
from sqlalchemy import text, and_
from datetime import datetime, timedelta
from werkzeug import secure_filename
from flask_login import LoginManager

app = Flask(__name__)
login = LoginManager(app)
login.login_view = 'login'
app.secret_key = 'certificates-management'
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///certificates.db'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
dir_path = os.path.dirname(os.path.realpath(__file__))
db = SQLAlchemy(app)
from views import *
def month_string_to_number(string):
    m = {
            'jan': '1',
            'feb': '2',
            'mar': '3',
            'apr': '4',
            'may': '5',
            'jun': '6',
            'jul': '7',
            'aug': '8',
            'sep': '9',
            'oct': '10',
            'nov': '11',
            'dec': '12'
        }
    s = string.strip()[:3].lower()
    try:
        out = m[s]
        return out
    except:
        raise ValueError('Not a month')
if __name__ == '__main__':
    app.run(debug=True)

views.py

import sqlite3
import json
import os
import csv
import codecs
from flask import Flask, jsonify, g, request, abort, render_template, redirect, url_for, flash
from flask_sqlalchemy import Model, SQLAlchemy
from models import Worker, Certificates, Logs, User, return_workers, insert_db, create_log_entry
from sqlalchemy import text, and_
from datetime import datetime, timedelta
from werkzeug import secure_filename
from app import app, db, month_string_to_number
from flask_login import current_user, login_user, logout_user, login_required
from urlparse import urlparse
@app.errorhandler(404)
def not_found(error):
    return render_template('error.html')
@app.route('/login', methods=['GET', 'POST'])
def login():
    if request.method == 'POST':
        if current_user.is_authenticated:
            return redirect(url_for('index'))
        user_name = request.form['username']
        user_password = request.form['password']
        remember_me = request.form.get('remember_me', False)
        user = User.query.filter_by(username=user_name).first()
        dir(user)
        if user is None or not user.check_password(user_password):
            flash('Invalid username or password')
            return redirect(url_for('login'))
        login_user(user, remember=remember_me)
        create_log_entry(current_user.name, "Logged in to the system", "Login")
        flash("Login successfull", 'success')
        return redirect(url_for('index'))
    return render_template('login.html')
@app.route('/logout')
def logout():
    create_log_entry(current_user.name, "Logged out from the system", "Logout")
    logout_user()
    flash("Logged out successfully", 'success')
    return redirect(url_for('index'))

models.py

from app import app, db, login
import datetime
from werkzeug.security import generate_password_hash, check_password_hash
from flask_login import UserMixin
class User(UserMixin, db.Model):
    __tablename__ = 'users'
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(255), nullable=False)
    username = db.Column(db.String(255), nullable=False, unique=True)
    password_hash = db.Column(db.String(255), nullable=False)
    def __init__(self, username, password):
        self.username = username
        self.password_hash = password
    def set_password(self, password):
        self.password_hash = generate_password_hash(password)
    def check_password(self, password):
        return check_password_hash(self.password_hash, password)

WSGI代码是这样的:

import sys
sys.path.append("/var/www/certs-management")
from app import app as application

和 Apache 配置:

<virtualhost *:80>
    ServerName myserver.example
    WSGIDaemonProcess certs-management user=apache group=apache threads=5 home=/var/www/certs-management/
    WSGIScriptAlias / /var/www/certs-management/cert-management.wsgi
    Alias /static /var/www/certs-management/static/
     <Directory "/var/www/certs-management/static/">
      Order allow,deny
      Allow from all
    </Directory>
    Alias /templates /var/www/certs-management/templates/
    <Directory "/var/www/certs-management/templates/">
      Order allow,deny
      Allow from all
    </Directory>
    <directory /var/www/certs-management>
        WSGIProcessGroup certs-management
        WSGIApplicationGroup %{GLOBAL}
        WSGIScriptReloading On
        Order deny,allow
        Allow from all
    </directory>
</virtualhost>

错误消息如下:

[Wed Jan 31 18:59:48.397516 2018] [mpm_prefork:notice] [pid 5634] AH00171: Graceful restart requested, doing restart
[Wed Jan 31 18:59:48.546219 2018] [auth_digest:notice] [pid 5634] AH01757: generating secret for digest authentication ...
[Wed Jan 31 18:59:48.546904 2018] [lbmethod_heartbeat:notice] [pid 5634] AH02282: No slotmem from mod_heartmonitor
[Wed Jan 31 18:59:48.547518 2018] [mpm_prefork:notice] [pid 5634] AH00163: Apache/2.4.6 (Red Hat Enterprise Linux) mod_wsgi/3.4 Python/2.7.5 configured -- resuming normal operations
[Wed Jan 31 18:59:48.547538 2018] [core:notice] [pid 5634] AH00094: Command line: '/usr/sbin/httpd'
[Wed Jan 31 18:59:52.011929 2018] [:error] [pid 3881] [remote :176] mod_wsgi (pid=3881): Target WSGI script '/var/www/certs-management/cert-management.wsgi' cannot be loaded as Python module.
[Wed Jan 31 18:59:52.011985 2018] [:error] [pid 3881] [remote :176] mod_wsgi (pid=3881): Exception occurred processing WSGI script '/var/www/certs-management/cert-management.wsgi'.
[Wed Jan 31 18:59:52.012015 2018] [:error] [pid 3881] [remote :176] Traceback (most recent call last):
[Wed Jan 31 18:59:52.012033 2018] [:error] [pid 3881] [remote :176]   File "/var/www/certs-management/cert-management.wsgi", line 3, in <module>
[Wed Jan 31 18:59:52.012098 2018] [:error] [pid 3881] [remote :176]     from app import app as application
[Wed Jan 31 18:59:52.012111 2018] [:error] [pid 3881] [remote :176]   File "/var/www/certs-management/app.py", line 26, in <module>
[Wed Jan 31 18:59:52.012158 2018] [:error] [pid 3881] [remote :176]     from views import *
[Wed Jan 31 18:59:52.012169 2018] [:error] [pid 3881] [remote :176]   File "/var/www/certs-management/views.py", line 12, in <module>
[Wed Jan 31 18:59:52.012320 2018] [:error] [pid 3881] [remote :176]     from app import app, db, month_string_to_number
[Wed Jan 31 18:59:52.012347 2018] [:error] [pid 3881] [remote :176] ImportError: cannot import name month_string_to_number

我真的不知道为什么会发生这种情况。要配置此应用程序,我只需按照以下文档进行操作:http://flask.pocoo.org/docs/0.12/deploying/mod_wsgi/

PS:服务器名称不正确,有关远程主机IP的信息也被删除了-我确信这与该问题无关。

谢谢。

这看起来不像是WSGI或Apache的问题,而是你有循环导入的事实。在您的app.py中,您正在从views.py导入所有内容:

from views import *

views.py中,您从app.py导入回来:

from app import app, db, month_string_to_number

真正的问题是您使用from ... import ...导入。如果您改用import views然后将对象称为views.xyz,它应该可以工作。在Reddit上查看此回复,以防您了解原因。

如果这解决了您的问题,或者是否有其他问题,请告诉我们。

在检查了雷纳托的建议后,我做了一些不同的事情来解决这个问题。事实上,真正的问题是循环导入,而不是WSGI,不是Apache。

我没有app.pyviews.py调用一个函数,而是将这个函数month_string_to_number移到views.py,并将导入从app.py中删除到views.py

它解决了这个问题。

如果您遇到此类问题,则应检查循环导入以确保您没有犯此错误。

最新更新