Flask request without port in url - python

I have an ubuntu EC2 server and want to run a flask server. I want to hit the server using my domain name, api.example.com, without having to include the port number. Right now, I can successfully access the server by doing api.example.com:5000/... but I can't figure out how to do api.example.com/....
Right now I'm just running the flask server directly, using python flask_server.py.
In flask_server.py:
if __name__ == '__main__':
app.run(host=0.0.0.0)

The run method takes a port optional argument:
if __name__ == '__main__':
app.run(host="0.0.0.0", port=80)
You can do this for testing, but for production I highly recommend you read the deployment options section in the documentation which details ways to run flask with various front end WSGI servers.
If you need help understanding how all these components work together and how to set them up; this gist has a nice summary.
Update: The host param needs to be a string.

You need sudo privilege in order to use port 80.
sudo python3 app.py
That will solve the problem.

Correct syntax to use Flask server on port 80 is:
if __name__ == '__main__':
app.run(host='0.0.0.0', port=80)
Keep in mind that you might need super user privileges.
This kind of workaround wound be acceptable if your were still building your application.
If, as I understood, you plan to deploy your app in production then you'd need to do it properly.
Here you find step by step information for Ubuntu, as requested:
https://www.digitalocean.com/community/tutorials/how-to-deploy-a-flask-application-on-an-ubuntu-vps

Related

Running a Python script that creates a webpage on a server

I have a Python script that creates a web page displaying some text at localhost port 8080. I have access to a server, and would the script to run there so that it is always running and available anywhere.
I am using the bottle, requests and json libraries.
This is the last line of code in the script that is executed to locally create a web page:
run(host='localhost', port=8080, debug=True)
How would I change this to run on a server? I also have WinSCP and PuTTy to add the script to the public_html directory of the server and I can change permissions. Sorry, I am a novice in this subject.
Thanks for any help!
That depends on the Apache httpd configuration. But, assuming most defaults were left in place and Apache httpd serves index.html, you can just create your webpage (which you tested locally on port 8080) and overwrite that file. But, this only works well if you have a static page and no logic in your Python code. If you want to combine the power of Apache httpd and Python (have the former call the latter) you'll have to use mod_wsgi.
Seeing as you're novice in this subject, I suggest starting off with a simple Apache httpd server according to their quickstart. Then, once you have a few successful requsets under your belt, add mod_wsgi.

ipv4 networking not enabled when runnig docker

I have a remote machine at my workplace, when we developers run server/ or docker containers. everything was working fine but a while back somethign went wrong.
if I run the python flask app
from app import app
app.run(host='0.0.0.0', port=5050)
i get message
* Running on http://0.0.0.0:5050/
and I am able to access the above from my local machine using the remote server machine ip:5050 but if I run docker container docker run -itd <conta_image_name> -p 80:90 --add-host=localdomain.com:machine_ip_address i get error message saying IPv4 forwarding is disabled. Networking will not work.
Now this issue is in production so I really need someone to throw up some light, what might be wrong or let me know what more info I need to put.
I have fixed this issue myself following this: https://success.docker.com/article/ipv4-forwarding
Another solution is..
Try adding -net=host along with docker run command
https://medium.com/#gchandra/docker-ipv4-forwarding-is-disabled-8499ce59231e

Heroku Deployment - Not found: '/'

I am brand new to Heroku deployments and am attempting to launch a Python 2.7 app using the service. I followed their deployment guide step by step, but every time I run "heroku open" I am given a 404 error due to " Not found: '/' ".
I believe that the error lies in the IP address, when I run the local server it currently listens on the default http://0.0.0.0:8080 address. My run code, from main:
# Expose WSGI app (so gunicorn can find it)
application = bottle.default_app()
if __name__ == '__main__':
bottle.run(application, host=os.getenv('IP', '0.0.0.0'),
port=os.getenv('PORT', '8080'))
I have ensured that my app accounts for heroku's dynamic porting, does anyone have any other ideas what is wrong?
Thank you, please let me know if I can provide any further information.

Communicating with python program running on server

I'm trying to create a control system that will run on a Raspberry PI configured as a server. I'll have a python program running on the server that will control a process (i.e. temperature).
My question is how would I go about communicating the the running python program via a web browser? I'd like to be able to set a control point and get back the current process value.
I'm new to web development and have been looking at PHP and CGI, but that doesn't feel right to me. Someone also suggested communicating via SQL, where a script and the python program would both have access, but this doesn't feel right either?
What is the preferred method for doing this?
Thanks
The easiest thing would be install Flask:
from flask import Flask
app = Flask(__name__)
#app.route("/")
def main():
return "Hey cool, it works!"
if __name__ == "__main__":
app.run("0.0.0.0", port=80, debug=True) # Might have to run as sudo for port 80

Slow Requests on Local Flask Server

