Уведомления

Группа в Telegram: @pythonsu

#1 Фев. 6, 2022 19:32:51

Nev
Зарегистрирован: 2022-02-06
Сообщения: 8
Репутация: +  0  -
Профиль   Отправить e-mail  

настройка gunicorn для работы с flask в функции

Мне необходимо создавать Flask сервер из функции (на самом деле это будет метод в классе)
Локально все работает, но на сервере через gunicorn не работает.

я уже пробовал много разных вариантов, вот лишь один из них.

 #  file test.py
 def serv():
    from flask import Flask
    app = Flask(__name__)
    @app.route("/")
    def hello():
        return "<h1 style='color:red'>Hello world!</h1>"
    if __name__ == "__main__":
        app.run()
    return app
# file wsgi.py
from test import serv
if __name__ == "__main__":
    serv().run()
Все работает локально. Но деплой на сервере с gunicorn и сервер возвращает 503 ошибку.
Если убрать функцию и импортировать без функции, все работает и даже с более простым кодом.

Очевидно, что требуется либо поднастройка gunicorn, либо иной оборот написания функции для данного модуля. Но у меня не хватает опыта разобраться. Прошу помощи.

Офлайн

#2 Фев. 7, 2022 00:33:09

py.user.next
От:
Зарегистрирован: 2010-04-29
Сообщения: 9873
Репутация: +  853  -
Профиль   Отправить e-mail  

настройка gunicorn для работы с flask в функции

Nev
Мне необходимо создавать Flask сервер из функции
Nev
на самом деле это будет метод в классе
Лучше объясни, что ты пытаешься сделать. Пока не поздно.

Иначе понастроишь тупости всякой, а потом придёшь вот к этому
Nev
Если убрать функцию и импортировать без функции, все работает и даже с более простым кодом.

Код твой выглядит очень странно с точки зрения питона. Видно, что ты плохо знаешь сам питон. Локальные импорты, например, не приняты, пишутся новичками, пока они не прочитали базовые вещи вроде PEP8. То же самое касается цепочки вызовов. Новичкам кажется, что это очень удобно, но на деле ты не сможешь отделить исключение из одного метода от исключения из другого метода в цепочке.

Это вот пример, когда из-за цепочки ты не можешь понять, где именно произошла ошибка
  
import random
 
class A:
    def f(self):
        if random.randint(1, 10) > 5:
            raise ValueError('1')
        else:
            return B()
 
class B:
    def f(self):
        if random.randint(1, 10) > 5:
            raise ValueError('1')
        else:
            return C()
 
class C:
    def f(self):
        if random.randint(1, 10) > 5:
            raise ValueError('1')
        else:
            return 'c'
 
obj = A()
 
try:
    print(obj.f().f().f())
except ValueError as e:
    print('error {} in ?'.format(e))
Когда эта ошибка будет писаться в лог, там вообще просто будет стоять “ошибка 1” и даже не будет возможности залезть в код и поискать проблему. То есть цепочка вызовов - это удобная вещь, но это удобство как раз и закладывает мину замедленного действия. Потом, будучи пользователем какой-нибудь такой программы, когда она посыпется в очередной раз, ты сто пятьсот раз поблагодаришь автора программы за его величайший ум - а именно за неинформативные логи.



Отредактировано py.user.next (Фев. 7, 2022 22:01:05)

Офлайн

#3 Фев. 7, 2022 09:38:31

Nev
Зарегистрирован: 2022-02-06
Сообщения: 8
Репутация: +  0  -
Профиль   Отправить e-mail  

настройка gunicorn для работы с flask в функции

Спасибо за интерес к моей задаче)

Лучше объясни, что ты пытаешься сделать. Пока не поздно.
Хочу написать микрофреймворк на Flask. К серверу будут приходить запросы, на них нужно будет отвечать.
Идея была реализации через Class где будет один внешний метод для запуска Flask, а внутри во время разбора пришедшего запроса “дергаться” другие методы этого класса.

Видно, что ты плохо знаешь сам питон. Локальные импорты, например, не приняты, пишутся новичками, пока они не прочитали базовые вещи вроде PEP8.
Так как пишется готовый модуль. Модуль test.py планируется единственным. wsgi.py использует его методы.

Это вот пример, когда из-за цепочки ты не можешь понять, где именно произошла ошибка
Согласен. Эту цепочку вызовов будет сложно тестировать.

Я все же не пойму на чьей стороне ошибка. Это внутренние настройки gunicorn или особенность Heroku?
Думал, что все дело в модуле который gunicorn отслеживает для ответа на запрос. Но даже если принудительно передать __name__ из wsgi.py например так:
 # file test.py
def servflask(nam):
    from flask import Flask
    app = Flask(nam)
    @app.route("/")
    def hello():
        return "<h1 style='color:blue'>Hello There!</h1>"
    return app
# file wsgi.py
from test import servflask
servflask(__name__).run()
То опять же, локально все работает. Но gunicorn начинает заваливать ошибками.
Exception in worker process
Хотя сервер запущен как и положено из основного модуля, явно указанного в app, о чем свидетельствует лог запуска:
Serving Flask app ‘wsgi’ (lazy loading)

Так как же запустить flask через функцию? Почему этого не удается сделать?

Отредактировано Nev (Фев. 7, 2022 09:39:46)

Офлайн

#4 Фев. 7, 2022 16:13:41

Nev
Зарегистрирован: 2022-02-06
Сообщения: 8
Репутация: +  0  -
Профиль   Отправить e-mail  

настройка gunicorn для работы с flask в функции

все я разобрался. Всем спасибо

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version