Проблема с Flask + Gunicorn + NGINX при работе с gunicorn

У меня нет большого опыта работы с python, и я впервые загружаю что-то вручную (с файлами .conf). У меня есть приложение, созданное с помощью Flask, и я хочу загрузить его на сервер. Я использовал гуникорн и nginx. Nginx выдал несколько ошибок и обнаружил, что приложение не работает с gunicorn (поэтому я еще не отлаживал nginx). Приложение работает нормально с командой flask run --host=0.0.0.0 и с командой python app.py. Я считаю, что ошибка связана с тем, как я импортирую свои файлы в python, но я не уверен. Журнал ошибок такой:

[2022-05-16 15:40:39 +0200] [127342] [INFO] Starting gunicorn 20.1.0
[2022-05-16 15:40:39 +0200] [127342] [INFO] Listening at: http://0.0.0.0:8003 (127342)
[2022-05-16 15:40:39 +0200] [127342] [INFO] Using worker: sync
[2022-05-16 15:40:39 +0200] [127343] [INFO] Booting worker with pid: 127343
[2022-05-16 15:41:09 +0200] [127342] [CRITICAL] WORKER TIMEOUT (pid:127343)
[2022-05-16 15:41:09 +0200] [127343] [INFO] Worker exiting (pid: 127343)
[2022-05-16 15:41:10 +0200] [127350] [INFO] Booting worker with pid: 127350
[2022-05-16 15:41:24 +0200] [127350] [ERROR] Exception in worker process
Traceback (most recent call last):
  File "/var/www/FlaskApp/AppName/venv/lib/python3.10/site-packages/gunicorn/arbiter.py", line 589, in spawn_worker
    worker.init_process()
  File "/var/www/FlaskApp/AppName/venv/lib/python3.10/site-packages/gunicorn/workers/base.py", line 134, in init_process
    self.load_wsgi()
  File "/var/www/FlaskApp/AppName/venv/lib/python3.10/site-packages/gunicorn/workers/base.py", line 146, in load_wsgi
    self.wsgi = self.app.wsgi()
  File "/var/www/FlaskApp/AppName/venv/lib/python3.10/site-packages/gunicorn/app/base.py", line 67, in wsgi
    self.callable = self.load()
  File "/var/www/FlaskApp/AppName/venv/lib/python3.10/site-packages/gunicorn/app/wsgiapp.py", line 58, in load
    return self.load_wsgiapp()
  File "/var/www/FlaskApp/AppName/venv/lib/python3.10/site-packages/gunicorn/app/wsgiapp.py", line 48, in load_wsgiapp
    return util.import_app(self.app_uri)
  File "/var/www/FlaskApp/AppName/venv/lib/python3.10/site-packages/gunicorn/util.py", line 359, in import_app
    mod = importlib.import_module(module)
  File "/usr/lib/python3.10/importlib/__init__.py", line 126, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 1050, in _gcd_import
  File "<frozen importlib._bootstrap>", line 1027, in _find_and_load
  File "<frozen importlib._bootstrap>", line 1006, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 688, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 883, in exec_module
  File "<frozen importlib._bootstrap>", line 241, in _call_with_frames_removed
  File "/var/www/FlaskApp/wsgi.py", line 14, in <module>
    from AppName import app
  File "/var/www/FlaskApp/AppName/app.py", line 19, in <module>
    @app.route('/')
AttributeError: 'NoneType' object has no attribute 'route'
[2022-05-16 15:41:24 +0200] [127350] [INFO] Worker exiting (pid: 127350)
[2022-05-16 15:41:25 +0200] [127342] [INFO] Shutting down: Master
[2022-05-16 15:41:25 +0200] [127342] [INFO] Reason: Worker failed to boot.

Он не может прочитать @app.route('/') из app.py:

-AttributeError: 'NoneType' object has no attribute 'route'

Структура файлов моего проекта:

---AppName
------app.py
------_init_.py (same as app.py)
------main.py (same as app.py)
------file1.py
------file2.py
------folder1
------static
------templates
------folder2
------venv
---wsgi.py
---make-image.sh
---requirements.txt
---gunicorn_starter.sh
---appname.wsgi (I thought maybe the naming needed to be the same with the name of the app)

Я добавил файл сценария оболочки для запуска gunicorn_starter.sh:

#!/bin/sh

gunicorn wsgi:AppName -w 1 --threads 1 -b 0.0.0.0:8003

Примечание: я использовал 2 рабочих 2 потока, затем три, а потом подумал, что для тестирования мне понадобится только один. Не знаю, повлияет ли это на результат.

app.py:

from flask import Flask, request, render_template
from file1 import function

import spacy
from spacy import displacy
nlp = spacy.load("el_core_news_sm")
from flaskext.markdown import Extension,Markdown

def create_app():
        #Init App
        app = Flask(__name__)
        Markdown(app)

app = create_app()