Just starting to play around with Flask on a local server and I'm noticing the request/response times are way slower than I feel they should be.
Just a simple server like the following takes close to 5 seconds to respond.
from flask import Flask
app = Flask(__name__)
#app.route("/")
def index():
return "index"
if __name__ == "__main__":
app.run()
Any ideas? Or is this just how the local server is?
Ok I figured it out. It appears to be an issue with Werkzeug and os's that support ipv6.
From the Werkzeug site http://werkzeug.pocoo.org/docs/serving/:
On operating systems that support ipv6 and have it configured such as modern Linux systems, OS X 10.4 or higher as well as Windows Vista some browsers can be painfully slow if accessing your local server. The reason for this is that sometimes “localhost” is configured to be available on both ipv4 and ipv6 socktes and some browsers will try to access ipv6 first and then ivp4.
So the fix is to disable ipv6 from the localhost by commenting out the following line from my hosts file:
::1 localhost
Once I do this the latency problems go away.
I'm really digging Flask and I'm glad that it's not a problem with the framework. I knew it couldn't be.
Add "threaded=True" as an argument to app.run(), as suggested here:
http://arusahni.net/blog/2013/10/flask-multithreading.html
For example: app.run(host="0.0.0.0", port=8080, threaded=True)
The ipv6-disabling solution did not work for me, but this did.
Instead of calling http://localhost:port/endpoint call http://127.0.0.1:port/endpoint.
This removed the initial 500ms delay for me.
The solution from #sajid-siddiqi is technically correct, but keep in mind that the built-in WSGI server in Werkzeug (which is packaged into Flask and what it uses for app.run()) is only single-threaded.
Install a WSGI server to be able to handle multi-threaded behavior. I did a bunch of research on various WSGI server performances. Your needs may vary, but if all you're using is Flask, then I would recommend one of the following webservers.
Update (2020-07-25): It looks like gevent started supporting python3 5 years ago, shortly after I commented that it didn't, so you can use gevent now.
gevent
You can install gevent through pip with the command pip install gevent or pip3 with the command pip3 install gevent. Instructions on how to modify your code accordingly are here: https://flask.palletsprojects.com/en/1.1.x/deploying/wsgi-standalone/#gevent
meinheld
gevent is better, but from all the benchmarks I've looked at that involve real-world testing, meinheld seems to be the most straightforward, simplistic WSGI server. (You could also take a look at uWSGI if you don't mind some more configuration.)
You can also install meinheld through pip3 with the command pip3 install meinheld. From there, look at the sample provided in the meinheld source to integrate Flask: https://github.com/mopemope/meinheld/blob/master/example/flask_sample.py
*NOTE: From my use of PyCharm, the line from meinheld import server highlights as an error, but the server will run, so you can ignore the error.
My problem was solved by "threaded=True", but I want to give some background to distinguish my problem from others for which this may not do it.
My issue only arose when running Flask with python3. Switching to python2, I no longer had this issue.
My problem manifested only when accessing the api with Chrome, at which point, Chrome displayed the expected screen, but everything else hung (curl, ffx, etc) until I either reloaded or closed the Chrome tab, at which point everything else that was waiting around returned a result.
My best guess is that Chrome was trying to keep the session open and Flask was blocking the subsequent requests. As soon as the connection from Chrome was stopped or reset, everything else was processed.
In my case, threading fixed it. Of course, I'm now going through some of the links others have provided to make sure that it's not going to cause any other issues.
threaded=True works for me, but finally I figured out that the issue is due to foxyproxy on firefox. Since when the flask app is running on localhost, slow response happens if
foxyproxy is enabled on firefox
slow response won't happen if
foxyproxy is disabled on firefox
access the website using other browsers
The only solution I found is to disable foxyproxy, tried to add localhost to proxy blacklist and tweak settings but none of them worked.
I used Miheko's response to solve my issue.
::1 localhost was already commented out on my hosts file, and setting Threaded=true didn't work for me. Every REST request was taking 1 second to process instead of being instant.
I'm using python 3.6, and I got flask to be fast and responsive to REST requests by making flask use gevent as its WSGI.
To use gevent, install it with pip install gevent
Afterwards, I used the https://gist.github.com/viksit/b6733fe1afdf5bb84a40#file-async_flask-py-L41 to set flask to use gevent.
Incase the link goes down, here's the important parts of the script:
from flask import Flask, Response
from gevent.pywsgi import WSGIServer
from gevent import monkey
# need to patch sockets to make requests async
# you may also need to call this before importing other packages that setup ssl
monkey.patch_all()
app = Flask(__name__)
# define some REST endpoints...
def main():
# use gevent WSGI server instead of the Flask
# instead of 5000, you can define whatever port you want.
http = WSGIServer(('', 5000), app.wsgi_app)
# Serve your application
http.serve_forever()
if __name__ == '__main__':
main()
I got this error when running on hosts other than localhost as well, so for some, different underlying problems may exhibit the same symptoms.
I switched most of the things I've been using to Tornado, and anecdotally it's helped an amount. I've had a few slow page loads, but things seem generally more responsive. Also, very anecdotal, but I seem to notice that Flask alone will slow down over time, but Flask + Tornado less so. I imagine using Apache and mod_wsgi would make things even better, but Tornado's really simple to set up (see http://flask.pocoo.org/docs/deploying/others/).
(Also, a related question: Flask app occasionally hanging)
I had a different solution here. I just deleted all .pyc from the server's directory and started it again.
By the way, localhost was already commented out in my hosts file (Windows 8).
The server was freezing the whole time and now it works fine again.
I run Python 3.8.10 which works fine, but as soon as I switch to Python 3.10.6 responses will be awful slow.
I could get around this problem with changing the precedence to IPv4 in /etc/gai.conf

Categories

Resources