9

I have a Flask application, getting this error while trying to integrate flask with faust.

app.py

import mode.loop.eventlet
import logging
import logging.config
import json
from flask import Flask
from elasticapm.contrib.flask import ElasticAPM

def create_app():
    app = Flask(__name__)
    configure_apm(app)
    configure_logging()
    register_blueprints(app)
    register_commands(app)
    return app

main.py

from flask import jsonify
from litmus.app import create_app
from intercepter import Intercepter

app = create_app()
app.wsgi_app = Intercepter(app.wsgi_app , app)

@app.route('/status')
def status():
    return jsonify({'status': 'online'}), 200

another controller

@api_blue_print.route('/v1/analyse', methods=['POST'])
def analyse():
    analyse_with_historic_data.send(value=[somedata])
    return jsonify({'message': 'Enqueued'}), 201

analyse_with_historic_data.py

@app.agent(analysis_topic)
async def analyse_with_historic_data(self, stream):
    async for op in stream:
        entity_log = EntityLog.where('id', op.entity_log_id).first()

Error Trace:

Traceback (most recent call last):
  File "/Users/sahilpaudel/.pyenv/versions/3.6.5/lib/python3.6/site-packages/eventlet/hubs/hub.py", line 461, in fire_timers
    timer()
  File "/Users/sahilpaudel/.pyenv/versions/3.6.5/lib/python3.6/site-packages/eventlet/hubs/timer.py", line 59, in __call__
    cb(*args, **kw)
  File "/Users/sahilpaudel/.pyenv/versions/3.6.5/lib/python3.6/site-packages/eventlet/semaphore.py", line 147, in _do_acquire
    waiter.switch()
greenlet.error: cannot switch to a different thread
Traceback (most recent call last):
  File "/Users/sahilpaudel/.pyenv/versions/3.6.5/lib/python3.6/site-packages/eventlet/hubs/hub.py", line 461, in fire_timers
    timer()
  File "/Users/sahilpaudel/.pyenv/versions/3.6.5/lib/python3.6/site-packages/eventlet/hubs/timer.py", line 59, in __call__
    cb(*args, **kw)
  File "/Users/sahilpaudel/.pyenv/versions/3.6.5/lib/python3.6/site-packages/eventlet/semaphore.py", line 147, in _do_acquire
    waiter.switch()
greenlet.error: cannot switch to a different thread
Traceback (most recent call last):
  File "/Users/sahilpaudel/.pyenv/versions/3.6.5/lib/python3.6/site-packages/eventlet/queue.py", line 118, in switch
    self.greenlet.switch(value)
greenlet.error: cannot switch to a different thread
^CError in atexit._run_exitfuncs:
Traceback (most recent call last):
  File "/Users/sahilpaudel/.pyenv/versions/3.6.5/lib/python3.6/threading.py", line 551, in wait
    signaled = self._cond.wait(timeout)
  File "/Users/sahilpaudel/.pyenv/versions/3.6.5/lib/python3.6/threading.py", line 299, in wait
    gotit = waiter.acquire(True, timeout)
  File "/Users/sahilpaudel/.pyenv/versions/3.6.5/lib/python3.6/site-packages/eventlet/semaphore.py", line 107, in acquire
    hubs.get_hub().switch()
  File "/Users/sahilpaudel/.pyenv/versions/3.6.5/lib/python3.6/site-packages/eventlet/hubs/hub.py", line 298, in switch
    return self.greenlet.switch()
  File "/Users/sahilpaudel/.pyenv/versions/3.6.5/lib/python3.6/site-packages/eventlet/hubs/hub.py", line 350, in run
    self.wait(sleep_time)
  File "/Users/sahilpaudel/.pyenv/versions/3.6.5/lib/python3.6/site-packages/eventlet/hubs/kqueue.py", line 96, in wait
    time.sleep(seconds)

I have trying to fix this issue by monkey.patch_all but that too it didn't work out giving another stacktrace that lock cannot be released something.

Sahil Paudel
  • 548
  • 6
  • 15

2 Answers2

14

Something similar happened to me when I tried to debug a flask application using Pycharm.

What I finally did to eventually solve my issue was to enable gevent compatibility in Pycharm:
File -> settings -> Build,Execution,Deployment -> Python debugger -> Gevent compatible

gilodo
  • 311
  • 3
  • 7
  • 6
    In vscode the same can be done by adding `"gevent": true` in your `launch.json`. See documentation [here](https://code.visualstudio.com/docs/python/debugging#_gevent). – Alex Telon Jan 10 '22 at 11:16
  • Thanks a lot @AlexTelon . I've been a while looking for some answers for that issue, but yours is the simplest. – Ariel Catala Valencia Jan 19 '22 at 10:49
  • @alex-telon it seems TS is using `eventlet`. Are you sure that `"gevent": true` is correct config? But it's really works for me with eventlet. – Kuznetsov-M Jul 18 '22 at 15:33
  • @Kuznetsov-M I am not sure. But if I remember it correctly I was also using `eventlet` not `gevent`. And OP here used `greenlet`. I assume these utilities work in a similar way which is why this flag worked for me too. – Alex Telon Aug 21 '22 at 11:40
  • I had a similar issue and that solved it, but now I can't debug my python code normally – mishadr May 30 '23 at 15:07
1

If previous answer do not help, paste the following before all imports:

from gevent import monkey
monkey.patch_all()

See here: https://www.gevent.org/api/gevent.monkey.html

Freddie
  • 908
  • 1
  • 12
  • 24
  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – xlmaster Mar 01 '23 at 13:11