Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Gunicorn ImportError: cannot import name 'ALREADY_HANDLED' from 'eventlet.wsgi' in docker

I had a working code running flask with gunicorn (eventlet worker) in docker. It's also working in production, but on my machine, it started doing this. I can't find anything on google about this thing. What meight be the problem?

Error: class uri 'eventlet' invalid or not found:
web_1       |
web_1       | [Traceback (most recent call last):
web_1       |   File "/root/.local/lib/python3.7/site-packages/gunicorn/util.py", line 99, in load_class
web_1       |     mod = importlib.import_module('.'.join(components))
web_1       |   File "/usr/local/lib/python3.7/importlib/__init__.py", line 127, in import_module
web_1       |     return _bootstrap._gcd_import(name[level:], package, level)
web_1       |   File "<frozen importlib._bootstrap>", line 1006, in _gcd_import
web_1       |   File "<frozen importlib._bootstrap>", line 983, in _find_and_load
web_1       |   File "<frozen importlib._bootstrap>", line 967, in _find_and_load_unlocked
web_1       |   File "<frozen importlib._bootstrap>", line 677, in _load_unlocked
web_1       |   File "<frozen importlib._bootstrap_external>", line 728, in exec_module
web_1       |   File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
web_1       |   File "/root/.local/lib/python3.7/site-packages/gunicorn/workers/geventlet.py", line 20, in <module>
web_1       |     from eventlet.wsgi import ALREADY_HANDLED as EVENTLET_ALREADY_HANDLED
web_1       | ImportError: cannot import name 'ALREADY_HANDLED' from 'eventlet.wsgi' (/root/.local/lib/python3.7/site-packages/eventlet/wsgi.py)
web_1       | ]
like image 291
Mark7888 Avatar asked May 05 '21 22:05

Mark7888


People also ask

How to fix a broken import from gevent to pywsgi?

Use a different WSGI server. You can directly use gevents wsgi server with python -m gevent.pywsgi my_module:my_app. Or try gunicorn. Patch the bottle sources to not have the broken import. gevent.wsgi simply did from gevent.pywsgi import *, so anywhere you see wsgi.Thing just replace it with pywsgi.Thing.

What happened to gevent WSGI?

gevent.wsgi was deprecated for years and was finally removed in gevent 1.3. There's an open bottle bug for this problem. Some of your options are: Use a different WSGI server.

How to replace WSGI with pywsgi?

You can directly use gevents wsgi server with python -m gevent.pywsgi my_module:my_app. Or try gunicorn Patch the bottle sources to not have the broken import. gevent.wsgi simply did from gevent.pywsgi import *, so anywhere you see wsgi.Thing just replace it with pywsgi.Thing.


3 Answers

Installing older version of eventlet solved the problem: pip install eventlet==0.30.2


EDIT:

you can use the newer versions like this: pip install eventlet==0.33.0 https://github.com/benoitc/gunicorn/archive/refs/heads/master.zip#egg=gunicorn==20.1.0

see: https://github.com/benoitc/gunicorn/pull/2581#issuecomment-994198667

thank you @jmunsch

like image 56
Mark7888 Avatar answered Oct 17 '22 22:10

Mark7888


Looks like there was a change recently to eventlet

See this PR for an example patch, and potential release version: https://github.com/benoitc/gunicorn/pull/2581

Eventlet 0.30.3+ removed wsgi.ALREADY_HANDLED breaking public API in just a patch version increase. Sorry.

Issue with ALREADY_HANDLED: eventlet/eventlet#543 Solution with WSGI_LOCAL: eventlet/eventlet#544

It's recommended to use eventlet>=0.31.0 if one uses websockets, because older versions are vulnerable to DoS attack. GHSA-9p9m-jm8w-94p2

CI failed in pylint checks on lines I didn't touch.

like image 37
jmunsch Avatar answered Oct 17 '22 23:10

jmunsch


I had exactly the same error when trying to use SocketIO with Flask and found the answer at https://localcoder.org/deploy-flask-socketio-on-beanstalk

I was able to get this running as per their suggestion:

pip uninstall gunicorn
pip uninstall eventlet
pip install gunicorn==20.1.0
pip install eventlet==0.30.2

gunicorn --worker-class eventlet -w 1 app:app

Environment: AWS ALB -> EC2/Linux2 (python 3.8.5, Flask Socket.IO)

like image 2
jono2010 Avatar answered Oct 17 '22 21:10

jono2010