Hello I am trying to display data that I am fetching from Interactive Brokers using ib_insync api.
I am running into some issues, from my troubleshooting and searches I believe it has something to do with asyncio.
I am running the code locally on my machine, ib_insync works well separately and I can print data. Python 3.9.6; streamlit==1.32.2
This is the error I get:
RuntimeError: There is no current event loop in thread ‘ScriptRunner.scriptThread’.
The problem is reported on github as well, somebody provided a solution but that does not work anymore.
opened 06:28PM - 25 Nov 19 UTC
type:bug
status:confirmed
priority:P3
area:server
# 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](https://github.com/erdewit/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!
from ib_insync import *
import streamlit as st
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)
Only requirements used are ib_insync and streamlit.
The I tried the solution from github and I get the exact same error:
from ib_insync import *
import asyncio
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)
ib = IB()
ib.connect('127.0.0.1', 7497,clientId=1)
contract = Crypto('BTC', 'PAXOS')
ib.qualifyContracts(contract)
bars = ib.reqHistoricalData(
contract, endDateTime='', durationStr='2 D',
barSizeSetting='1 hour', whatToShow='MIDPOINT', useRTH=True)
df = util.df(bars)
st.dataframe(df)
Hi @dreamless2871 and welcome to our community!
Just wondering - have you tried using st.cache_resource to manage the asyncio event loop and cache the async IB data fetching process?
Best,
Charly
Charly thank you for your response, I attempted your solution then made me realise by removing most of the lines of the code that it breaks just by importing both modules:
import streamlit as st
from ib_insync import *
Just having these 2 lines in my file breaks things.
I fixed the issue by importing modules in the following exact order:
import streamlit as st
import asyncio
loop = asyncio.new_event_loop()
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)
print(df)
st.dataframe(df)
1 Like
system
Closed
March 30, 2024, 10:26am
6
This topic was automatically closed 2 days after the last reply. New replies are no longer allowed.