在没有 CMD 的情况下运行 Flask API [英] Running Flask API without CMD

查看:40
本文介绍了在没有 CMD 的情况下运行 Flask API的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在一家在本地计算机和服务器上部署系统的公司工作.

I'm working on a company that deploy their system on local computer and servers.

给我的任务是创建一个 python 应用程序,它与 plc 通信并使用 Reactjs/Electron.js 显示收集的数据或将数据保存在 MS SQL Server>.

The task given to me is to create a python application which communicates with a plc and display gathered data using Reactjs/Electron.js or save the data on MS SQL Server.

我的想法是使用 tkinter 创建 gui,并通过创建 .spec 文件和 pyinstaller 将其转换为应用程序看起来像 XAMPP,我可以在其中重新启动并启动 api.

My idea was to create gui using tkinter and convert it to an app by creating a <filename>.spec file and pyinstaller that look like XAMPP where I could restart and start the api.

如果我使用 tkinter 我应该从哪里开始?当 gui 打开时,我设法启动了后端,但我不知道停止或重新启动后端.我对 threads 也没有太多想法,但我认为它会帮助我创建我想要的东西.

If I use tkinter where should I start? I manage to start the backend when the gui opened but I have no clue to stop or restart the backend. I also don't have much idea on threads but I think it would help me create what I want.

我也在寻找是否可以使用 XAMPP 作为主机来运行 api 但没有运气.

I was also searching if I could use XAMPP as a host to run the api but no luck.

如果你们有更好的方法在没有 cmd 的情况下在本地主机上运行 api 真的会有所帮助

If you guys have a better way to run the api on localhost without the cmd would really help

推荐答案

好的,所以这花了一段时间但我想出了如何不使用 subprocess(主要是因为还有一个关于不使用的问题python 所以唯一的方法是将烧瓶应用程序转换为 .exe 然后使用 subprocess 但我发现如何只使用 python),主要问题(简单修复,但在使用 subprocess.Popen 时也必须解决)是flask 重新启动启动另一个进程的服务器,因此您必须使用 use_reloader=False.run() 方法中的代码>.评论中的解释:

Ok, so this took a while but I figured out how to not use subprocess (mainly because there was another question regarding not using python so the only way would be to convert flask app to .exe and then use subprocess but I found out how to do this using just python), the main issue (simple fix but has to be resolved when using subprocess.Popen too) is that flask restarts the server which starts another process so you have to use use_reloader=False in .run() method. Explanation in comments:

app.py

# import what's necessary
from flask import Flask, render_template_string, url_for
from flask import request


app = Flask(__name__)


# sample route
@app.route('/')
def home():
    return render_template_string('<a href="{{ url_for("about") }}">To About Page</a>'
                                  '<h1>Home Page</h1>')


# sample route
@app.route('/about')
def about():
    return render_template_string('<a href="{{ url_for("home") }}">To Home Page</a>'
                                  '<h1>About Page</h1>')


# important route that will do the stopping part since that was a requirement in the question
# link to this in the answer at the bottom
@app.route('/kill_server', methods=['GET'])
def kill_server():
    func = request.environ.get('werkzeug.server.shutdown')
    if func is None:
        raise RuntimeError('Not running with the Werkzeug Server. Could not shut down server.')
    func()
    return 'Server shutting down...'


# to prevent this from running when importing
if __name__ == '__main__':
    app.run(debug=True)

run.py

# import all that is necessary
from tkinter import Tk, Text, Button, Frame
from for_so_dir.app import app as server
from threading import Thread
from queue import Queue, Empty
import requests
import logging.handlers


# simple dictionary to avoid using `global`, just a preference of mine
info = {'server_is_running': False}


# the function that starts server (multiprocessing is not possible with flask as far as I know)
# basically checks if the server is not running already and if it is not then starts a thread
# with the server (which is the same as `app` in the app.py) and sets that server is running
def start_server():
    if info['server_is_running']:
        return
    Thread(target=server.run, kwargs={'debug': True, 'use_reloader': False}, daemon=True).start()
    info['server_is_running'] = True


# function from stopping server, again in the answer at the bottom, but basically
# this sends a request to the server and that request executes a function
# that stops the server
def stop_server():
    if not info['server_is_running']:
        return
    requests.get('http://127.0.0.1:5000/kill_server')


# function for showing the logs in the Text widget, it simply tries to get data from
# the queue (if there is nothing it simply loops again) and then inserts that data into
# the text widget
def update_text_log():
    try:
        data = queue.get(block=False)
    except Empty:
        pass
    else:
        log.config(state='normal')
        log.insert('end', data.msg + '\n')
        log.config(state='disabled')
    finally:
        root.after(100, update_text_log)


# this `if statement` is not that necessary in the current code but it might as well
# stay here
if __name__ == '__main__':
    # initialise the Queue
    queue = Queue()
    # now the main part, to get the info from flask you need to use `logging`
    # since that is what it uses for all the messages, and use the `QueueHandler`
    # to put the messages in the queue and then update them using the above
    # function
    logging.basicConfig(handlers=(logging.handlers.QueueHandler(queue), ))
    
    # simple `tkinter` stuff
    root = Tk()
    # this part can be removed or made toggleable but it allows to easier see how
    # this works in action
    root.attributes('-topmost', True)

    log = Text(root, state='disabled')
    log.pack(expand=True, fill='both')

    update_text_log()

    button_frame = Frame(root)
    button_frame.pack(fill='x')
    Button(button_frame, text='Start Server', command=start_server).pack(expand=True, fill='x', side='left')
    Button(button_frame, text='Stop Server', command=stop_server).pack(expand=True, fill='x', side='right')

    root.mainloop()

来源:

唯一的问题是在控制台中显示启动消息,有一种方法可以通过添加 import os 然后添加 os.environ['WERKZEUG_RUN_MAIN'] = 'true' 来删除它app.py 文件,但有一个小问题,那就是使用按钮停止服务器将执行以下操作:Process finished with exit code 15(在至少在 Windows 上)所以你必须找到一种方法来解决这个问题,因为我还不能这样做

The only issue is about displaying the starting message in console, there is a way to remove it by adding import os and then os.environ['WERKZEUG_RUN_MAIN'] = 'true' to the app.py file but there is a slight issue then that stopping the server using the button will do this: Process finished with exit code 15 (at least on Windows) so you will have to find a way to workaround this since I am not able yet to do so

这篇关于在没有 CMD 的情况下运行 Flask API的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