Deploy simple server using Flask on AWS - python

I'm using this Python code to see if I can view the simple AWS server however, I'm still not able to load the webpage properly.
from flask import Flask
app = Flask(__name__)
#app.route('/')
def index():
return "It works!"
if __name__ == '__main__':
app.run(port=80, host='0.0.0.0')
In AWS, inbound:
HTTP TCP port 80 with a source of: 0.0.0.0/0
SSH TCP port 22 with a source of: 0.0.0.0/0
Outbound - everything is allowed.
I'm seeing no errors on terminal when I start the program. The console says Running on http://127.0.0.1:5000/ (Press CTRL+C to quit) so I'm trying to load http://ubuntu#ec2-IPADDRESS.compute-1.amazonaws.com:5000

Flask defaults to binding to 127.0.0.1:5000.
If you're trying to access http://ubuntu#ec2-IPADDRESS.compute-1.amazonaws.com:5000 , you'll need to have port 5000 opened in the inbound firewall rules and bind to 0.0.0.0 instead of 127.0.0.1.

You can not use port 80 for your web application. Let it run on default port then host your web application by mod_wsgi or uWSGI... Check the deployment options here: http://flask.pocoo.org/docs/0.12/deploying/ .
Imo: better if you deploy your application on AWS Elastic Beanstalk. Give me a shout if you need a sample project.

Related

Why isn't the Flask public server receiving requests?

