Как запустить сервер flask из другого модуля?

#python #flask

#python #flask

Вопрос:

Я пытаюсь запустить сервер flask из другого модуля, а затем закрыть сервер (это не главное в приложении), в настоящее время код выглядит следующим образом для webserver.py

 from flask import Flask, render_template
from flask_classful import FlaskView
import os
from werkzeug.utils import secure_filename
from flask import request



host = 'localhost'
debug = True


app = Flask (__name__)
app.config

@app.route('/')

def main(): 
   return render_template("index.html")
def run():
    if __name__ == 'Refactor2': 
        app.run(ssl_context = (r"path_to_cert", r"path_to_key"), host = "localhost", port = 443)

def shutdown_server(): 
    func = request.environ.get('werkzeug.server.shutdown')
    if func is None:
        raise RuntimeError('Not running with the Werkzeug Server')
    func()

def shutdownServer():
   shutdown_server() 
   return "Server is shutting down"
 

Затем я пытаюсь запустить это в следующем модуле (с именем Refactor2):

 import webserver 

class buyer:
    def __init__(self, email, password):
        self.email = email
        self.password = password
    
    def server_run(self):
        run()
        print("Server has been started")
 

Однако сервер не запускается, и я не могу перейти на веб-страницу. Сообщения об ошибках не отображаются.

Ответ №1:

Кажется необычным способом запуска приложения Flask, но если оставить это в стороне…

Предполагая, что вы используете это с python Refactor2.py , __name__ будет 'webserver' .

Это можно продемонстрировать на минимальном примере:

 $ cat webserver.py 
def run():
    print (__name__)

$ cat Refactor2.py 
import webserver
webserver.run()

$ python Refactor2.py 
webserver
 

Итак, в вашем webserver модуле вы могли бы сделать:

 def run():
    if __name__ == 'webserver':
        app.run(ssl_context = (r"path_to_cert", r"path_to_key"), host = "localhost", port = 443)
 

Или просто:

 def run():
    app.run(ssl_context = (r"path_to_cert", r"path_to_key"), host = "localhost", port = 443)
 

И назовите это как:

 import webserver
# ...
class buyer:
    # ...
    def server_run(self):
        webserver.run()
        print("Server has been started")
 

Конечно, этот «Сервер запущен» фактически не будет достигнут, пока сервер ( webserver.run вызов) не завершится и сервер не остановится.

Опять же, это кажется странным способом запуска приложения. Я предлагаю вам изучить документы о том, как запускать Flask в рабочей среде, поскольку, похоже, то, чего вы пытаетесь достичь, — это работа системы оркестровки, а не сам процесс python. В рабочей среде вы должны использовать сервер WSGI, такой как gunicorn, вместо сервера разработки ( app.run ). Конечно, возможно, вы это уже знаете 😉

Ответ №2:

__name__ дает имя текущего модуля. Итак, в вашем run() методе __name__ , вероятно, решается webserver . Я бы предложил передать имя в качестве переменной в run() from server_run()

webserver.py

 def run(name):
    if name == 'Refactor2':
        app.run(ssl_context = (r"path_to_cert", r"path_to_key"), host = "localhost", port = 443)
 

Рефакторинг2

 import webserver 

class buyer:
    def __init__(self, email, password):
        self.email = email
        self.password = password
    
    def server_run(self):
        run(__name__)
        print("Server has been started")
 

Обратите внимание, что если Refactor2 находится в пакете, вы можете получить имя модуля с точкой, например ‘src.Refactor2’. Возможно, было бы лучше передать более явное имя для запуска, так как при переименовании Refactor2 вам потребуется обновить жесткий код в webserver.py слишком. Что-то вроде

 def server_run(self):
        webserver.run('buyer')
        print("Server has been started")
 

и

(webserver.py )

 def run(name):
    if name == 'buyer':
        app.run(ssl_context = (r"path_to_cert", r"path_to_key"), host = "localhost", port = 443)
 

редактировать: не уверен, что вы предоставили полный пример кода, но также похоже, что, возможно, вы не вызываете правильный run() метод server_run() — похоже, он должен вызываться в модуле веб-сервера, который я отредактировал в своем ответе, чтобы отразить