My question is basically what's in the title: how can I setup gunicorn to run a web.py app? (Also, if there are any differences, how would I do it on heroku?)
I already have my app running on heroku using the built in cherrypy, but I have not been able to get gunicorn to work with web.py (I just have no idea where to start - I couldn't find any tutorials).
I'm afraid I'm not familar with Heroku, but I can answer your basic question.
gunicorn is a HTTP server for running Python web apps via WSGI. web.py is a framework for creating Python web apps using WSGI.
So you don't really need a tutorial for using both together, as all you need to do is figure out how to pass the WSGI entry point of your web.py application to gunicorn. A WSGI application is just a Python callable with the right interface i.e. it takes certain parameters and returns a certain response. See this WSGI tutorial for more.
The "hello world" application from the web.py tutorial looks like this test.py:
import web
urls = (
'/', 'index'
)
class index:
def GET(self):
return "Hello, world!"
if __name__ == "__main__":
app = web.application(urls, globals())
app.run()
But that does not expose the WSGI application which gunicorn needs.
web.py provides a WSGI application via the wsgifunc method of web.application. We can add this to test.py by adding the following after the index class:
# For serving using any wsgi server
wsgi_app = web.application(urls, globals()).wsgifunc()
This is basically what the web.py documentation tells you to do in the deployment section, when using Apache + mod_wsgi - the fact that the Python code is the same for us with gunicorn is not a coincidence because this is exactly what WSGI gives you - a standard way to write the Python so that it can be deployed using any WSGI capable server.
As explained in the gunicorn docs, we can then point gunicorn at the wsgi_app member of the test module as follows:
(tmp)day#office:~/tmp$ gunicorn test:wsgi_app
2012-12-03 23:31:11 [19265] [INFO] Starting gunicorn 0.16.1
2012-12-03 23:31:11 [19265] [INFO] Listening at: http://127.0.0.1:8000 (19265)
2012-12-03 23:31:11 [19265] [INFO] Using worker: sync
2012-12-03 23:31:11 [19268] [INFO] Booting worker with pid: 19268
Related
I've got an aiohttp based project in Python, not overly complicated, just takes advantage of the async routes, etc. I'd like to quickly deploy to Heroku and cannot find a recent step by step. I've tried using their standard Gunicorn approach and it's not working. My Procfile is:
web: gunicorn go:web --preload
Here are the errors that seem to be important from my Heroku log:
2020-06-28T01:37:40.103872+00:00 app[web.1]: ======== Running on http://0.0.0.0:8080 ========
2020-06-28T01:37:40.103895+00:00 app[web.1]: (Press CTRL+C to quit)
2020-06-28T01:37:51.000000+00:00 app[api]: Build succeeded
2020-06-28T01:38:31.441039+00:00 heroku[web.1]: Error R10 (Boot timeout) -> Web process failed to bind to $PORT within 60 seconds of launch
If anyone has successfully deployed an aiohttp project to Heroku, I'd love to know what you had to adjust to get it working! Thanks very much.
I got this working for a hello world aiohttp app
here's app.py
from aiohttp import web
import os
async def hello(request):
return web.Response(text="Hello, world")
app = web.Application()
app.add_routes([web.get('/', hello)])
web.run_app(app, port=os.getenv('PORT'))
Procfile
web: python app.py --bind localhost:8080
requirements.txt
aiohttp
Flask
Werkzeug
Thankful for this other SO post which help alot for not using gunicorn.
BAMN!
I have a service, which contains 2 Flask-applications - let's name them app and monitoring_app running on different ports. monitoring_app is an utility service which provides metrics collected with prometheus_client. I have faced up with an issue trying run them under the Gunicorn server properly.
I have read through the similar topic:
Multiple Flask Application in single uwsgi
but it seems my problem can't be solved with Dispatcher Middleware.
I can start these applications without Gunicorn like this:
from threading import Thread
import os
from my_project import create_app, create_monitoring_app
def start_app(my_app):
my_app.run(host="localhost",
debug=True,
port=int(os.environ.get("API_PORT", "5000")),
threaded=True,
use_reloader=False)
if __name__ == "__main__":
app = create_app()
app_thread = Thread(target=start_app, daemon=True, args=(app,))
app_thread.start()
monitoring_app = create_monitoring_app()
monitoring_app.run(host="localhost",
port=int(os.environ.get("OPS_PORT", "5001")),
threaded=True,
use_reloader=False,
debug=True)
It works ok for development, but it runs under Flask development server which is not ok for production environment. With Gunicorn I can start them separately:
gunicorn "my_project:create_monitoring_app()" -b "[::]:$OPS_PORT" &
gunicorn "my_project:create_app()" -b "[::]:$API_PORT"
but then they will be in different interpreters and I can't use prometheus_client of app in monitoring_app what is critical for me
What can I do to achieve same behavior as if I run these applications from my development environment? Or may be I am doing something wrong and I should do it in another way?
Im trying to deploy a python app to heroku. I use a web framework called quart (an asyncio adaptation of flask). The build succeeds when I try to deploy, but in the heroku logs, I get this error message:
TypeError: __call__() takes 1 positional argument but 3 were
This is the code that runs the app:
if __name__ == '__main__':
app.run(host='0.0.0.0', port=int(os.environ['PORT']))
My procfile consists of this:
web: gunicorn main_loop:app
Help would be appreciated.
Quart requires a specific Gunicorn worker class1. I think if your procfile was
web: gunicorn --worker-class quart.worker.GunicornWorker main_loop:app
it would work. (I don't have a heroku dyno available to test though).
(I am the Quart author)
I'm getting started with WSGI and until now, with a little help from some tutorials,I'm making some tests towards Flask with uWSGI in front of it, since that Flask is not a good option for Production environments (doesn't scale well and by default, it answers one request per time - http://flask.pocoo.org/docs/0.12/deploying/) and uWSGI gives flexibility and more reliability, spawning workers and processes. Am I wrong?
Most of the tutorials that I saw until, are pointing about setups with Nginx in front of WSGI, but is it really necessary? What I'm trying to do is just to give a scalable way to deliver requests to my Flask application, something with more performance and scalability.
So I have this basic setup:
hello.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=8080)
wsgi.py
from hello import app
if __name__ == "__main__":
app.run()
Running uWSGI:
uwsgi --socket 0.0.0.0:8080 --plugin python --wsgi-file wsgi.py --callable app --master --processes 4 --threads 2 &
When I perform a curl against the loopback address, I receive an empty reply..
curl http://127.0.0.1:8080
invalid request block size: 21573 (max 4096)...skip
curl: (52) Empty reply from server
Forgive me, but I can't see what I'm missing. Does anyone here, more experienced with WSGI, could point where is the failure of this setup? Any help would me much appreciated.
Reference documents:
https://www.digitalocean.com/community/tutorials/how-to-serve-flask-applications-with-uwsgi-and-nginx-on-ubuntu-16-04
http://uwsgi-docs.readthedocs.io/en/latest/WSGIquickstart.html
Your option, socket should be used when you combine uwsgi with web server (nginx for example). Otherwise you should use http, so
uwsgi --http 0.0.0.0:8080 --plugin python --wsgi-file wsgi.py --callable app --master --processes 4 --threads 2
will work.
Production environments (doesn't scale well and by default, it answers
one request per time - http://flask.pocoo.org/docs/0.12/deploying/)
and uWSGI gives flexibility and more reliability, spawning workers and
processes. Am I wrong?
You are right.
Most of the tutorials that I saw until, are pointing about setups with
Nginx in front of WSGI, but is it really necessary? What I'm trying to
do is just to give a scalable way to deliver requests to my Flask
application, something with more performance and scalability.
Well, nginx is designed to be in front and having it is much better then only application server (uwsgi). Specialisation, that's the key. Let your application server focus on bussiness processing and python.
Trying to work with Django python pulsar concurrent processing framework.
The wsgi server provided by pulsar can be used through command line as
$python manage.py pulse
which basically starts a HTTP WSGI server, similar to django's dev server.
How can it be set up with Apache webserver with mod_wsgi?
Is this case what you really want is to use pulsar's WSGI server and consume your django app as a regular wsgi application (if you are on django 1.5.x or above it would have created a wsgi.py in your project home). Here's an example:
from pulsar.apps import wsgi
import yourapp
middlewares = [
wsgi.middleware.wait_for_body_middleware,
yourapp.wsgi.application
]
if __name__ == '__main__':
wsgi.WSGIServer(wsgi.handlers.WsgiHandler(middleware=middlewares)).start()
protip: the "wait_for_body_middleware" makes pulsar wait for the full body response to be available before moving on to another request (which is the normal behavior of most webapps)
source:
http://pythonhosted.org/pulsar/apps/wsgi/intro.html#wsgi-server