running multiple multi-route Flask applications - python

I have a flask app script that has multiple routes...
#app.py
def create_app(Tractor_id=0):
#app.route("/")
def index():
return render_template('index.html')
#app.route("/id")
def start():
return Tractor_id
#app.route("/stop")
def stop():
I'm trying to implement it multiple times with different parameters each time with the help of DispatcherMiddleware but I'm having trouble with it.
Here's the actual implementation:
# multiapp.py
from werkzeug.middleware.dispatcher import DispatcherMiddleware
from werkzeug.serving import run_simple
import start
T1 = start.create_app(Tractor_id='101')
T2 = start.create_app(Tractor_id='102')
# merge
application = DispatcherMiddleware(
None, {
'/{}'.format('T101'): T1,
'/{}'.format('T102'): T2
}
)
if __name__ == '__main__':
run_simple(
hostname='localhost',
port=5000,
application=application,
use_reloader=True,
use_debugger=True,
use_evalex=True)
In the index.html there are buttons that should redirect the user to the /id and /stop routes, but the do not work.
The general question would be, how to run multiple Flask applications which each have multiple routes within them?

I dont know DispatcherMiddleware.
But if you are trying to bind few flask servers, just pick for every process another port and it will work.
When you request them of course pay attention to port.
If you are struggling with actually making a multi route server, heres a good example.

Related

flask auto variable update issue

I've just joined this platform, i am amateur at python, i tried to do something at python, i want to design a basic website with python flask module, i want to get data from other py files but when i run the main program data comes just once, i want to get data frequently like each 1 seconds etc. i want to get "c" value (at from plc.py) each second. like auto update from other py file.
my main program is;
from multiprocessing import Process,Queue,Pipe
from flask import Flask, jsonify, render_template, request
from flask_apscheduler import APScheduler
import webbrowser
import time
from plc import c
app = Flask(__name__)
scheduler = APScheduler()
#app.route('/_stuff', methods = ['GET'])
def stuff():
return jsonify(result=c[3]) # c[3] yerine time.asctime() yazınca değişken veri geliyor
def scheduledTask():
print(c)
return (c)
#app.route('/')
def index():
return render_template('dy1.html')
if __name__ == '__main__':
scheduler.add_job(id='Scheduled task', func=scheduledTask, trigger='interval', seconds=5)
scheduler.start()
app.run(debug=True, use_reloader=True)

Flask: Storing Socket-Connection variables without Cookies

I need to have 'variables and activity associated with each client' without using cookies. How and where can i store this variables? I am pretty new to flask and servers.
For now, I thought of using a python dictionary and storing sessionID-variable pairs like shown below.
I have a feeling that this is a stupid idea, but I can not think of an alternative :/.
Hope, you can help me.
import flask
app = Flask(__name__)
app.secret_key = b'_5#y2L"F4Q8z\n\xec]/'
enter code heresocketio = SocketIO(app)
cache = {}
#app.route('/')
def index():
return send_from_directory('static', "index.html")
#socketio.on('savePseudonym')
def sendKeepAlive():
cache[(request.sid,'pseudonym')]= pseudonym
cache[(request.sid,'time')]= time
if __name__ == "__main__":
socketio.run(app, debug=True)
You can use session, in more or less the same way you use it with Flask routes.
from flask import session
#socketio.on('savePseudonym')
def sendKeepAlive():
session['pseudonym'] = pseudonym
session['time'] = time
The only thing to keep in mind is that because Socket.IO sessions are not based on cookies, any changes you make to the session in a Socket.IO handler will not appear on the Flask session cookie. If you need to share the session between Flask routes and Socket.IO event handlers, then you can use a server-side session with the Flask-Session extension.

python flask return prior execution of reboot

