New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
RuntimeError: There is no current event loop in thread error with Streamlit and Asyncio #744
Comments
@jroakes Can you provide a mini-repro, that is, a complete Streamlit app and command line? Streamlit uses Tornado and it is likely conflicting with you trying to get an event loop in
by using |
Closing this. Please reopen if you have more data to help us debug. |
I'm running into the same problem. My code has a button that when clicked creates an HTMLSession which goes to Google to search for some content available only when the page gets rendered. |
I also have a very similar issue. The simplest way to reproduce it is to run a
This results in:
Stack trace:
|
I'm currently experiencing the same issue! Is there already a fix? |
I'm receiving this error as well.
|
Same... we do a DB query (
cc @spmallette wrt apache/tinkerpop#1212 |
@tvst Are you still having issues reproducing, e.g., starting nest_asyncio? |
I'm experiencing this as well, using an internal API client that's using nest_asyncio. I'm able to reproduce the error with:
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:
|
same problem when importing holoviews.. nothing special, just a simple import ..
|
Same problem with ib_insync and streamlit 1.1
Error-stack:
|
confirmed streamlit isn't working with ib_insync (0.9.70). from ib_insync import IB
import streamlit as st produces error-stack: 2021-12-06 10:42:49.353 Traceback (most recent call last):
File "/Users/me/opt/miniconda3/envs/trading/lib/python3.9/site-packages/streamlit/script_runner.py", line 350, in _run_script
exec(code, module.__dict__)
File "/Users/me/pysystemtrade/private/streamlit_app/app.py", line 1, in <module>
from ib_insync import IB
File "/Users/me/opt/miniconda3/envs/trading/lib/python3.9/site-packages/ib_insync/__init__.py", line 6, in <module>
from eventkit import Event
File "/Users/me/opt/miniconda3/envs/trading/lib/python3.9/site-packages/eventkit/__init__.py", line 4, in <module>
from .event import Event
File "/Users/me/opt/miniconda3/envs/trading/lib/python3.9/site-packages/eventkit/event.py", line 7, in <module>
from .util import NO_VALUE, main_event_loop
File "/Users/me/opt/miniconda3/envs/trading/lib/python3.9/site-packages/eventkit/util.py", line 18, in <module>
main_event_loop = asyncio.get_event_loop()
File "/Users/me/opt/miniconda3/envs/trading/lib/python3.9/asyncio/events.py", line 642, in get_event_loop
raise RuntimeError('There is no current event loop in thread %r.'
RuntimeError: There is no current event loop in thread 'ScriptRunner.scriptThread'. |
Actually, ib_insync also depends on asyncio; is there a broader incompatibility between asyncio and streamlit? That would really limit the number of applications that can use streamlit, surely? |
I'm also running into the same problem attempting to use ib_insync in streamlit. I ran across the following gist which seems to give some hints but I am unable to find the magic to get this working in streamlit based on this example. https://gist.github.com/jwsmithers/0575fc78f9d54a93988ad29300dfe4b7 |
I can also reproduce this error... Primary environment is: ...but error also occurs using: Steps to reproduce:
Ideas anyone? How can we get these 2 asyncio-dependent packages.. in sync? Edit 1: datotalk's workaround works! #744 (comment)
Edit 2: It didn't really work - the errors went away but the app doesn't work at all (seems to hang). The ib_insync docs have code recipes to make ib_insync work with threaded and non-threaded apps https://ib-insync.readthedocs.io/recipes.html I like the library, but this seems to be a lot of working around just to have it play nice. For now I've settled for using https://pypi.org/project/ib/ which works well - not as simple as ib_insync but some helper functions can bring it on par. Hopefully someone on the streamlit team will pick this issue up and come up with a remedy, but I'm sure this will require some collab with the keeper of ib_insync @erdewit https://github.com/erdewit |
@d416 what version are you using? I tried your minimal example and got the same errors as before: test.py
streamlit run test.py
|
I'm getting this same error when trying to use HTMLSession() from requests_html. The application works fine as a simple python program, but adding in |
@im-keiran ib_insync is certainly easier to use, and I'm sure someone could get Streamlit to work with it with a great deal of debugging, but this was beyond the scope of my own personal project. |
Same problem here. And that creates the problems mentioned above in the following lines of nest_asyncio File "/opt/conda/lib/python3.9/site-packages/..... .... name.py", line 12, in |
At least is it know wh there is this conflict streamlit vs asyncio? |
I ran into the same issue while using asyncio. Solved by implementing a helper module from this stack overflow reply. |
Add this code before import ib_insync:
|
@Anton-Filimoncev 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 = get_or_create_eventloop()
asyncio.set_event_loop(loop) |
This is probabaly also a neat solution from the community forum for this kind of issues: https://discuss.streamlit.io/t/deploy-sketch-on-streamlit/40434/2 Here the code snippet from the forum thread as reference, it deals with the import asyncio
from contextlib import contextmanager
import streamlit as st
# Create a context manager to run an event loop
@contextmanager
def setup_event_loop():
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
try:
yield loop
finally:
loop.close()
asyncio.set_event_loop(None)
# Use the context manager to create an event loop
with setup_event_loop() as loop:
import sketch
# Now you can use the 'sketch' library in your Streamlit app
st.write("The 'sketch' library has been successfully imported.") |
For those who may have missed it, this solution #744 (comment) was posted by the maintainer of ib_insync It sort of works, but not well enough for me that I've moved on from getting streamlit (1.3.1) to work with ib_insync (0.9.81).
import ib_insync
import streamlit as st
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 = get_or_create_eventloop()
asyncio.set_event_loop(loop)
from ib_insync import *
ib = IB()
ib.connect('127.0.0.1', 7497,clientId=1)
contract = Forex('EURUSD')
bars = ib.reqHistoricalData(
contract, endDateTime='', durationStr='2 D',
barSizeSetting='1 hour', whatToShow='MIDPOINT', useRTH=True)
df = util.df(bars)
st.dataframe(df) |
To add an "initialize" button before the ib.connect('127.0.0.1', 7497, clientId=1) line to prevent repeated connections that may lead to the "clientId already in use" issue, you can do the following:
|
This solution is not working anymore, is there any update on this? |
Having same problems, streamlit should support async data sources out of the box in my not very humble opinion.
Known problems for now:
So with that said, very ugly workaround that I found working best for now: @st.cache_resource(show_spinner=False)
def get_event_loop():
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
return loop
if not st.session_state.get("event_loop"):
st.session_state["event_loop"] = get_event_loop() then pass that event loop wherever your data is coming from, here is motor example: async def setup_db(force=False):
if force or not st.session_state.get("db_client"):
with st.spinner("Loading..."):
client = AsyncIOMotorClient(
os.environ["MONGODB_URI"],
tls=MONGODB_TLS,
io_loop=st.session_state["event_loop"],
)
st.session_state["db_client"] = await init_database(client=client)
return client init_database is a call to beanie's init database I understand that making the entire framework async would require too much work and would prb confuse the ML/AI crowd too much, but streamlit is such a gorgeous framework, the only place it fails in misery is the async |
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 errorRuntimeError: There is no current event loop in thread 'ScriptRunner.scriptThread'
.Steps to reproduce
What are the steps we should take to reproduce the bug:
Expected behavior:
Load RenderHTML class, launch chrome, and build a new browser page.
Actual behavior:
With: nest_asyncio.apply()
Without: nest_asyncio.apply()
Is this a regression?
That is, did this use to work the way you expected in the past? IDK
yes / no
Debug info
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!
The text was updated successfully, but these errors were encountered: