Running aiohttp server using gunicorn - python

I am trying to run a aiohttp based server using Gunicorn.
Here is the command:
gunicorn aiohttpdemo_polls:app --bind 127.0.0.1:8080
It returns:
Failed to find application: 'aiohttpdemo_polls'
But when I am running it using python -m like below:
python -m aiohttpdemo_polls
It works fine. The code can be found from here which is a demo app in the aiohttp repo.
Also tried it like below:
gunicorn aiohttpdemo_polls.main:app --bind 127.0.0.1:8080
But its also not running the server. It returns
Failed to find application: 'aiohttpdemo_polls.main'
Any idea where to look further for fixing the issue?

aiohttp 3.1 supports coroutine as application factory, such as:
async def my_web_app():
app = web.Application()
app.router.add_get('/', index)
return app
Current implementation of aiohttpdemo_polls uses this approach. It can be started with
gunicorn aiohttpdemo_polls.main:init_app --bind localhost:8080 --worker-class aiohttp.GunicornWebWorker

The demo does not support gunicorn yet.
I filed an issue: https://github.com/aio-libs/aiohttp-demos/issues/10
Thanks for report.

Related

How to quickly deploy a Aiohttp Python project on Heroku or similar

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!

App Engine Flexible can't use datastore with websockets example

I tried adding the websockets example project to the datastore project and the websockets work but when a page queries the datastore or tries to put a new entity I get a 502 response. In the logs it shows a critical error on the service worker. If I remove the websocket code the datastore code works as intended. The only difference I can see is the entrypoints for the app samples slightly differ
the websocket sample uses
entrypoint: gunicorn -b :$PORT -k flask_sockets.worker main:app
while the datastore sample uses
entrypoint: gunicorn -b :$PORT main:app
websocket sample https://github.com/GoogleCloudPlatform/python-docs-samples/tree/master/appengine/flexible/websockets
datastore sample
https://github.com/GoogleCloudPlatform/python-docs-samples/tree/master/appengine/flexible/datastore
The problem appears to be that GRPC (the default transport mechanism of the Cloud Datastore client) is not compatible with gevent. Aside from using a different websockets framework, you can work around the issue by activating grpc's gevent compatibility patch, using the following code:
import grpc.experimental.gevent as grpc_gevent
grpc_gevent.init_gevent()
As a complement of Andrew's answer, you can extend the gunicorn worker class to run gRPC applications.
# gevent_grpc_worker.py
from gunicorn.workers.ggevent import GeventWorker
from grpc.experimental import gevent
class GeventGrpcWorker(GeventWorker):
def patch(self):
super(GeventGrpcWorker, self).patch()
gevent.init_gevent()
self.log.info('patched grpc')
# config.py for gunicorn
import multiprocessing
from gevent_grpc_worker import GeventGrpcWorker
# http://docs.gunicorn.org/en/stable/design.html#how-many-workers
workers = multiprocessing.cpu_count() * 2 + 1
worker_connections = 10000
# Use an asynchronous worker as most of the work is waiting for websites to load
worker_class = '.'.join([GeventGrpcWorker.__module__,
GeventGrpcWorker.__name__])
timeout = 30
Then start your managed application by:
gunicorn -c config.py app:app
As you said it seems there is a problem with the flask_socket.worker, I have test it and it does not work with the datastore client.
I have tried with the Flask-SocketIO framework using the eventlet worker and the datastore queries work fine.
entrypoint: gunicorn -b :$PORT --worker-class eventlet -w 1 main:app
Also you need to add the eventlet module in the requirements.txt file eventlet==0.24.1
The downside of this is that it breaks the compatibility with the websocket code so you need to rewrite this part. Keep in mind that code samples are just intended to show in a few lines how to use the Google Cloud products and copy-paste them without modifying the configuration undelied in the app.yaml is not a good idea.

Python error when attempting to run on heroku

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)

Gunicorn RecursionError with gevent and requests in python 3.6.2

I have a simple flask script that uses requests to make http requests to third party web service. The way I run the script in gunicorn is
gunicorn abc:APP -b 0.0.0.0:8080 -w 4 -k gevent --timeout 30 --preload
However, after I upgrade the code to python 3.6.2, I can still run the server, but whenever the webserver received a request, it shows
RecursionError: maximum recursion depth exceeded while calling a Python object
on every worker, and the server seems are still running. When I change the running command to
gunicorn abc:APP -b 0.0.0.0:8080 -w 4 --timeout 30 --preload
It all works again. So is there any issue with gunicorn's async worker and requests in python 3.6.2? Is there a way to fix this?
(This question is also asked at https://github.com/benoitc/gunicorn/issues/1559)
This is because of the ssl is imported before monkey patch, gunicorn import the ssl module(config.py in gevent) when loading config,however the monkey patch is called when init the worker or at the top of app.py file which is definitely after import of ssl, this is why we get the warning.
A simple solution is to use a config file for gunicorn.
we could do gevent monkey patch at the beginning of config file, and start gunicorn with the config file, in this way, the monkey patch could be completed before import ssl, and thus avoid this problem.
A config file named gunicorn_config.py could contain lines below:
import gevent.monkey
gevent.monkey.patch_all()
workers = 8
and then we could start gunicorn with
gunicorn --config config.py --worker-class gevent --preload -b 0.0.0.0:5000 app:app
More information could be found here
Please see https://github.com/benoitc/gunicorn/issues/1559. This may possibly be fixed in the next version of gunicorn, but unfortunately you may have to stay with python 3.5.2 if you don't want to break gunicorn.

Run Falcon APP with uwsgi

I just started to learn Falcon (http://falcon.readthedocs.org/en/latest/user/quickstart.html)
but it need a web server running and docs suggesting use uwsgi or gunicorn.
though they have mentioned that how to use it with gunicorn
$ pip install gunicorn #install
$ gunicorn things:app #and run app through gunicorn.
But I want to run this sample app with uwsgi. but I have no clue how to.
I have installed it pip install uwsgi also gevent as suggested here http://falcon.readthedocs.org/en/latest/user/install.html
but what now. somebody guide me.
You'll probably find your answer on the uWSGI documentation site, specifically try this page:
http://uwsgi-docs.readthedocs.org/en/latest/WSGIquickstart.html
I've never used Falcon or uWSGI, but it looks like you can probably get away with:
uwsgi --wsgi-file things.py --callable app
You can use uwsgi.ini to store configuration and easy run. Good way to setup uwsgi as services. Configuration with virtualenv
[uwsgi]
http = :8000
chdir = /home/user/www/uwsgi-ini
virtualenv = /home/user/www/uwsgi-ini/venv/
wsgi-file = main.py
callable = app
processes = 4
threads = 2
stats = 127.0.0.1:9191
and run in app folder:
uwsgi uwsgi.ini
command with virtualenv
uwsgi --http :8000 --wsgi-file main.py --callable app -H $(pwd)/venv/

Categories

Resources