wxPython and Flask integration - python

I am trying to integrate wxPython and Flask into a single application, but I am not sure how to get them to work together as they both want exclusive use of the main thread.
I am calling the application with:
export FLASK_APP=keypad_controller
python3 -m flask run -p 2020 -h 0.0.0.0 --eager-loading --no-reload
The main code block using Flask is:
from flask import Flask
def create_app(test_config=None):
app = Flask(__name__)
return app
I am not sure how to integrate wxPython (below) into the above code, how do I run flask?
wx_app = wx.App()
main_window = MainWindow(config)
main_window.Show()
wx_app.MainLoop()

Start Flask (app.run()) in a separate thread.
Not that if you want app.run(debug=True), you must also pass use_reloader=False, because things will go off the rails quickly if Flask decides that it wants needs to reload anything from other than the main thread.

Related

make flask manage.py multithreaded

I'm using python, flask and and manage.py to create a backend-website with different routes, like /api/foo and /api/bar.
When accessing /api/foo the code should request data from /api/bar and process those data. But this (post-) request hangs endless, probably because the flask server is single threaded.
Currently the web-endpoint for /api/foo and /api/bar is started that way:
from flask_script import Manager
app = create_app(os.getenv('FLASK_CONFIG') or 'default')
manager = Manager(app)
if __name__ == '__main__':
manager.run()
So no app.run() is needed. This means, it's not possible to call something like app.run(threaded=True). But manager.run() does not support the threaded=True parameter.
How can I made the manage.py multi threaded?
btw: This is currently for development only. In production this app will use gunicorn or uWSGI later.

How to emit data from background process to Flask-SocketIO

emitted data from different process to socketio but not working
I created Flask App in which I am using Flask-SocketIO framework. The code for flask app is below:
from web import create_app, socketio
app = create_app()
if __name__ == '__main__':
socketio.run()
I am running this using flask run command.
But I have another python script in which I am importing socketio and want to emit data to client's browser.
# cli-script.py
import time
from web import socketio
def demo():
while 1:
socketio.emit('my-event', ("My Data"))
time.sleep(10)
demo()
My flask application folder structure looks like this:
/-
web
__init__.py
code.py
web-script.py
cli-script.py
and I am running two python processes:
flask run
python cli-script.py
Why this doesn't work ?

Python Flask - How to start python server using flask and execute it multiple times using multiple argumens

I have tested basic Flask script (hello.py) and it is working fine. I have commented out the main function routing part and just executed the script.
from flask import Flask
app = Flask(__name__)
''' #Commenting the Main function part
#app.route("/")
def main():
return "Welcome!"
'''
if __name__ == "__main__":
app.run(host= '0.0.0.0')
As expected, the server is started and I got the following message as well :
C:\>python hello.py
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
Now my requirement is once this python server is started, how to execute another python script and route to this python server.
For example I have the following script which needs to be executed via browser (since the python server is already up and running) by accessing http://127.0.0.1:5000/arg1/arg2
import .....
from flask import Flask
app = Flask(__name__)
#app.route('/<string:arg1>/<string:arg2>')
def main():
do something ........
call sub-function(arg1, arg2)
do something ........
if __name__ == '__main__':
arg1 = 100
arg2 = 50
#app.run(debug=True) **#I should not run this again as server is already started.So commented it out**
main(arg1, arg2) #Calling Main function using two IDs as arguments.
Note : If i keep app.run() in the actual program script which needs to be executed, then it is working fine. But my requirement is server start script actual program script should be different but somehow interlinked via app. I am not sure how to achieve this.
Here it seems that you want the same API(with the same port number all the time) to be called when you run the python script. that can be done by addingapp.run(port=50000, debug=True) at the end.
And place all #app.route() in that same python script (App.py) by migrating body of the Def methodName(): to a different Python script in the same directory and calling that by addingfrom .SubScript import *
The SubScript.py files has to have classes to be called in App.py as objects. and in those classes methods needs to be called def methodName(self): in order to be run as an object
This way you have clean and organized code base to use with python flask. If you can use the Pycharm editor the process will be much easier.

Specify number of processes for eventlet wsgi server

I am trying to add websocket functionality to an existing application. The existing structure of the app is
In /server/__init__.py:
from connexion import App
...
connexion_app = App(__name__, specification_dir='swagger/') # Create Connexion App
app = connexion_app.app # Configure Flask Application
...
connexion_app.add_api('swagger.yaml', swagger_ui=True) # Initialize Connexion api
In startserver.py:
from server import connexion_app
connexion_app.run(
processes=8,
debug=True
)
In this way, I was able to specify the number of processes. There are some long-running tasks that make it necessary to have as many processes as possible.
I have modified the application to include websocket functionality as below. It seems to be that I only have one process available. Once the application attempts to run one of the long-running processes, all API calls hang. Also, if the long-runnign process fails, the application is stuck in a hanging state
In /server/__init__.py:
from connexion import App
import socketio
...
connexion_app = App(__name__, specification_dir='swagger/') # Create Connexion App
sio = socketio.Server() # Create SocketIO for websockets
app = connexion_app.app # Configure Flask Application
...
connexion_app.add_api('swagger.yaml', swagger_ui=True) # Initialize Connexion api
In startserver.py:
import socketio
import eventlet
from server import sio
from server import app
myapp = socketio.Middleware(sio, app)
eventlet.wsgi.server(eventlet.listen(('', 5000)), myapp)
What am I missing here?
(side note: If you have any resources available to better understand the behemoth of the Flask object, please point me to them!!)
Exact answer to question: Eventlet built-in WSGI does not support multiple processes.
Approach to get the best solution for described problem: share one file that contains absolute minimum code required to reproduce problem. Maybe here https://github.com/eventlet/eventlet/issues or any other way you prefer.
Way of hope. Random stuff to poke at: eventlet.monkey_patch(), isolate Eventlet and long blocking calls in separate threads or processes.

Replacing flask internal web server with Apache

I have written a single user application that currently works with Flask internal web server. It does not seem to be very robust and it crashes with all sorts of socket errors as soon as a page takes a long time to load and the user navigates elsewhere while waiting. So I thought to replace it with Apache.
The problem is, my current code is a single program that first launches about ten threads to do stuff, for example set up ssh tunnels to remote servers and zmq connections to communicate with a database located there. Finally it enters run() loop to start the internal server.
I followed all sorts of instructions and managed to get Apache service the initial page. However, everything goes wrong as I now don't have any worker threads available, nor any globally initialised classes, and none of my global variables holding interfaces to communicate with these threads do not exist.
Obviously I am not a web developer.
How badly "wrong" my current code is? Is there any way to make that work with Apache with a reasonable amount of work? Can I have Apache just replace the run() part and have a running application, with which Apache communicates? My current app in a very simplified form (without data processing threads) is something like this:
comm=None
app = Flask(__name__)
class CommsHandler(object):
__init__(self):
*Init communication links to external servers and databases*
def request_data(self, request):
*Use initialised links to request something*
return result
#app.route("/", methods=["GET"]):
def mainpage():
return render_template("main.html")
#app.route("/foo", methods=["GET"]):
def foo():
a=comm.request_data("xyzzy")
return render_template("foo.html", data=a)
comm = CommsHandler()
app.run()
Or have I done this completely wrong? Now when I remove app.run and just import app class to wsgi script, I do get a response from the main page as it does not need reference to global variable comm.
/foo does not work, as "comm" is an uninitialised variable. And I can see why, of course. I just never thought this would need to be exported to Apache or any other web server.
So the question is, can I launch this application somehow in a rc script at boot, set up its communication links and everyhing, and have Apache/wsgi just call function of the running application instead of launching a new one?
Hannu
This is the simple app with flask run on internal server:
from flask import Flask
app = Flask(__name__)
#app.route("/")
def hello():
return "Hello World!"
if __name__ == "__main__":
app.run()
To run it on apache server Check out fastCGI doc :
from flup.server.fcgi import WSGIServer
from yourapplication import app
if __name__ == '__main__':
WSGIServer(app).run()

Categories

Resources