AWS Ubuntu部署Flask应用报错:'Flask'对象不可迭代
解决Flask部署Gunicorn时的TypeError: 'Flask' object is not iterable错误
在AWS Ubuntu服务器部署Flask应用时,Gunicorn日志显示处理/favicon.ico请求时出现如下错误,自行排查未解决:
错误日志
[2023-12-29 22:32:39 +0000] [5686] [ERROR] Error handling request /favicon.ico Traceback (most recent call last): File "/home/ubuntu/venv/lib/python3.10/site-packages/gunicorn/workers/sync.py", line 135, in handle self.handle_request(listener, req, client, addr) File "/home/ubuntu/venv/lib/python3.10/site-packages/gunicorn/workers/sync.py", line 183, in handle_request for item in respiter: TypeError: 'Flask' object is not iterable
相关代码
main.py
from myAPP import create_app from flask_mail import Mail import base64 # 补充缺失的导入 app = create_app() @app.template_filter('custom_b64encode') def custom_b64encode(data): return base64.b64encode(data).decode('utf-8') from flask import render_template @app.errorhandler(404) def not_found_error(error): return render_template('404.html'), 404 # 移除重复注册的蓝图,create_app中已完成注册 # from myAPP.views import views # app.register_blueprint(views, name='my_views') app.config['UPLOAD_FOLDER'] = '/photos/' if __name__ == '__main__': app.run()
init.py
import os from flask import Flask from flask_sqlalchemy import SQLAlchemy from flask_login import LoginManager from flask_mail import Mail db = SQLAlchemy() DB_NAME = "database.db" mail = Mail() # 全局初始化mail UPLOAD_FOLDER = '/photos/' # 定义UPLOAD_FOLDER def create_app(): # 移除错误添加的environ和start_response参数 app = Flask(__name__) app.config['SQLALCHEMY_DATABASE_URI'] = f'sqlite:///{DB_NAME}' app.config['SECRET_KEY'] = 'SecretKey' app.config['SECURITY_PASSWORD_SALT'] = 'SecurityPasswordSalt' app.config['MAIL_SERVER'] = 'example.home.pl' app.config['MAIL_PORT'] = 587 app.config['MAIL_USE_TLS'] = True app.config['MAIL_USE_SSL'] = False app.config['MAIL_USERNAME'] = os.environ.get('MAIL_USERNAME', 'username') app.config['MAIL_PASSWORD'] = os.environ.get('MAIL_PASSWORD', 'password') app.config['MAIL_DEFAULT_SENDER'] = 'defaultSender@example.com' db.init_app(app) mail.init_app(app) with app.app_context(): db.create_all() from .views import views from .auth import auth app.register_blueprint(views, url_prefix='/') app.register_blueprint(auth, url_prefix='/') from .models import User, Photo login_manager = LoginManager() login_manager.login_view = 'auth.loginPage' login_manager.init_app(app) @login_manager.user_loader def load_user(id): return User.query.get(int(id)) from . import models with app.app_context(): db.create_all() return app app = create_app() app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER from itsdangerous import URLSafeTimedSerializer s = URLSafeTimedSerializer(app.config['SECRET_KEY'])
问题原因及修复步骤
核心问题
create_app函数被错误添加了environ和start_response参数——这是WSGI应用的回调签名,但create_app是Flask应用工厂函数,返回的是Flask实例。Gunicorn会将请求参数传给应用入口,若指向带WSGI参数的工厂函数,会导致把Flask实例当作可迭代的响应对象处理,触发TypeError。
修复步骤
- 修正create_app函数签名:移除
create_app的environ=None, start_response=None参数,恢复为无参的应用工厂函数(如上述__init__.py代码所示)。 - 移除重复蓝图注册:main.py中重复注册了views蓝图,create_app内已完成注册,需删除该部分代码避免路由冲突。
- 补充缺失的导入:main.py中使用
base64但未导入,需添加import base64。 - 修正UPLOAD_FOLDER未定义问题:在__init__.py开头定义
UPLOAD_FOLDER,避免末尾配置时出错。 - 正确配置Gunicorn启动命令:确保启动时指向已创建的Flask实例,而非工厂函数。例如:
或指向myAPP模块中的app实例:gunicorn main:app --bind 0.0.0.0:8000gunicorn myAPP:app --bind 0.0.0.0:8000
内容的提问来源于stack exchange,提问作者Mortyk Manu
相关产品推荐
相关产品推荐

