Ошибка при развертывании приложения Python на AWS Lambda - PullRequest
0 голосов
/ 07 мая 2019

Я создал приложение Python-Tornado и пытаюсь развернуть его на AWS Lambda с помощью zappa.Но я получаю ошибку Ошибка: Внимание!Проверка состояния развернутой лямбды не удалась.Запрос 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()

В чем здесь ошибка и как ее исправить?

1 Ответ

1 голос
/ 07 мая 2019

Похоже, что развертывание прошло успешно, но когда Заппа проверяет, работает ли код, возвращается код возврата 502, что говорит о том, что лямбда-функция не запускается в лямбда-среде.

Взглянув на журналы, критическая строка выглядит следующим образом:

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

И это верно, если мы посмотрим на ваш код, ни в коем случае вы не выставите атрибут с именемapp in main.py.

У меня нет опыта работы с Tornado, но я подозреваю, что если вы переместите объявление 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()
...