I am working on python project which includes starting a flask API server on a button click. For buttons and UI I am using pyqt5. So on start server button click flask api server will start and on stop server button click, flask api server will stop.
I am able to start the server but the problem is when we start the flask api server, we use app.run(HOST, 80). During this the control always remains here and doesnt move out of it due to which when I click stop button, it doesnt stop. Below is the code:
app.py
import sys
import time
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton
from server import start_local_server
from PyQt5.QtCore import pyqtSlot
from threading import Thread
run = True
def start_api_server():
while run:
start_local_server()
print("server is running")
time.sleep(1)
print("SERVER HAS STOPPED")
class App(QWidget):
global run
def __init__(self):
super().__init__()
self.title = 'PyQt5 button - pythonspot.com'
self.left = 10
self.top = 10
self.width = 320
self.height = 200
self.initUI()
def initUI(self):
self.setWindowTitle(self.title)
self.setGeometry(self.left, self.top, self.width, self.height)
start_btn = QPushButton('Start Server', self)
start_btn.move(100, 70)
start_btn.clicked.connect(self.on_click_start_btn)
stop_btn = QPushButton('Stop Server', self)
stop_btn.move(200, 70)
stop_btn.clicked.connect(self.on_click_stop_btn)
fun_btn = QPushButton('Click to check responsiveness', self)
fun_btn.move(150, 100)
fun_btn.clicked.connect(self.on_click_fun_btn)
self.show()
@pyqtSlot()
def on_click_start_btn(self):
Thread(target=start_api_server).start()
@pyqtSlot()
def on_click_stop_btn(self):
print("Stop server ")
run = False
@pyqtSlot()
def on_click_fun_btn(self):
print('If it is working, this means UI is responsive')
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = App()
sys.exit(app.exec_())
In above code, I have button click function on_click_start_btn this starts a thread with target start_api_server. This will further start the local flask server. When I want to stop the server, I will simply make run as False which will break the start_api_server function and the server will stop. As per my understanding this should work fine.
Below is the code for flask api:
server.py
import os
import datetime
from flask import Flask, jsonify
from flask_cors import CORS
app = Flask(__name__)
CORS(app)
wsgi_app = app.wsgi_app
@app.route('/api/status')
def check_status():
return jsonify({'status': 'ok', 'date': datetime.datetime.now().isoformat()}), 200
def start_local_server():
HOST = os.environ.get('SERVER_HOST', 'localhost')
try:
PORT = int(os.environ.get('SERVER_PORT', '5555'))
except ValueError:
PORT = 5555
app.run(HOST, 80)
The problem occurs in above flask code. In above code, there is function start_local_server() which we are using in app.py. In this we have app.run(), when our code reaches here, it always remains here and never moves out it due to which I am not able to stop this server.
I want to simply make code where I can start and stop the flask server using button click but due to app.run, its not working. Can anyone please help me with this issue. Is there any alternative to above problem. Please help. Thanks
Updated code as per answer:
server = Process
def start_local_server():
global server
server = Process(target=app.run, args=('localhost', 80))
# HOST = os.environ.get('SERVER_HOST', 'localhost')
# try:
# PORT = int(os.environ.get('SERVER_PORT', '5555'))
# except ValueError:
# PORT = 5555
# app.run(HOST, 80)
def stop_local_server():
global server
server.terminate()