RuntimeError: There is no current event loop in thread in async + apscheduler RuntimeError: There is no current event loop in thread in async + apscheduler python-3.x python-3.x

RuntimeError: There is no current event loop in thread in async + apscheduler


In your def demo_async(urls), try to replace:

loop = asyncio.get_event_loop()

with:

loop = asyncio.new_event_loop()asyncio.set_event_loop(loop)


The important thing that hasn't been mentioned is why the error occurs. For me personally, knowing why the error occurs is as important as solving the actual problem.

Let's take a look at the implementation of the get_event_loop of BaseDefaultEventLoopPolicy:

class BaseDefaultEventLoopPolicy(AbstractEventLoopPolicy):    ...    def get_event_loop(self):        """Get the event loop.        This may be None or an instance of EventLoop.        """        if (self._local._loop is None and            not self._local._set_called and            isinstance(threading.current_thread(), threading._MainThread)):            self.set_event_loop(self.new_event_loop())        if self._local._loop is None:            raise RuntimeError('There is no current event loop in thread %r.'                               % threading.current_thread().name)        return self._local._loop

You can see that the self.set_event_loop(self.new_event_loop()) is only executed if all of the below conditions are met:

  • self._local._loop is None - _local._loop is not set
  • not self._local._set_called - set_event_loop hasn't been called yet
  • isinstance(threading.current_thread(), threading._MainThread) - current thread is the main one (this is not True in your case)

Therefore the exception is raised, because no loop is set in the current thread:

if self._local._loop is None:    raise RuntimeError('There is no current event loop in thread %r.'                       % threading.current_thread().name)


Just pass fetch_all to scheduler.add_job() directly. The asyncio scheduler supports coroutine functions as job targets.

If the target callable is not a coroutine function, it will be run in a worker thread (due to historical reasons), hence the exception.