使用Zappa部署Flask至AWS Lambda时遇'Flask对象不可迭代'错误
问题描述
我是一名新手,正在尝试使用Zappa将Flask应用部署到AWS Lambda。我的Flask应用目录结构如下:
backend ├── __init__.py ├── __pycache__ ├── app.py ├── databases ├── home.py ├── static ├── templates └── utils.py
app.py中通过initialize_app函数实例化应用,代码如下:
import os from flask import Flask as FlaskApp from flask_cors import CORS import boto3 import logging from backend import home def initialize_app(test_config=None, *args, **kwargs): print("MADE IT HERE TOO") # create and configure the app app = FlaskApp(__name__, instance_relative_config=True) # Set up logging logger = logging.getLogger() logger.setLevel(logging.INFO) logger.info("Boto3 Version: %s", boto3.__version__) print("APP HAS REACHED THIS POINT") s3_client = boto3.client('s3') print("Here too...") # Example of logging try: response = s3_client.list_buckets() logger.info("S3 Buckets: %s", response['Buckets']) except Exception as e: logger.error("Error accessing S3: %s", str(e)) if test_config is None: # load the instance config, if it exists, when not testing app.config.from_pyfile('config.py', silent=True) else: # load the test config if passed in app.config.from_mapping(test_config) print("made it here before os makedirs") # ensure the instance folder exists try: os.makedirs(app.instance_path) except OSError: pass print("made it here before home") app.register_blueprint(home.bp) print("made it here after home") return app
home蓝图中配置了根路由:
bp = Blueprint('home', __name__, url_prefix='/') @bp.route('/') def index(): return "Welcome to the Home Page!"
Zappa配置如下:
{ "dev": { "app_function": "backend.app.initialize_app", "aws_region": "af-south-1", "exclude": [ "boto3", "dateutil", "botocore", "s3transfer", "concurrent", "node_modules", "frontend", "awsTests" ], "profile_name": "default", "project_name": "backend", "runtime": "python3.10", "s3_bucket": "zappa-htprl75eu", "slim_handler": true }
CloudWatch日志显示所有初始化打印语句均正常输出,但Lambda实例返回错误:'Flask' object is not iterable。我排查了home.py未发现调用app的问题,怀疑是Zappa使用返回的app的方式触发错误。使用Python 3.10.6,依赖包列表如下:
argcomplete==3.5.1 blinker==1.7.0 boto3==1.35.32 botocore==1.35.32 certifi==2024.8.30 cffi==1.17.1 cfn-flip==1.3.0 charset-normalizer==3.3.2 click==8.1.7 cryptography==43.0.1 durationpy==0.9 Flask==3.0.2 Flask-Cors==4.0.0 hjson==3.1.0 idna==3.10 itsdangerous==2.1.2 Jinja2==3.1.3 jmespath==1.0.1 kappa==0.6.0 MarkupSafe==2.1.5 pdf2image==1.17.0 pillow==10.3.0 placebo==0.9.0 pycparser==2.22 PyJWT==2.9.0 PyMuPDF==1.24.2 PyMuPDFb==1.24.1 python-dateutil==2.9.0.post0 python-slugify==8.0.4 PyYAML==6.0.2 requests==2.32.3 s3transfer==0.10.2 six==1.16.0 text-unidecode==1.3 toml==0.10.2 tqdm==4.66.5 troposphere==4.8.3 urllib3==2.2.3 Werkzeug==3.0.1 zappa==0.59.0
问题原因及解决办法
原因
Zappa的app_function配置项需要指向Flask应用实例,而非返回实例的函数。当前配置中backend.app.initialize_app是函数,Zappa调用它后会错误地将返回的Flask实例当作可迭代对象处理,从而抛出'Flask' object is not iterable错误。
解决方法
方式一:直接创建Flask实例供Zappa引用
修改app.py,在函数外生成应用实例:
# 保留原initialize_app函数不变 def initialize_app(test_config=None, *args, **kwargs): # 原函数内容 ... # 直接初始化应用实例 app = initialize_app()
然后更新Zappa配置中的app_function:
"app_function": "backend.app.app"
方式二:用Zappa包装器处理初始化函数
如果需要保留动态初始化逻辑,可使用Zappa的lambda_handler包装函数,修改app.py:
from zappa.handlers import lambda_handler # 保留原initialize_app函数不变 def initialize_app(test_config=None, *args, **kwargs): # 原函数内容 ... # 包装初始化函数 handler = lambda_handler(initialize_app)
再更新Zappa配置:
"app_function": "backend.app.handler"
额外注意
- 部署前激活虚拟环境,重新执行
zappa update dev或zappa deploy dev - Lambda环境仅允许写入
/tmp目录,os.makedirs(app.instance_path)可能失败,建议将需要写入的路径改为/tmp,或移除该逻辑(若无需实例文件夹)
内容的提问来源于stack exchange,提问作者user8188120
相关产品推荐
相关产品推荐

