Changing the host IP address in Flask to access it from outside - python

My application is hosted in Azure VM. I have created a static IP and a Public IP for the VM. Here are my steps.
Created the VM
Open the port 5000 using the inbound port rule.
Created a port forwarding rule in my router that has original port
as 5000, the static IP of VM and the to port as 5000
Added my code and ran the program
Works with static IP
When I try to access it outside, it doesn't work. I have been on this for the whole day and still unable to figure out anything. Can you please guide here on how to access it outside of VM?
Below is my code:
from flask import Flask, render_template, redirect, url_for
from flask import request
app = Flask(__name__)
#app.route('/login', methods=['GET', 'POST'])
def login():
error = None
if request.method == 'POST':
if request.form['username'] != 'admin' or request.form['password'] != 'admin':
error = "Invalid Credentials. Please try again."
else:
return render_template('link.html')
return render_template('login.html',error = error)
if __name__ == '__main__':
app.run(host = 'static IP')

Related

FLASK: curl: (7) Failed to connect to 127.0.0.1 port 5500: Connection refused

I am trying to transition from making Rshiny apps to flask-react apps. Its definitely a steep learning curve so far!
I am sort of following a few tutorials e.g (https://dev.to/arnu515/build-a-fullstack-twitter-clone-using-flask-and-react-1j72) to try and get some basic functionality down .
However some reason curl can't seem to interact with my app. I've tried putting the urls with and without quotes but get the same response. Also I tried the default 5000 port as well. I am running the app in windows:
C:\Users\Marc\flaskTest\backend>curl "http://127.0.0.1:5500"
curl: (7) Failed to connect to 127.0.0.1 port 5500: Connection refused
app.py code
from flask import Flask
from flask_cors import CORS
app = Flask(__name__)
CORS(app)
#app.route('/')
def index():
return "hello"
#app.route('/message', methods=["GET"])
def message():
message ="my message"
return jsonify({"message": message})
if __name__ == "__main__":
app.run(debug=True, port=5500)
You used jsonify in the view function but haven't imported it before, so there would be error when Flask app runs.
Actually you can just write code like return {"message": message}, it would do the same thing with jsonify does if you are using latest version of flask.
Try:
if __name__ == '__main__':
app.run(host='0.0.0.0', debug=True, port=5500)
Also in windows cmd type ipconfig IPV4 address. Suppose your IPV4 address is 192.168.X.X, access the website as http://192.168.X.X:5500.
Read what it does: Externally Visible Server

Not Found page when waitress start

I get this error when I access the default page after starting the flask server using the waitress.
The code is:
from app import app
from waitress import serves
if __name__ == '__main__':
serves (app, host = "0.0.0.0", port = 8080)
I access the page http://localhost:8080 in the browser
erro:
Not Found
The requested URL was not found on the server. If you entered the URL manually please check your spelling and try again.
You need a url handler:
#app.route('/')
def index():
return "hello"

Am I able to have an IP White list range for Flask, and not a list of IP's?

I have a basic flask server I am using for Python development with a Google Chat Bot. I would like to limit the range of IP's that can access the server to any within a certain range. For the purposes of this, say 123.0.0.1 to 123.255.255.255.
I know how to easily do this for a single IP, from similar issues seen online.
from flask import abort, request
#app.before_request
def limit_remote_addr():
if request.remote_addr != '123.0.0.1':
abort(403) # Forbidden
But I don't want to do this for every IP, or have to make a list. Is that possible? Or am I better off configuring my firewall to remove this step?
As #Klaus D. mentioned you can check if the remote address starts with a portion of the address.
You can check if the remote address is listed in a specific list of IP addresses in #before_request decorator.
Here I am showing an example of white listing IP addresses in Python.
Used local network(connected via WiFi) to test it.
Local IP address for Flask server: 192.168.0.107
app.py:
from flask import abort, Flask, render_template, request
ALLOWED_IPS = ['192.168.1.', '127.0.0.1']
app = Flask(__name__)
#app.errorhandler(403)
def permission_error(e):
return render_template('403.html', error_code=403), 403
#app.before_request
def limit_remote_addr():
client_ip = str(request.remote_addr)
valid = False
for ip in ALLOWED_IPS:
if client_ip.startswith(ip) or client_ip == ip:
valid = True
break
if not valid:
abort(403)
#app.route('/', methods = ['GET'])
def home():
return "Your IP: {}".format(request.remote_addr)
if __name__ == '__main__':
app.run(host='0.0.0.0', debug=True)
403.html:
<h3>Your IP address is not white listed</h3>
Output:
Accessing the app from a IP which is not in ALLOWED_IPS list:
Accessing the app from a IP which is in ALLOWED_IPS list:
After updating the ALLOWED_IPS list to ALLOWED_IPS = ['192.168.0.', '127.0.0.1'], I can access the Flask app from 192.168.0.107:

Can't access Flask app running on 0.0.0.0 on GCE

I set Firewall Rule for my local google compute instance at host '0.0.0.0' and port 7000.
And I executed python server.py, it was running on https://0.0.0.0:7000
but when I enter https://external-ip:7000 on my local browser it did not work.
So how can I run flask on google compute engine and open in my local computer browser?
server.py
from flask import Flask
app = Flask(__name__)
#app.route('/')
def hello_world():
return 'Hello World’
if __name__ == '__main__':
app.run(debug=1,port=7000,host='0.0.0.0')
A few things:
Check your VPC firewall:
https://cloud.google.com/vpc/docs/firewalls
In your terminal, see if connections are working locally on that host by issuing:
telnet localhost 7000
If it connects then it's either firewall or the below.
If you're running on https, you'll probably need to have something along the lines of:
context = ('host.crt', 'host.key')
app.run(host='0.0.0.0',port='7000', ssl_context=context)
Lastly, it's https:// not \

Serve a Flask app on a sub-url during localhost development

I have a Flask app as backend that serves a REST API and an AngularJS front-end app.
I use Grunt/Livereload to serve the front-end at the address: http://localhost:5000/
Is it possible to serve the Flask app on a sub-url of localhost during development, using app.run() or run_simple from werkzeug?
Specifically I would like to have the Flask app accessible at the address: http://localhost:5000/api
I found this solution but it has the disadvantage of serving a dummy app at http://localhost:5000/ which uses the address and doesn't let me serve the AngularJS app at that address.
The way that Flask and Yoman are set up you cannot actually do this - it is possible to have two processes share the same port, but it is generally done to allow one master process to pass off handling of individual requests to sub-processes, which is not quite what you are doing here. (In general, in production, you would run both the front and back end behind a proxy server like nginx.)
Fortunately, you do not have to re-invent the wheel or run a separate proxy server just to develop your app - there is a Grunt plugin called grunt-connect-proxy that will let you proxy requests to a sub-url to another location entirely. That will let you spin up your Flask backend server on a different port (say port 5001) and proxy requests to localhost:5000/api (for example) to localhost:5001/:
connect: {
options: {
port: 5000,
hostname: 'localhost'
},
proxies: [
{
context: '/api',
host: '127.0.0.1',
port: 5001,
https: false,
changeOrigin: false,
xforward: false
}
]
}
And then you can run your Flask app with app.run(port=5001).
This worked for me
from flask import Flask
prefix = '/abc'
app = Flask(__name__)
# redefine route
def route(path, *args, **kwargs):
return _route(prefix + path, *args, **kwargs)
_route = app.route
app.route = route
# Test function
#app.route('/')
def hello_world():
return 'Hello World!'
if __name__ == '__main__':
app.run()

Categories

Resources