Using requests module in flask route function - python

Consider the following minimal working flask app:
from flask import Flask
app = Flask(__name__)
#app.route("/")
def hello():
return "I am /"
#app.route("/api")
def api():
return "I am /api"
if __name__ == "__main__":
app.run()
This happily works. But when I try to make a GET request with the "requests" module from the hello route to the api route - I never get a response in the browser when trying to access http://127.0.0.1:5000/
from flask import Flask
import requests
app = Flask(__name__)
#app.route("/")
def hello():
r = requests.get("http://127.0.0.1:5000/api")
return "I am /" # This never happens :(
#app.route("/api")
def api():
return "I am /api"
if __name__ == "__main__":
app.run()
So my questions are: Why does this happen and how can I fix this?

You are running your WSGI app with the Flask test server, which by default uses a single thread to handle requests. So when your one request thread tries to call back into the same server, it is still busy trying to handle that one request.
You'll need to enable threading:
if __name__ == "__main__":
app.run(threaded=True)
or use a more advanced WSGI server; see Deployment Options.

Related

What is the best way for a Python script to communicate with a Python Flask server that transports content to the client?

The following scenario:
I have a Raspberry Pi running as a server. Currently I am using a Python script with Flask and I can also access the Raspberry Pi from my PC. (The flask server runs an react app.)
But the function should be extended. It should look like the following:
2nd Python script is running all the time. This Python script fetches data from an external API every second and processes it. If certain conditions are met, the data should be processed and then the data should be communicated to the Python Flask server. And the Flask server then forwards the data to the website running on the computer.
How or which method is best to program this "interprocess communication". Are there any libraries? I tried Celery, but then it throws up my second Python script whenever I want to access the external API, so I don't know if this is the right choice.
What else would be the best approach? Threading? Direct interprocess communication?
If important, this is how my server application looks so far:
from gevent import monkey
from flask import Flask, render_template
from flask_socketio import SocketIO
monkey.patch_all()
app = Flask(__name__, template_folder='./build', static_folder='./build/static')
socket_io = SocketIO(app)
#app.route('/')
def main():
return render_template('index.html')
#socket_io.on('fromFrontend')
def handleInput(input):
print('Input from Frontend: ' + input)
send_time()
#socket_io.on('time')
def send_time():
socket_io.emit('time', {'returnTime': "some time"})
if __name__ == '__main__':
socket_io.run(app, host='0.0.0.0', port=5000, debug=True)
Well i found a solution for my specific problem i implemented it with a thread as follows:
import gevent.monkey
gevent.monkey.patch_all()
from flask import Flask, render_template
from flask_socketio import SocketIO
import time
import requests
from threading import Thread
app = Flask(__name__, template_folder='./build', static_folder='./build/static')
socket_io = SocketIO(app)
#app.route('/')
def main():
thread = Thread(target=backgroundTask)
thread.daemon = True
thread.start()
return render_template('index.html')
#socket_io.on('fromFrontend')
def handleInput(input):
print('Input from Frontend: ' + input)
#socket_io.on('time')
def send_time():
socket_io.emit('time', {'returnTime': 'hi frontend'})
def backgroundTask():
# do something here
# access socket to push some data
socket_io.emit('time', {'returnTime': "some time"})
if __name__ == '__main__':
socket_io.run(app, host='0.0.0.0', port=5000, debug=True)

waitress command line returning "Malformed Application" when deploying flask web app

I'm attempting to deploy a simple web app, and I'm using command line waitress-serve --call command. But every time, the command immediately returns 1. Malformed application 'name_of_project_here'.
Here's my flask web app in python:
from flask import Flask, render_template
app = Flask(__name__)
#app.route('/')
def index():
return render_template('base.html')
if __name__ == '__main__':
app.run(debug = True)
and the command I run is just
waitress-serve --call "name_of_project"
I did try looking through the documentation, and I found where the error occurs, but couldn't find an explanation of why it's occurring. What does malformed application mean?
Minimal working example:
If you put code in file main.py
from flask import Flask
def create_app():
app = Flask(__name__)
#app.route('/')
def index():
return "Hello World!"
return app
if __name__ == '__main__':
app = create_app()
app.run()
then you can run it as
waitress-serve --call "main:create_app"
So "name_of_project" has to be "filename:function_name" which creates Flask() instance.
It can't be any text. And if you forget : then you may see "Malformed application"
when defining your appname and the function that initialize your app with : dont put them into quotes('')

How to host publicly visible flask server on windows

I am trying to host a flask server from my windows computer so I can access it from external devices
I am using Flask/Python and have already tried a few things but can't get it to work
Tried running it on 0.0.0.0, port 33, 5000, etc. but I still can't access it this way
from flask import Flask, request, abort
app = Flask(__name__)
if __name__ == '__main__':
app.run(host='0.0.0.0', port=33)
When I then run the file I get:
Running on http://0.0.0.0:33/ (Press CTRL+C to quit)
But it isn't even running there, nor on any other way I can access it
I expect to be able to access my flask application and send requests to it by using my public IP address
What can I do here to make it work?
You have missed an important line in your code:
After the line
app = Flask(__name__)
You have to write the line:
#app.route('/')
We use the route() decorator to tell Flask what URL should trigger our function.
And then define a function that will tell what task to be performed in the web app hosted in the respective address.
The function might look something like this:
def hello_world():
return 'Hello, World!'
The complete code then will look like:
from flask import Flask
app = Flask(__name__)
#app.route('/')
def hello_world():
return 'Hello, World!'
if __name__ == '__main__':
app.run(host='0.0.0.0', port=33)
Hope this helps.

Flask hangs the main thread

I want to use the Flask as my RESTful API server, but the main thread hangs and it doesn't execute the code after the app.run().
In util/restAPI.py
from flask import Flask
app = Flask('__name__')
#app.route('/')
def index():
return "Hello, World!"
In main.py
from util import restAPI
if __name__ == "__main__":
restAPI.app.run()
print "haha"
Should I use threads or something else to help me?

Flask dynamic route not working - Real Python

I'm working through RealPython and I'm having trouble with the flask dynamic route.
Everything seemed to work until the dynamic route. Now if I try to enter a "search query" (i.e. localhost:5000/test/hi) the page is not found. localhost:5000 still works fine.
# ---- Flask Hello World ---- #
# import the Flask class from the flask module
from flask import Flask
# create the application object
app = Flask(__name__)
# use decorators to link the function to a url
#app.route("/")
#app.route("/hello")
# define the view using a function, which returns a string
def hello_world():
return "Hello, World!"
# start the development server using the run() method
if __name__ == "__main__":
app.run()
# dynamic route
#app.route("/test/<search_query>")
def search(search_query):
return search_query
I can't see that other people using RealPython have had an issue with the same code, so I'm not sure what I'm doing wrong.
The reason why this is not working is because flask never learns that you have another route other / and /hello because your program gets stuck on app.run().
If you wanted to add this, all you need to do would be to add the new route before calling app.run() like so:
# ---- Flask Hello World ---- #
# import the Flask class from the flask module
from flask import Flask
# create the application object
app = Flask(__name__)
# use decorators to link the function to a url
#app.route("/")
#app.route("/hello")
# define the view using a function, which returns a string
def hello_world():
return "Hello, World!"
# dynamic route
#app.route("/test/<search_query>")
def search(search_query):
return search_query
# start the development server using the run() method
if __name__ == "__main__":
app.run(host="0.0.0.0", debug=True, port=5000)
Now this will work.
Note: You don't need to change the run configurations inside of app.run. You can just use app.run() without any arguments and your app will run fine on your local machine.
Try using the entire URL instead of just the IP address.

Categories