I am trying to set up a server on a windows 10 machine, using Python and Flask, but it is not responding to external requests.
This is my server.py file:
from flask import Flask
app = Flask(__name__)
#app.route("/")
def index():
return "Hi there"
if __name__ == "__main__":
app.run(host="0.0.0.0", port=5000)
When running, it says:
* Running on all addresses (0.0.0.0)
WARNING: This is a development server. Do not use it in a production deployment.
* Running on http://127.0.0.1:5000
* Running on http://195.XX.XXX.XXX:5000 (Press CTRL+C to quit)
Indeed, if I try to access it from that machine, using 127.0.0.1:5000 or 195.XX.XXX.XXX:5000, it works correctly.
However, when trying to access it from another machine, (using Chrome if that can be an issue), it just loads indefinitely, then says no data received, ERR_EMPTY_RESPONSE.
What is wrong with this? I've followed steps on the documentation so I don't get what could be wrong.
I also disabled firewall entirely on the windows 10 machine.
How you're running matters. If it's via
python server.py
then the app.run() will execute, and the server will bind to 0.0.0.0
But if you're running via some variant of
FLASK_APP=server.py flask run
then app.run() won't execute, and the server will bind to 127.0.0.1
In that case, adding --host=0.0.0.0 should fix things (unless you're having a firewall issue).

Do WSGI servers connect to devices outside of the network? [duplicate]

I'm not sure if this is Flask specific, but when I run an app in dev mode (http://localhost:5000), I cannot access it from other machines on the network (with http://[dev-host-ip]:5000). With Rails in dev mode, for example, it works fine. I couldn't find any docs regarding the Flask dev server configuration. Any idea what should be configured to enable this?
While this is possible, you should not use the Flask dev server in production. The Flask dev server is not designed to be particularly secure, stable, or efficient. See the docs on deploying for correct solutions.
The --host option to flask run, or the host parameter to app.run(), controls what address the development server listens to. By default it runs on localhost, change it to flask run --host=0.0.0.0 (or app.run(host="0.0.0.0")) to run on all your machine's IP addresses.
0.0.0.0 is a special value that you can't use in the browser directly, you'll need to navigate to the actual IP address of the machine on the network. You may also need to adjust your firewall to allow external access to the port.
The Flask quickstart docs explain this in the "Externally Visible Server" section:
If you run the server you will notice that the server is only
accessible from your own computer, not from any other in the network.
This is the default because in debugging mode a user of the
application can execute arbitrary Python code on your computer.
If you have the debugger disabled or trust the users on your network,
you can make the server publicly available simply by adding
--host=0.0.0.0 to the command line:
$ flask run --host=0.0.0.0
This tells your operating system to listen on all public IPs.
If you use the flask executable to start your server, use flask run --host=0.0.0.0 to change the default from 127.0.0.1 and open it up to non-local connections.
If you run the server you will notice that the server is only
accessible from your own computer, not from any other in the network.
This is the default because in debugging mode a user of the
application can execute arbitrary Python code on your computer.
If you have the debugger disabled or trust the users on your network,
you can make the server publicly available simply by adding
--host=0.0.0.0 to the command line:
$ flask run --host=0.0.0.0
This tells your operating system to listen on all public IPs.
Reference: https://flask.palletsprojects.com/quickstart/
Try this if the 0.0.0.0 method doesn't work
Boring Stuff
I personally battled a lot to get my app accessible to other devices(laptops and mobile phones) through a local-server. I tried the 0.0.0.0 method, but no luck. Then I tried changing the port, but it just didn't work. So, after trying a bunch of different combinations, I arrived to this one, and it solved my problem of deploying my app on a local server.
Steps
Get the local IPv4 address of your computer.
This can be done by typing ipconfig on Windows and ifconfig on Linux
and Mac.
Please note: The above step is to be performed on the machine you are serving the app on, and on not the machine on which you are accessing it. Also note, that the IPv4 address might change if you disconnect and reconnect to the network.
Now, simply run the flask app with the acquired IPv4 address.
flask run -h 192.168.X.X
E.g. In my case (see the image), I ran it as:
flask run -h 192.168.1.100
On my mobile device
Optional Stuff
If you are performing this procedure on Windows and using Power Shell as the CLI, and you still aren't able to access the website, try a CTRL + C command in the shell that's running the app. Power Shell gets frozen up sometimes and it needs a pinch to revive. Doing this might even terminate the server, but it sometimes does the trick.
That's it. Give a thumbs up if you found this helpful.😉
Some more optional stuff
I have created a short Powershell script that will get you your IP address whenever you need one:
$env:getIp = ipconfig
if ($env:getIp -match '(IPv4[\sa-zA-Z.]+:\s[0-9.]+)') {
if ($matches[1] -match '([^a-z\s][\d]+[.\d]+)'){
$ipv4 = $matches[1]
}
}
echo $ipv4
Save it to a file with .ps1 extension (for PowerShell), and run it on before starting your app. You can save it in your project folder and run it as:
.\getIP.ps1; flask run -h $ipv4
Note: I saved the above shellcode in getIP.ps1.
Cool.👌
Add host='0.0.0.0' to app.run`.
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000)
If you get OSError: [WinError 10013] An attempt was made to access a socket in a way forbidden by its access permissions on Windows, you either don't have permission to use the port, or something else is using it which you can find with netstat -na|findstr 5000.
Check whether the particular port is open on the server to serve the client or not?
in Ubuntu or Linux distro
sudo ufw enable
sudo ufw allow 5000/tcp //allow the server to handle the request on port 5000
Configure the application to handle remote requests
app.run(host='0.0.0.0' , port=5000)
python3 app.py & #run application in background
If your cool app has it's configuration loaded from an external file, like in the following example, then don't forget to update the corresponding config file with HOST="0.0.0.0"
cool.app.run(
host=cool.app.config.get("HOST", "localhost"),
port=cool.app.config.get("PORT", 9000)
)
If you're having troubles accessing your Flask server, deployed using PyCharm, take the following into account:
PyCharm doesn't run your main .py file directly, so any code in if __name__ == '__main__': won't be executed, and any changes (like app.run(host='0.0.0.0', port=5000)) won't take effect.
Instead, you should configure the Flask server using Run Configurations, in particular, placing --host 0.0.0.0 --port 5000 into Additional options field.
More about configuring Flask server in PyCharm
You can also set the host (to expose it on a network facing IP address) and port via environment variables.
$ export FLASK_APP=app.py
$ export FLASK_ENV=development
$ export FLASK_RUN_PORT=8000
$ export FLASK_RUN_HOST=0.0.0.0
$ flask run
* Serving Flask app "app.py" (lazy loading)
* Environment: development
* Debug mode: on
* Running on https://0.0.0.0:8000/ (Press CTRL+C to quit)
* Restarting with stat
* Debugger is active!
* Debugger PIN: 329-665-000
See How to get all available Command Options to set environment variables?
Go to your project path on CMD(command Prompt) and execute the following command:-
set FLASK_APP=ABC.py
SET FLASK_ENV=development
flask run -h [yourIP] -p 8080
you will get following o/p on CMD:-
Serving Flask app "expirement.py" (lazy loading)
Environment: development
Debug mode: on
Restarting with stat
Debugger is active!
Debugger PIN: 199-519-700
Running on http://[yourIP]:8080/ (Press CTRL+C to quit)
Now you can access your flask app on another machine using http://[yourIP]:8080/ url
For me i followed the above answer and modified it a bit:
Just grab your ipv4 address using ipconfig on command prompt
Go to the file in which flask code is present
In main function write app.run(host= 'your ipv4 address')
Eg:
Create file .flaskenv in the project root directory.
The parameters in this file are typically:
FLASK_APP=app.py
FLASK_ENV=development
FLASK_RUN_HOST=[dev-host-ip]
FLASK_RUN_PORT=5000
If you have a virtual environment, activate it and do a pip install python-dotenv .
This package is going to use the .flaskenv file, and declarations inside it will be automatically imported across terminal sessions.
Then you can do flask run
This answer is not solely related with flask, but should be applicable for all cannot connect service from another host issue.
use netstat -ano | grep <port> to see if the address is 0.0.0.0 or ::. If it is 127.0.0.1 then it is only for the local requests.
use tcpdump to see if any packet is missing. If it shows obvious imbalance, check routing rules by iptables.
Today I run my flask app as usual, but I noticed it cannot connect from other server. Then I run netstat -ano | grep <port>, and the local address is :: or 0.0.0.0 (I tried both, and I know 127.0.0.1 only allows connection from the local host). Then I used telnet host port, the result is like connect to .... This is very odd. Then I thought I would better check it with tcpdump -i any port <port> -w w.pcap. And I noticed it is all like this:
Then by checking iptables --list OUTPUT section, I could see several rules:
these rules forbid output tcp vital packets in handshaking. By deleting them, the problem is gone.
I had the same problem, I use PyCharm as an editor and when I created the project, PyCharm created a Flask Server. What I did was create a server with Python in the following way;
basically what I did was create a new server but flask if not python
I hope it helps you
This finally worked for me.
import os
Then place this at the end of your python app.py or main file.
if __name__ == "__main__":
port = int(os.environ.get("PORT", 5000))
app.run(host='0.0.0.0', port=port)
go to project path
set FLASK_APP=ABC.py
SET FLASK_ENV=development
flask run -h [yourIP] -p 8080
you will following o/p on CMD:-
* Serving Flask app "expirement.py" (lazy loading)
* Environment: development
* Debug mode: on
* Restarting with stat
* Debugger is active!
* Debugger PIN: 199-519-700
* Running on http://[yourIP]:8080/ (Press CTRL+C to quit)
If none of the above solutions are working, try manually adding "http://" to the beginning of the url.
Chrome can distinguish "[ip-address]:5000" from a search query. But sometimes that works for a while, and then stops connecting, seemingly without me changing anything. My hypothesis is that the browser might sometimes automatically prepend https:// (which it shouldn't, but this fixed it in my case).
In case you need to test your app from an external network.
Simply serve it to the whole Internet with ngrok.com
which will deploy it like a dev server but in no time and locally, saved me a lot of time, and no, I'm not related to that company :)
Just make sure to change the port in your flask app:
app.run(host='0.0.0.0', port=80)

404 in python flask application on EC2

i'm kinda new to all this, so bare with me
I'm trying to deploy my flask app to EC2, and before getting to set a WSGI server, id like to try to connect to port 8080
the code can be found here: https://github.com/Klasyer/POBAP
I've set the flask app host to 0.0.0.0 and port to 8080
In EC2 i opened the inbound rule for 8080
When i try to open the app through the web (http://18.223.32.186:8080/) i get a 404.
What am i missing/doing wrong?
Thanks ahead for any help
Try attaching an elastic IP address to the instance that your running and once it is done you can access the flask app running in the instance. But you should include the port number always while accessing it.
If you need the app to be accessed without the use of port number then in your flask app change the port number to 443 which is for HTTPS and 80 for HTTP. If you need HTTPS the process is somewhat different because you need to make a purchase but for HTTP it's free. So go on with HTTP by using the port number as 80
app.run(host='0.0.0.0', port=80)

Flask application cannot be exposed on droplet

I'm deploying a flask server to a Digital Ocean droplet.
from flask import Flask
app = Flask(__name__)
#app.route("/a/<string:b>")
def deploy(b):
return "Response"
Using the following command:
FLASK_APP=server.py python -m flask run --host=0.0.0.0 --port=5555
When I deploy the application locally, I can receive response by doing
curl -XGET localhost:5555/a/random
When deploying on the droplet, it works internally, but when calling the droplet externally (despite having exposed port 5555 on TCP) it does not connect.
What could have changed? I'm also deploying a flask graphql server on the same droplet via docker which works perfectly fine.
This is possible a common issue when uses VPS.
People like me may often forget to setup firewall(s) if the codes are correct.
You mentioned that it works locally but not externally. I guess it should be.
Digital Ocean level:
Add inbound TCP port 5555 in droplet firewall setting
System level
iptables: e.g. iptables -A INPUT -p tcp -dport 5555 -j ACCEPT
firewalld: e.g. firewall-cmd --permanent --zone=public --add-port=5555/tcp
Or you may disable OS firewalls by systemctl stop [service-name] or service [service-name] stop. You may google the commands.
Flask accepts connections from localhost by default.
In order to make your Flask app publicly available, you have to bind it to 0.0.0.0 address by adding --host=0.0.0.0 parameter.
Externally Visible Server
If you run the server you will notice that
the server is only accessible from your own computer, not from any
other in the network. This is the default because in debugging mode a
user of the application can execute arbitrary Python code on your
computer.
If you have the debugger disabled or trust the users on your network,
you can make the server publicly available simply by adding
--host=0.0.0.0 to the command line:
flask run --host=0.0.0.0 This tells your operating system to listen on
all public IPs.

Python flask expose to external visible

With the help of the post Flask - configure dev server to be visible across the network, I have tried the same to make my Flask externally visible so that I can send HTTP requests from my local browser to the Flask in remote server.
Can someone please help on why its not working for me even I have opened the connections.
I started my flask in Putty [script in dev server] and tried accessing the URL from my Chrome as http://[my_sys_ip]:5000/. Chrome reports me OOPS error.
On Flask, I have made it externally visble with debug mode turned off:
if __name__ == '__main__':
app.run(host='0.0.0.0', debug = False)
From netstat, I can see its listening on 5000:
netstat -an | grep :5000
tcp 0 0 0.0.0.0:5000 0.0.0.0:* LISTEN
When tried to send a GET request from the same dev server, I'm successful with the expected response:
python testing.py
URL called is http://0.0.0.0:5000/
Message to the user is Hello World!!!!!!!
What am I missing ?
I know this is an old question, but I figured I'll throw my 2 cents in.
From your description, it sounds like you are launching your flask application on a remote server (dev server) through PuTTY. You are then trying to access the app on your local system (localhost). The application isn't running on your local system, so that would explain the error in chrome.
Instead of going to http://[my_sys_ip]:5000, you will need to go to http://[dev_svr_ip]:5000.

Categories

Resources