How to Serve a Local App Using Waitress and Nginx - python

I have a dash(plotly) app set up using flask as the server and can serve it on our Windows Server to port:8041 using waitress. My code to launch waitress is below;
#!/usr/bin/env python3
from waitress import serve
from src.pacedash.app import server as application
if __name__ == "__main__":
serve(application, threads=100, port=8041)
Everything works great if I use python run_waitress.py, except that when someone on our network navigates to the servename:8041 there is a "Not Secure" warning next to the url. Our IT vendor was able to get a cert file and key, but I'm not sure how to bring those into my current setup.
I have been trying to use nginx, but I can't find a guide to setting it up with waitress and I'm not too familiar with web apps or wsgi because I primarily work as the lone data person here.

I have been working on this same issue and have a solution. The nginx .conf file needs have a location defined like this:
location /myapp/ {
# Define the location of the proxy server to send the request to
proxy_pass http://localhost:8041/myapp/;
# standard proxy_set_header stuff below...
}
Then in your Dash application set the url_base_pathname to the same value:
app = dash.Dash(__name__, url_base_pathname='/myapp/')

I would use ngrok to expose your web app. It's amazingly simple:
Read this: https://ngrok.com/
I could be misinterpreting what you need, because I am not familiar with waitress (why not serve the app locally just using flask?), but if you need to test the live app, ngrok is what you should use.

Related

How to run Python Flask app on domain name?

I own a domain name, how can I get my flask app to run on it, using my public IP address (assigned to me by my internet provider)? I don't want it to run on localhost, or my private IPv4 address, I want it to run on my Public IP address. Thanks in advance.
If it helps, I am using Google Domains.
Do I need to add anything to my flask app?
I'm currently running it like this:
if __name__ == "__main__":
db.create_all()
app.run(debug=True, host="0.0.0.0", port=80)
Was this a public IP provided by your Internet provider? Or is it a public IP provided by a web hosting company? The two answers are different.
If it came from a web hosting company, then you need to upload your flask app to your account on their server. Note, however, that most shared hosting companies will not let you run an app 24/7. They want to support FastCGI servers that come and go.
If this was provided by your Internet provider, then you will need to provide and configure a server. You will need to have your router redirect port 80 and 443 to that server. You will then need to run your flask app on that server. Make sure your server is secure, because public-facing IP address get hammered by scammers.

Docker and WSGI with a Python Pyramid app?

I am looking at two articles on how to Dockerize a Pyramid app. I am not that familiar with Python, but I am fairly certain with a Pyramid app you need to use WSGI.
This article uses WSGI:
https://medium.com/#greut/minimal-python-deployment-on-docker-with-uwsgi-bc5aa89b3d35
This one just runs the python executable directly:
https://runnable.com/docker/python/dockerize-your-pyramid-application
It seems unlikely to me that you can run python directly and not incorporate WSGI, can anyone provide an explanation for why the runnable.com article's docker solution would work?
Per the scripts in the second link:
from wsgiref.simple_server import make_server
from pyramid.config import Configurator
from pyramid.response import Response
~snip~
if __name__ == '__main__':
config = Configurator()
config.add_route('hello', '/')
config.add_view(hello_world, route_name='hello')
app = config.make_wsgi_app() # The wsgi server is configured here
server = make_server('0.0.0.0', 6543, app) # and here
This contains an explanation of why the wsgi server is built in the if __name__=="__main__" block

flask with uwsgi nginx gateway timeout

I have set up a flask application to use uwsgi and nginx
I used the tutorials on the internet but I have the following issue
I have the following functions on the controller.py file
api_module = Blueprint('cassandra_api', __name__, url_prefix="/api")
#api_module.route('/', methods=['GET', 'POST'])
def home():
return "c"
the above works great when trying
myip/api/
but the following doesn't work at all
#api_module.route("/fault_prone_snippets/", methods=['GET'])
def get_fault_prone_snippets():
#code to connect with cassandra db and retrieve get parameters
When I visit
myip/api/faut_prone_snippets/
with or without get parameters, no code is executed, I don't see an error message and after the minute is over I get a gateway timeout. The problem is that when I run my flask from localhost it works great. Trying to use cassandra driver from the python console on my dev environment works too and connects with no error. How can I debug this kind of setup when it works locally but not in production?
As you're running behind nginx it might be that setting the keep_alive timeout in the http section of your nginx.conf will help. And/or proxy_send_timeout,
proxy_read_timeout parameters in the location section.

Tornado web server in webfaction

