将Python应用程序部署到AWS Lambda时的错误



我已经构建了一个Python-Tornado应用程序,并试图使用Zappa将其部署到AWS Lambda。但是,我遇到了一个错误错误:警告!状态检查已部署的Lambda失败。``/''的get请求产生了502响应代码。

根文件夹内的文件夹结构是:

├── amortization.py
├── config.py
├── dmi-amort-dev-1557138776.zip
├── main.py
├── requirements.txt
├── venv
│   ├── bin
│  
└── zappa_settings.json

zappa deploy dev给我:

Calling deploy for stage dev..
Downloading and installing dependencies..
- pandas==0.24.2: Using locally cached manylinux wheel
- numpy==1.16.3: Using locally cached manylinux wheel
- sqlite==python3: Using precompiled lambda package
Packaging project as zip.
Uploading dmi-amort-dev-1557143681.zip (30.8MiB)..
100%|█████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 32.3M/32.3M [00:19<00:00, 1.94MB/s]
Scheduling..
Scheduled dmi-amort-dev-zappa-keep-warm-handler.keep_warm_callback with expression rate(4 minutes)!
Uploading dmi-amort-dev-template-1557143718.json (1.5KiB)..
100%|█████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 1.56K/1.56K [00:00<00:00, 10.6KB/s]
Waiting for stack dmi-amort-dev to create (this can take a bit)..
75%|█████████████████████████████████████████████████████████████████████████████████████████████████████▎                                 | 3/4 [00:09<00:04,  5.00s/res]
Deploying API Gateway..
Error: Warning! Status check on the deployed lambda failed. A GET request to '/' yielded a 502 response code.

zappa tail给我

Traceback (most recent call last):
File "/var/task/handler.py", line 602, in lambda_handler
return LambdaHandler.lambda_handler(event, context)
File "/var/task/handler.py", line 245, in lambda_handler
handler = cls()
File "/var/task/handler.py", line 142, in __init__
wsgi_app_function = getattr(self.app_module, self.settings.APP_FUNCTION)
AttributeError: module 'main' has no attribute 'app'

zappa_settings.json

{
    "dev": {
        "app_function": "main.app",
        "aws_region": "ap-south-1",
        "profile_name": "default",
        "project_name": "dmi-amort",
        "runtime": "python3.6",
        "s3_bucket": "zappa-mekp457ye",
        "manage_roles": false,
        "role_name": "lambda-role",
    }
}

main.py

import tornado.web
from tornado.ioloop import IOLoop
from tornado.web import MissingArgumentError
from config import get_arguments
from amortization import get_amort_schedule
class MainHandler(tornado.web.RequestHandler):
    def prepare(self):
        """Checking if all the required parameters are present."""
        if self.request.method != 'POST':
            self.write_error(status_code=405, message="Method not allowed")
            return
        self.parameters = dict()
        for key in get_arguments():
            try:
                self.parameters[key] = self.get_argument(key)
            except MissingArgumentError:
                self.write_error(status_code=400,
                                message="Missing Argument(s)")
                return
        # checking if 'label' is provided
        if 'label' in self.request.arguments.keys():
            self.parameters['label'] = self.get_argument('label')
        # Set up response dictionary.
        self.response = dict()
    def get(self, *args, **kwargs):
        self.write_error(status_code=405, message="Method not allowed")
    def post(self, *args, **kwargs):
        """Executes the main logic part."""
        self.response = get_amort_schedule(self.parameters)
        self.write_json()
    def set_default_headers(self):
        """Sets content-type as 'application/json' for response as JSON."""
        self.set_header('Content-Type', 'application/json')
    def write_error(self, status_code, **kwargs):
        """Invokes when error occurs in processing the request."""
        if 'message' not in kwargs:
            if status_code == 405:
                kwargs['message'] = 'Invalid HTTP method.'
            else:
                kwargs['message'] = 'Unknown error.'
        kwargs["error"] = True
        self.set_status(status_code=status_code)
        self.response = dict(kwargs)
        self.write_json()
    def write_json(self):
        """Responsible for writing the response."""
        if "status" in self.response:
            self.set_status(self.response.get("status"))
        self.set_default_headers()
        self.write(self.response)
        self.finish()

def main():
    app = tornado.web.Application([
        (r'/', MainHandler),
    ], debug=True)
    # server = HTTPServer(app)
    # server.bind(8888)
    # server.start(0)
    app.listen()
    # app.run(host='0.0.0.0')
    IOLoop.current().start()

if __name__ == '__main__':
    main()

这里有什么错误,我该如何解决?

看起来部署成功了,但是当Zappa检查代码是否正常工作时,返回代码是502,这表明LAMBDA函数未能在lambda中运行环境。

看日志,关键行是:

AttributeError: module 'main' has no attribute 'app'

这是事实,如果我们查看您的代码,您绝不会在main.py中公开一个称为app的属性。

我对龙卷风没有经验,但我怀疑如果您将app的声明从main()功能移出并进入根部范围,则处理程序应该成功。

例如:

        # rest of the file...
        self.finish()
app = tornado.web.Application([
    (r'/', MainHandler),
], debug=True)
app.listen()
def main():
    IOLoop.current().start()
if __name__ == '__main__':
    main()

最新更新