for reasons I want to trigger the reboot of an raspberry pi using a REST api.
My REST api is coded in python flask like this:
from flask import Flask
from flask import jsonify
import subprocess
app = Flask(__name__)
#app.route('/api/reboot')
def reboot():
subprocess.call("/sbin/reboot")
return jsonify(triggered='reboot')
if __name__ == '__main__':
app.run(debug=True,host="0.0.0.0")
the code is working perfectly fine. But due to its a reboot the return will not be send (because the system is rebooting obviously).
Is there a way to trigger the reboot some kind of async with a delay of a couple milliseconds, that allows to return some value (in my case just an custom 'ack') prior the actual reboot?
Try threading.Timer:
For example:
from flask import Flask
from flask import jsonify
import subprocess
import threading
app = Flask(__name__)
def _reboot():
subprocess.call("/sbin/reboot")
#app.route('/api/reboot')
def reboot():
t = threading.Timer(1, _reboot)
t.start()
return jsonify(triggered='reboot')
if __name__ == '__main__':
app.run(debug=True,host="0.0.0.0")

Run Flask as threaded on IIS 7

I am running a flask app using celery to offload long running process on a IIS 6.5 server and using python 2.7
The choice of the python 2.7, flask and IIS 7 server are imposed by the Company and cannot be changed.
The flask app works on IIS server (so the server set-up should be correct), except for the following.
I am struggling to find the good implementation to make flask works smoothly on the server.
I searched for similar questions on the site, but none helped so far.
When I am running the flask app on my pc, the application only performs as expected if I use OPTION A or OPTION B.
OPTION A:
from flask import Flask
app = Flask(__name__)
#app.route("/")
def hello():
return "Hello from FastCGI via IIS!"
if __name__ == "__main__":
app.run(threaded=True) # <--- This works
OPTION B:
If I wrap the flask app inside tornado, it works well as well:
from tornado.wsgi import WSGIContainer
from tornado.httpserver import HTTPServer
from tornado.ioloop import IOLoop
from myapp import app
http_server = HTTPServer(WSGIContainer(app))
http_server.listen(5000)
IOLoop.instance().start()
OPTION C:
However if I run the flask app only with the default parameters, then it does not work the webserver is not returning the view that should be returned after a task has been offloaded to celery.
from flask import Flask
app = Flask(__name__)
#app.route("/")
def hello():
return "Hello from FastCGI via IIS!"
if __name__ == "__main__":
app.run() # <--- Default App
Example of view working for OPTION A & B but not for OPTION C or on ISS:
Here below a stripped down example of a async task that is picked by celery. Note that I'm using Flask-Classy to generate the views, so the code is slightly different than the traditional routing in Flask.
class AnalysisView(FlaskView):
### Index page ---------------
def index(self):
return render_template('analysis.intro.html')
### Calculation process ------
def calculate(self, run_id):
t_id = task_create_id(run_id)
current_analysis = a_celery_function.apply_async(args=[x, y], task_id=t_id)
# Redirect to another view --> Not working when OPTION C or on ISS server
return redirect(url_for('AnalysisView:inprogress', run_id=run_id))
### Waiting page ---------------
def inprogress(self, run_id=run_id):
return render_template('analysis.inprogress.html')
My main problem is how can I use OPTION A (preferably, as it involves less change for me) or OPTION B to work together with IIS server?
Is there a way to tell flask to run with threaded=True during the Flask() initialization or via config settings?
Thanks in advance for you help.

Requests not able call multiple routes in same Flask application

I am not able to successfully use Python Requests to call a second route in the same application using Flask. I know that its best practice to call the function directly, but I need it to call using the URL using requests. For example:
from flask import Flask
import requests
app = Flask(__name__)
#app.route("/")
def hello():
return "Hello World!" # This works
#app.route("/myrequest")
def myrequest():
#r = requests.get('http://www.stackoverflow.com', timeout=5).text # This works, but is external
#r = hello() # This works, but need requests to work
r = requests.get('http://127.0.0.1:5000/', timeout=5).text # This does NOT work - requests.exceptions.Timeout
return r
if __name__ == "__main__":
app.run(debug=True, port=5000)
Your code assumes that your app can handle multiple requests at once: the initial request, plus the request that is generated while the initial is being handled.
If you are running the development server like app.run(), it runs in a single thread by default; therefore, it can only handle one request at a time.
Use app.run(threaded=True) to enable multiple threads in the development server.
As of Flask 1.0 the development server is threaded by default.

Categories

Resources