I am starting with web development. I am trying to develop and webapp using the Instagram API and Django. I was looking that a lot of people it's using Tornado Web Server for Real Time Subscriptions. So I am using Webfaction as a host and found this code so I can wrap my Django project with the "WSGI Container" that Tornado Web Server provides:
import os
import tornado.httpserver
import tornado.ioloop
import tornado.wsgi
import tornado.web
import sys
import django.core.handlers.wsgi
sys.path.append('/path/to/project')
class HelloHandler(tornado.web.RequestHandler):
def get(self):
self.write('Hello from tornado')
def main():
os.environ['DJANGO_SETTINGS_MODULE'] = 'myproject.settings' # path to your settings module
wsgi_app = tornado.wsgi.WSGIContainer(django.core.handlers.wsgi.WSGIHandler())
tornado_app = tornado.web.Application(
[
('/hello-tornado', HelloHandler),
('.*', tornado.web.FallbackHandler, dict(fallback=wsgi_app)),
]
)
http_server = tornado.httpserver.HTTPServer(tornado_app)
http_server.listen(8080)
tornado.ioloop.IOLoop.instance().start()
if __name__ == "__main__":
main()
So I run this python script inside my Webfaction server and everytime I try to access "http://mywebsite.com/hello-tornado/" does not seem to work. I know I am running that Tornado web server on that port but do not know how too access from the browser or something like that. What I am doing wrong here? Thanks for your help and patience. Will cyber high-five for every answer.
EDIT: What I am really trying to do is that I want to receive all the calls from the subscriptions that I make with the Instagram RealTime Subscription API through Tornado, for that I have a callback url "http://mysite.com/sub" and I want to be able to receive through Tornado.
You are starting the server at port 8080, Web browsers use port 80 by default, try using: http://mywebsite.com:8080/hello-tornado
if you want to use port 80 and you already have a web server running in the box you can try following Ali-Akber Saifee suggestion, or run the WSGI application directly from the server, using something like mod_python (http://www.modpython.org), you will lose the ability to run Tornado code, but Django will work.
You have to create a custom app (listening on port), note the port that is assigned to your app then configure tornado to serve on that port: http_server.listen(my port)
You can also avoid tornado and start directly by installing a django app.

AWS - Running webservice - Cherrypy + Python

I have a linux box (Ubuntu 10.10 server edition) in ec2. I have written a web service using cherrypy framework. Let's say this is the code that I have written.
import sys
sys.path.insert(0,'cherrypy.zip')
import cherrypy
from cherrypy import expose
class Service:
#expose
def index(self):
return 'Hello World'
cherrypy.quickstart(Service())
I have copied this file, the cherrypy.zip file to /var/www in my ec2 instance. [I should inform that I created the www directory manually, as it wasn't there]. Then I ran
python webservice.py
and got the message
[01/Apr/2011:13:50:04] ENGINE Bus STARTED
However, when I try to run
(I have masked my public ip)
ec2-1**-2**-1**-**.ap-southeast-1.compute.amazonaws.com/
in my browser, I get connection failed. Can anyone tell me where I have gone wrong? or what I should do?
EDIT:
Okay, here is something interesting that I found. When I do
python webservice.py
I see
ENGINE Serving on 127.0.0.1:8080
Which means, the webservice will run only for the local machine. How do I make set the service 0.0.0.0 (that is, to serve any IP address?)
Hope this detail is sufficient for understanding the problem I'm facing. Help, please :)
EDIT 2:
Oh well, found the solution :-) Have to add this before cherrypy.quickstart() call
cherrypy.config.update({'server.socket_host': '0.0.0.0',
'server.socket_port': 80,
})
The cherrypy.quickstart function takes a config argument, which can be a dict, an open configuration file, or a path to a configuration file. I favor using a path to a configuration file because that minimizes the hardcoding of settings that you might prefer to control from a startup script.
In addition, since you control the server, you could configure a reverse proxy to route requests to the CherryPy application. This gives you quite a bit of flexibility. For example, if you wanted to, you could run multiple instances of the CherryPy application in parallel, each configured to listen on a different port.
Here's a sample configuration file for nginx, instructing it to forward requests to a single instance of your CherryPy application:
server
{
server_name your.hostname.com;
  location / {
    proxy_pass http://127.0.0.1:8080/;
  }
}
And here's a sample configuration file instructing nginx to load-balance across two instances of your application, which are listening on the loopback address at ports 33334 and 33335:
upstream myapps {
server 127.0.0.1:33334;
server 127.0.0.1:33335;
}
server {
server_name your.hostname.com;
location / {
proxy_pass http://myapps;
}
}

Categories

Resources