streamlit: RuntimeError: There is no current event loop in thread error with Streamlit and Asyncio

Summary

I am running pyppeteer, which depends on asyncio, to load data which is only available in a rendered web page. I experienced an error earlier with Jupyter, which depends on tornado, and where I received an error that RuntimeError: This event loop is already running. The reason is that tornado was reworked with asyncio and there didn’t seem to be a realistic workaround by the Jupyter developers. The issue was solved with this library nest_asyncio. Whether I include nest_asyncio or not, I receive the error RuntimeError: There is no current event loop in thread 'ScriptRunner.scriptThread'.

Steps to reproduce

What are the steps we should take to reproduce the bug:

  1. Initializing the RenderHTML class in the following imported file, will cause the error to be outputted as an error to the Streamlit UI.
import asyncio
import nest_asyncio
#nest_asyncio.apply()
from pyppeteer import launch

class HTMLMissing(Exception):
    '''An exception for a missing or invalid HTML.'''
    pass

class RenderHTML():

    def __init__(self, html=None):
        self.html = ""
        self.set_html(html)
        asyncio.get_event_loop().run_until_complete(self.build_page())

    async def build_page(self):
        browser = await launch()
        context = await browser.createIncognitoBrowserContext()
        self.page = await browser.newPage()

   ...other functions...

Expected behavior:

Load RenderHTML class, launch chrome, and build a new browser page.

Actual behavior:

With: nest_asyncio.apply()

RuntimeError: There is no current event loop in thread 'ScriptRunner.scriptThread'.
Traceback:

  File "c:\users\jroak\anaconda3\envs\project\lib\site-packages\streamlit\ScriptRunner.py", line 311, in _run_script
    exec(code, module.__dict__)
  File "D:\AnacondaProjects\DataProject\main.py", line 25, in <module>
    from engine import *
  File "D:\AnacondaProjects\DataProject\engine.py", line 25, in <module>
    from lib import *
  File "D:\AnacondaProjects\DataProject\lib\__init__.py", line 34, in <module>
    from .renderer import RenderHTML
  File "D:\AnacondaProjects\DataProject\lib\renderer.py", line 55, in <module>
    nest_asyncio.apply()
  File "c:\users\jroak\anaconda3\envs\project\lib\site-packages\nest_asyncio.py", line 11, in apply
    loop = loop or asyncio.get_event_loop()
  File "c:\users\jroak\anaconda3\envs\project\lib\asyncio\events.py", line 644, in get_event_loop
    % threading.current_thread().name)

Without: nest_asyncio.apply()

RuntimeError: There is no current event loop in thread 'ScriptRunner.scriptThread'.
Traceback:

  File "c:\users\jroak\anaconda3\envs\project\lib\site-packages\streamlit\ScriptRunner.py", line 311, in _run_script
    exec(code, module.__dict__)
  File "D:\AnacondaProjects\DataProject\main.py", line 94, in <module>
    main()
  File "D:\AnacondaProjects\DataProject\main.py", line 71, in main
    crawler = render_data(crawler)
  File "c:\users\jroak\anaconda3\envs\project\lib\site-packages\streamlit\caching.py", line 560, in wrapped_func
    return get_or_set_cache()
  File "c:\users\jroak\anaconda3\envs\project\lib\site-packages\streamlit\caching.py", line 540, in get_or_set_cache
    return_value = func(*args, **kwargs)
  File "D:\AnacondaProjects\DataProject\main.py", line 39, in render_data
    crawler.render()
  File "D:\AnacondaProjects\DataProject\engine.py", line 126, in render
    renderer = RenderHTML()
  File "D:\AnacondaProjects\DataProject\lib\renderer.py", line 72, in __init__
    asyncio.get_event_loop().run_until_complete(self.build_page())
  File "c:\users\jroak\anaconda3\envs\project\lib\asyncio\events.py", line 644, in get_event_loop
    % threading.current_thread().name)

Is this a regression?

That is, did this use to work the way you expected in the past? IDK yes / no

Debug info

  • Streamlit version: 0.50.2
  • Python version: 3.7.5
  • Using Conda? PipEnv? PyEnv? Pex? Conda
  • OS version: Windows 10
  • Browser version: 70.0.1 (64-bit)

Additional information

If needed, add any other context about the problem here. For exmaple, did this bug come from https://discuss.streamlit.io or another site? Link the original source here!

About this issue

  • Original URL
  • State: open
  • Created 5 years ago
  • Reactions: 5
  • Comments: 29 (1 by maintainers)

Commits related to this issue

Most upvoted comments

I’m experiencing this as well, using an internal API client that’s using nest_asyncio. I’m able to reproduce the error with:

import nest_asyncio
nest_asyncio.apply()

with the same error and stack trace as @Agerrr on Python 3.6.8.

I’m using this as a workaround for the time being:

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

Add this code before import ib_insync:

import asyncio

def get_or_create_eventloop():
    try:
        return asyncio.get_event_loop()
    except RuntimeError as ex:
        if "There is no current event loop in thread" in str(ex):
            loop = asyncio.new_event_loop()
            asyncio.set_event_loop(loop)
            return asyncio.get_event_loop()

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

I’m currently experiencing the same issue! Is there already a fix?

I also have a very similar issue. The simplest way to reproduce it is to run a streamlit app (streamlit run <your_streamlit_app_file_name>.py) with the following code:

import nest_asyncio
nest_asyncio.apply()

This results in:

RuntimeError: There is no current event loop in thread 'ScriptRunner.scriptThread'.

Stack trace:

File "[...]/lib/python3.7/site-packages/streamlit/ScriptRunner.py", line 322, in _run_script
    exec(code, module.__dict__)
File "[...]/<your_streamlit_app_file_name>.py", line 15, in <module>
    nest_asyncio.apply()
File "[...]/lib/python3.7/site-packages/nest_asyncio.py", line 9, in apply
    loop = loop or asyncio.get_event_loop()
File "[...].pyenv/versions/3.7.3/lib/python3.7/asyncio/events.py", line 644, in get_event_loop
    % threading.current_thread().name)