I am able to run a webserver using the following code
from flask import Flask
from waitress import serve
app = Flask(__name__, static_url_path='/static')
...
serve(app, port=8080)
The problem is that I can access it only from the machine where it is running, if I try to access it using the ipv4 ip, it doesn't work. Am I missing a step?
Simple example,try it!
I hope it will help you.
app1.py
from flask import Flask
app = Flask(__name__)
# app.run(host='0.0.0.0', port=8080,debug=True)
waitress_server.py
from waitress import serve
import app1
serve(app1.app, host='0.0.0.0', port=8080)
Then run below command
python waitress_server.py
Waitress now provides a simple command line Utility called waitress-serve for running the Flask Application. Please note that this answer is valid for Waitress 1.30. The command line arguments could change in future.
If your Flask application is called myapplication and the method which instantiates your application is called create_app, then you can run the command below. This will launch the server listening on port 8080 by default.
waitress-serve --call "myapplication:create_app"
If you wish to launch it on port 80 (http), then all you need to do is:
waitress-serve --port=80 --call "myapplication:create_app"
D:\flaskapps>waitress-serve --port 80 --call "dlrlsummarizer:create_app"
Serving on http://ADITHYA-PC:80
Waitress serve command line arguments.
Flask 1.0 production deployment tutorial.
Try using
serve(app, host='0.0.0.0', port=8080)
I ran into this question and looking something similar.
After looking at the documentation and combined with your original request, I tested
serve(app, port=8080, host="x.x.x.x")
Where x.x.x.x is my host ip address.
It works fine on my end.
Complete code
from flask import Flask
from waitress import serve
app = Flask(__name__)
...
serve(app, port=8080, host="x.x.x.x")
I realize this question was probably based in a miss-diagnosed firewall or NAT issue, but in case people come here actually wanting to serve a Flask app with waitress on windows properly (as a service), I want to point to my answer here, so that it can be of use and receive some feedback.
from flask import Flask
from waitress import serve
app = Flask(__name__)
#app.route("/")
def hello_world():
return "<p>Hello stay healthy.</p>"
if __name__ == "__main__":
serve(app, host="127.0.0.1", port=8080)
Problem may persist in host. You can use host="127.0.0.1" in your program.
Save your program in app.py file.
Run your program.
The server will be accessible at http://localhost:8080
I just realized that can be reached by computers in the same network, but not from computers outside of the network
You need to forward the port in your router and use your public IP address.
To be able to use your internal PC (behind the router) you need to forward in the router the externl port 8080 to internal port 8080 and IP address of your server.
In this conditions you can access your server from outside your network using your external IP. That is OK if you have a static IP address allocated by your provider. If not than you can use a free DNS provider (I use DnsExit) which will provide you with a name for your external IP address. This way you can access your server with a name even if the IP address from your service provider changes from time to time.
Related
I work on a linux cluster that is behind a firewall. It does not have web access.
I had this idea I could try to run flask and direct it to a port I know is open (5901 for vnc), and then tunnel that port and view it in my browser.
It's not working so far. Is this possible at all?
Here is what I'm doing:
helloflask.py
from flask import Flask
app = Flask(__name__)
#app.route("/")
def hello():
return "Hello World!"
if __name__ == "__main__":
app.run(host='0.0.0.0', port=5901)
#app.run()
I run python helloflask.py then
ssh -L 5901:<inner server>:5901 <outer server>
Then I navigate to localhost:5901. Nothing. I also tried links localhost:5901 and links <server>:5901, but again nothing.
Is it possible there is some way to do this?
You can do this :
Run your flask app or notebook on the remote server on any port. Say for example port 5000.
On your local machine run below command to establish the ssh tunnelling :
ssh -D 8123 -f -C -q -N username#remotesrrver
The port 8123 is arbitrary here it can be any allowed port on your local machine. Then setup one of your browser (Fire fox may be) to use socks proxy on port 8123
Make sure that the traffic is proxied for localhost also. By default Firefox disable proxying for localhost. Once these are established you should be able to go to http://localhost:5000 on your browser to hit the app /notebook running on the remote machine
And your hellowflask.py should be like something below for it to work
from flask import Flask
app = Flask(__name__)
#app.route("/")
def hello():
return "Hello World!"
if __name__ == "__main__":
app.run(host='0.0.0.0', port=5901)
#app.run()
Might I suggest trying something like pyngrok to programmatically manage an ngrok tunnel for you? Full disclosure, I am the developer of it. Flask example here, but it's as easy as installing pyngrok:
pip install pyngrok
and using it:
from pyngrok import ngrok
# <NgrokTunnel: "http://<public_sub>.ngrok.io" -> "http://localhost:5000">
http_url = ngrok.connect(5000)
I'm running Ubuntu using Virtual Box Manager from windows machine. Inside the VM box ubuntu i'm running a python flask application which is running at http://localhost:5000.
I tried to access the VM box localhost URL on windows machine using the VM box IP which I got using ifconfig. But it's says :
Your Internet access is blocked
Am i accessing it the right way ?
here is my python flask code :
from flask import Flask
app = Flask(__name__)
#app.route("/")
def hello():
return "Hello World!"
if __name__ == "__main__":
app.run()
You need to specify a host='0.0.0.0' while starting your app. By default it will only accept requests from localhost. So if you are sending a request from some other IP then you must have to specify a host.
See below example.
from flask import Flask
app = Flask(__name__)
#app.route("/")
def hello():
return "Hello World!"
if __name__ == "__main__":
app.run(host='0.0.0.0')
Also if you want to activate the debugging mode to analyse the exceptions/errors while you access your application. You can also set debug attribute to 'True'.
if __name__ == "__main__":
app.run(host='0.0.0.0', debug=True)
Below code will allow you to access Flask web from any public IP instead of 127.0.0.1
if __name__ == '__main__':
app.run(host='0.0.0.0', debug='TRUE')
By default Flask runs on port: 5000. Sometime on VM this port will be blocked. To allow traffic on this port execute below command.
iptables -I INPUT -p tcp --dport 5000 -j ACCEPT
My use case:
We need to run a watir-webdriver script in headless mode and our dev machines run Windows.
The gist of our problem:
I can stand up the python server inside the container, but I can't connect to it at its expected location from the host: http://192.168.59.103:8084.
The architecture:
A ruby script that "does something useful and prints the output to the console" and a basic python server that imports os and then executes os.system('ruby ourrubyscript.rb') inside our index route. We also brought in flask for api routing and flask.cors to eliminate potential cross origin issues.
Local test (on Host):
running "python server.py" in our host workspace stands up a python server on port 5000. Routing to it from a browser executes our route and prints the expected output to the console.
server.py
from flask import Flask
from flask import request
from flask.ext.cors import CORS
import os
app = Flask(__name__)
CORS(app, resources={r'/': {"origins": "*"}}, headers='Content-Type')
app.config['CORS_HEADERS'] = 'Content-Type'
#app.route('/')
def index():
return "<h1>Hello Stupid</h1>"
#app.route('/ruby/test', methods=['GET'])
def runRubyScript():
return os.system("ruby script.rb")
if __name__ == "__main__":
app.run()
When I nav to localhost:5000, "Hello Stupid" prints to my screen.
When I route to localhost:5000/ruby/test, our script runs and that script prints to my console.
Procedure to move this to docker
We pulled latest centos and installed wget, xvfb, git, ruby, python, pip, flask, flask-cors, and firefox; committed that to a local image named "webdev."
Then gem installed headless and installed phantomjs to $PATH
We then cloned our src repository to "/opt/testapp" in the container. This repository contains our "server.py" file and a "script.rb" file.
docker#boot2docker:~$ docker run -d -p 5000:5000 --name wd webdev python /opt/testapp/server.py
So, I left my boot2docker-vm bound to private ip 192.168.59.103, and I can confirm that this ip is valid by navigating to a different port that is running a different container; however, when I navigate to 5000, I get an ERR_CONNECTION_REFUSED. I had an almost "AHA!!" moment thinking that iptables had the port locked down by default and we needed to go open internal port 5000 in order to map it out to the vm but then I found that the centos image does not have iptables (or firewalld since this is CentOS7) installed by default. When that approach turned out to be incorrect, I decided to post to see if anyone might be able to assist here because I am out of ideas.
So I have figured out why this is not exposed to the host environment and this makes perfect sense.
In NAT mode, the virtual machine gets assigned a private static ip address: 192.168.59.103 (that is...the virtual machine gets assigned that IP)
Each container stands up with 2 adapters: a loopback and an externally facing virtual private bridge accessible to the vm.
When I stand up my server on port 5000, it binds directly to loopback inside the container and is inaccessible to the virtual machine.
Removing the localhost binding from the service and allowing it to
bind to the default gateway 0.0.0.0:5000
causes the service to listen on all adapters and allows communications
between the vm and the container's external adapter through the
virtual private bridge that gets created when the container stands.
For some reason, switching my virtual machine to run in Bridged mode against my NIC is causing the boot2docker-vm to crash on start....so I'm relegated to NAT for the time being until I can figure out how to switch it properly.
[Edit 1 (related to bridging)]
Bridge mode seems to currently be unsupported in boot2docker as of at least October 8, 2014. b2d expects a NAT adapter for ssh bootstrapping and the host adapter for container<->container socket access.
The current, unsupported, undocumented workaround to expose a container to hosts on a network is to add a third network interface to VirtualBox and bridge with it.
[Edit 2 (example server running against default gateway)]
Here is an example of a flask server that attaches to all interfaces:
Note that the only Δ between the server above and the server below is the final line of the configuration.
app.run()
needs to become
app.run(host='0.0.0.0')
from flask import Flask
from flask import request
from flask.ext.cors import CORS
import os
app = Flask(__name__)
CORS(app, resources={r'/': {"origins": "*"}}, headers='Content-Type')
app.config['CORS_HEADERS'] = 'Content-Type'
#app.route('/')
def index():
return "<h1>Hello Stupid</h1>"
#app.route('/ruby/test', methods=['GET'])
def runRubyScript():
return os.system("ruby script.rb")
if __name__ == "__main__":
app.run(host='0.0.0.0')
I'm trying to develop my first "large" app with Flask on Heroku and I'm attempting to combine the basic tutorial here: https://devcenter.heroku.com/articles/python with the instructions here: http://flask.pocoo.org/docs/patterns/packages/#larger-applications. It works locally with "foreman start" but when I push to Heroku I get an error that the wrong port is in use:
Starting process with command python run.py
2012-12-04T23:45:18+00:00 app[web.1]: * Running on
http://127.0.0.1:5000/ 2012-12-04T23:45:18+00:00 app[web.1]: *
Restarting with reloader 2012-12-04T23:45:23+00:00 heroku[web.1]:
Error R11 (Bad bind) -> Process bound to port 5000, should be 33507
(see environment variable PORT)
I'm new to all this, but it looks like it's trying to run "locally" on Heroku. I've tried all sorts of combinations, but can't get it to work. My very simple code right now is (the app is called "pml"):
directory: /pml
Procfile:
web: python run.py
run.py:
from pml import app
app.run(debug=True)
directory: /pml/pml/
__init__.py
from flask import Flask
app = Flask(__name__)
import pml.views
view.py
from pml import app
#app.route('/')
def index():
return 'Hello World!'
I haven't used Heroku, but to me, it looks like they have a reserved port for Flask, specifically 33507. It looks like it will try to use an environment variable, which I am not sure how to set in Heroku. The good news is you can tell Flask which port to use.
try this:
app.run(debug=True, port=33507)
and it looks like adding the PORT to the env in heroku is done like this:
heroku config:add PORT=33507
You should only have to do one of these. I would try the first as it, to me, is the straight forward way to fix the issue.
EDIT
After reading the article from your post, I see where the issue comes in.
port = int(os.environ.get('PORT', 5000))
That line says, get the value of PORT from the environment if it is set, otherwise use 5000. I am not sure why they wouldn't allow it to run from 5000 if that's what is in their docs, but I would try this change:
port = int(os.environ.get('PORT', 33507))
I'm trying to develop my first "large" app with Flask on Heroku and I'm attempting to combine the basic tutorial here: https://devcenter.heroku.com/articles/python with the instructions here: http://flask.pocoo.org/docs/patterns/packages/#larger-applications. It works locally with "foreman start" but when I push to Heroku I get an error that the wrong port is in use:
Starting process with command python run.py
2012-12-04T23:45:18+00:00 app[web.1]: * Running on
http://127.0.0.1:5000/ 2012-12-04T23:45:18+00:00 app[web.1]: *
Restarting with reloader 2012-12-04T23:45:23+00:00 heroku[web.1]:
Error R11 (Bad bind) -> Process bound to port 5000, should be 33507
(see environment variable PORT)
I'm new to all this, but it looks like it's trying to run "locally" on Heroku. I've tried all sorts of combinations, but can't get it to work. My very simple code right now is (the app is called "pml"):
directory: /pml
Procfile:
web: python run.py
run.py:
from pml import app
app.run(debug=True)
directory: /pml/pml/
__init__.py
from flask import Flask
app = Flask(__name__)
import pml.views
view.py
from pml import app
#app.route('/')
def index():
return 'Hello World!'
I haven't used Heroku, but to me, it looks like they have a reserved port for Flask, specifically 33507. It looks like it will try to use an environment variable, which I am not sure how to set in Heroku. The good news is you can tell Flask which port to use.
try this:
app.run(debug=True, port=33507)
and it looks like adding the PORT to the env in heroku is done like this:
heroku config:add PORT=33507
You should only have to do one of these. I would try the first as it, to me, is the straight forward way to fix the issue.
EDIT
After reading the article from your post, I see where the issue comes in.
port = int(os.environ.get('PORT', 5000))
That line says, get the value of PORT from the environment if it is set, otherwise use 5000. I am not sure why they wouldn't allow it to run from 5000 if that's what is in their docs, but I would try this change:
port = int(os.environ.get('PORT', 33507))