@app.route('/')
def home():
    return render_template('index.html')


@app.route('/submit', methods=['POST'])
def submit():
        variale1 = function(var)
        ....some code...
        return something

if __name__ == '__main__':
        app.run(host='0.0.0.0')

wsgi.py:

import os
import sys

fpath = os.path.join(os.path.dirname(__file__),'AppName')
sys.path.append(fpath)
#print("||the system path||",sys.path)

import file2
import file1
import AppName
from AppName import app

if __name__ == "__main__":
#    app = create_app()
    app.run()

НГИНКС:

Я запускаю его со службой в /etc/systemd/system/AppName.service .

AppName.service:

[Unit]
Description=Gunicorn instance to serve AppName
After=network.target

[Service]
User=user1
Group=www-data
WorkingDirectory=/var/www/FlaskApp/AppName
Environment="PATH=/var/www/FlaskApp/AppName/venv/bin"
ExecStart=/var/www/FlaskApp/AppName/venv/bin/gunicorn -w 2 --bind unix:AppName.sock -m 007 wsgi:app

[Install]
WantedBy=multi-user.target

Здесь nginx выдает ошибку, что он не может подключиться к сокету, и это было из-за того, что gunicorn не был запущен.

Этот сервис используется с /etc/nginx/sites-available/AppName.conf.

AppName.conf:

server {
    listen 80;
    server_name domainname.com www.domainname.com;

    location / {
        include proxy_params;
        proxy_pass http://unix:/var/www/FlaskApp/AppName/AppName.sock;
    }
}

Затем я использую команды:

sudo systemctl start AppName
sudo systemctl enable AppName
sudo systemctl status AppName

И добавить символическую ссылку в site-enabled. Затем я просто запускаю nginx.

Я видел сообщение, в котором говорится об использовании декораторов функций: https://stackoverflow.com/questions/2757496/using-python-decorator-functions-from-a-different-module Но я не знаю многого о питоне, поэтому я очень запутался с этим. Я даже не уверен, является ли это ошибкой или тем, как у меня есть файл в этом.py.

Я следовал этим руководствам:

https://www.linkedin.com/pulse/building-deploying-production-ready-flask-app-anand-iyer

https://gunicorn.org/#deployment

https://docs.gunicorn.org/en/stable/deploy.html

https://towardsdatascience.com/understanding-python-imports-init-py-and-pythonpath-once-and-for-all-4c5249ab6355

https://www.geeksforgeeks.org/decorators-in-python/

Основное руководство, которое я использовал, это:

https://www.digitalocean.com/community/tutorials/how-to-serve-flask-applications-with-gunicorn-and-nginx-on-ubuntu-18-04

Ссылки, которые я использовал для отладки:

https://stackoverflow.com/questions/66834369/heroku-gunicorn-flask-app-running-error

https://stackoverflow.com/questions/8488482/attributeerror-nonetype-object-has-no-attribute-route-and-webapp2

https://stackoverflow.com/questions/2757496/using-python-decorator-functions-from-a-different-module
Анализ настроения постов в Twitter с помощью Python, Tweepy и Flair
Анализ настроения постов в Twitter с помощью Python, Tweepy и Flair
Анализ настроения текстовых сообщений может быть настолько сложным или простым, насколько вы его сделаете. Как и в любом ML-проекте, вы можете выбрать...
7 лайфхаков для начинающих Python-программистов
7 лайфхаков для начинающих Python-программистов
В этой статье мы расскажем о хитростях и советах по Python, которые должны быть известны разработчику Python.
Установка Apache Cassandra на Mac OS
Установка Apache Cassandra на Mac OS
Это краткое руководство по установке Apache Cassandra.
Сертификатная программа "Кванты Python": Бэктестер ансамблевых методов на основе ООП
Сертификатная программа "Кванты Python": Бэктестер ансамблевых методов на основе ООП
В одном из недавних постов я рассказал о том, как я использую навыки количественных исследований, которые я совершенствую в рамках программы TPQ...
Создание персонального файлового хранилища
Создание персонального файлового хранилища
Вы когда-нибудь хотели поделиться с кем-то файлом, но он содержал конфиденциальную информацию? Многие думают, что электронная почта безопасна, но это...
Создание приборной панели для анализа данных на GCP - часть I
Создание приборной панели для анализа данных на GCP - часть I
Недавно я столкнулся с интересной бизнес-задачей - визуализацией сбоев в цепочке поставок лекарств, которую могут просматривать врачи и...
0
0
23
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Добавьте в оператор возврата функции create_app. В конце функции поместите return app.

Без него он возвращает None, поэтому ожидается, что python не знает, что такое app.route.

Спасибо тебе за это. Я слишком много думал об этом как о веб-приложении и меньше как о питоне. Не могу поверить, что совершил такую ​​ошибку новичка!

thesamurai23 17.05.2022 10:44

Другие вопросы по теме