sammchardy / python-binance

Binance Exchange API python implementation for automated trading
https://python-binance.readthedocs.io/en/latest/
MIT License
6.06k stars 2.21k forks source link

Basic ThreadedWebsocketManager example doesn't work. #1243

Closed Enebz closed 6 days ago

Enebz commented 2 years ago

Describe the bug Basic example of ThreadedWebsocketManager doesn't work. The console remains empty after long waiting.

To Reproduce Code snippet to reproduce the behavior:

import time

from binance import ThreadedWebsocketManager

api_key = ''
api_secret = ''

def main():

    symbol = 'BNBBTC'

    twm = ThreadedWebsocketManager(api_key=api_key, api_secret=api_secret)
    # start is required to initialise its internal loop
    twm.start()

    def handle_socket_message(msg):
        print(f"message type: {msg['e']}")
        print(msg)

    twm.start_kline_socket(callback=handle_socket_message, symbol=symbol)
    twm.start_depth_socket(callback=handle_socket_message, symbol=symbol)

    twm.join()

if __name__ == "__main__":
   main()

Expected behavior I expected it to work :)

Environment (please complete the following information):

ImWez commented 2 years ago

I have same issue.

I solved using python 3.9 and python-binance==1.0.15 in Virtual Env

Enebz commented 2 years ago

Yes, I figured that doing this was going to make it work, but I'd like to be able to use the latest versions...

Heissluftofen commented 2 years ago

Thank you very much. My bot didn't run since last week because i did some updates. Why on earth did they change something which lead to not working websockets or threats anymore.

Enebz commented 2 years ago

@Heissluftofen What type of bot are you making? I am making a bot too. Maybe we can chat on discord or something?

kolexander commented 2 years ago

I have python-binance==1.0.16 The console remains empty after long waiting too. When I use python-binance==1.0.15 I got Traceback (most recent call last): File "/home/kolex/www/cryptobot/pblastprice.py", line 33, in <module> bsm.start_symbol_ticker_socket(callback=btc_trade_history, symbol='BTCUSDT') File "/home/kolex/.pyenv/versions/3.10.7/lib/python3.10/site-packages/binance/streams.py", line 1288, in start_symbol_ticker_socket return self._start_async_socket( File "/home/kolex/.pyenv/versions/3.10.7/lib/python3.10/site-packages/binance/streams.py", line 1195, in _start_async_socket socket = getattr(self._bsm, socket_name)(**params) File "/home/kolex/.pyenv/versions/3.10.7/lib/python3.10/site-packages/binance/streams.py", line 757, in symbol_ticker_socket return self._get_socket(symbol.lower() + '@ticker') File "/home/kolex/.pyenv/versions/3.10.7/lib/python3.10/site-packages/binance/streams.py", line 346, in _get_socket self._conns[conn_id] = ReconnectingWebsocket( File "/home/kolex/.pyenv/versions/3.10.7/lib/python3.10/site-packages/binance/streams.py", line 62, in __init__ self._queue = asyncio.Queue(loop=self._loop) File "/home/kolex/.pyenv/versions/3.10.7/lib/python3.10/asyncio/queues.py", line 34, in __init__ super().__init__(loop=loop) File "/home/kolex/.pyenv/versions/3.10.7/lib/python3.10/asyncio/mixins.py", line 17, in __init__ raise TypeError( TypeError: As of 3.10, the *loop* parameter was removed from Queue() since it is no longer necessary ^CException ignored in: <module 'threading' from '/home/kolex/.pyenv/versions/3.10.7/lib/python3.10/threading.py'> Traceback (most recent call last): File "/home/kolex/.pyenv/versions/3.10.7/lib/python3.10/threading.py", line 1567, in _shutdown lock.acquire()

Enebz commented 2 years ago

@kolexander

You have to use Python 3.9 to use python-binance 1.0.15.

The reason lies in your error message:

TypeError: As of 3.10, the loop parameter was removed from Queue()

Heissluftofen commented 2 years ago

It depends on what you want to know. I am quit satisfied with my bot. But i made it quick and dirty. More important now is how the market works. At the moment it is quit calm.

Magnus @.***> schrieb am Mo., 26. Sept. 2022, 21:39:

@Heissluftofen https://github.com/Heissluftofen What type of bot are you making? I am making a bot too. Maybe we can chat on discord or something?

— Reply to this email directly, view it on GitHub https://github.com/sammchardy/python-binance/issues/1243#issuecomment-1258528713, or unsubscribe https://github.com/notifications/unsubscribe-auth/A3JCGQMOLCHDFSI3LWKKVFLWAH3YJANCNFSM6AAAAAAQDQYDFM . You are receiving this because you were mentioned.Message ID: @.***>

Sladerix commented 1 year ago

I have same issue.

I solved using python 3.9 and python-binance==1.0.15 in Virtual Env

It pointed me in the right way.... but I noticed that with python-binance==1.0.16 (latest) it does not work anymore. it gives this error.

RuntimeError: Task <Task pending name='Task-27' coro=<Queue.get() running at /Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/asyncio/queues.py:166> cb=[_release_waiter(<Future pendi...1039faf10>()]>)() at /Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/asyncio/tasks.py:416]> got Future <Future pending> attached to a different loop

python 3.9 and python-binance==1.0.15python 3.9 and python-binance==1.0.16python 3.10 and python-binance==1.0.16

viper7882 commented 1 year ago

+1 for me using python 3.10 and python-binance==1.0.16 in Windows 11. It seems like this issue has been discovered quite a long while but nobody is looking into it. Does @Enebz expect all users not to move on to the latest versions?

Enebz commented 1 year ago

If you want to look into it, go ahead. I provided a temporary way to work with the library, I am not interested in working to patch this issue.

chan1919 commented 1 year ago

The same problem,how to fix the bug with lastest version of Python and python-binance.

WonniPooh commented 8 months ago

Was able to fixed that issue by:

replaced self._handle_read_loop = self._loop.call_soon_threadsafe(asyncio.create_task, self._read_loop()) to self._handle_read_loop = asyncio.create_task(self._read_loop()) in a file binance/streams.py, line 98

Full description -

I did some kind of research, and what I've come to:

First I allowed debug output for websocket, which is created in file binance/streams.py, line 87

adding

logging.basicConfig(
    format="%(message)s",
    level=logging.DEBUG,
)

It allowed to verify that WS itself works fine, it receives data successfully, so seems it is a processing problem; Processing is done by function async def _read_loop(self) of same file, so seems like it is never actually called;

I replaced self._handle_read_loop = self._loop.call_soon_threadsafe(asyncio.create_task, self._read_loop()) to self._handle_read_loop = asyncio.create_task(self._read_loop()) and from that moment it worked fine for me.

Now lets try to understand if this change will affect the logic - _read_loop task is created by async def connect function, which is only called by async def __aenter__(self) function;

Lets assume I want to sub to all prices update, and lets follow the flow:

market_ws_client = ThreadedWebsocketManager()
market_ws_client.daemon = True
market_ws_client.start()
market_ws_client.start_all_mark_price_socket(callback=cb)

start_all_mark_price_socket calls _start_async_socket, which creates socket by calling socket = getattr(self._bsm, socket_name)(**params)

However, that created socket is started by calling self._loop.call_soon_threadsafe(asyncio.create_task, self.start_listener(socket, socket_path, callback))

start_listener function calls async with socket as s which actually runs __aenter__ method mentioned above.

So actually __aenter__ is already called from inside of self._loop of ThreadedApiManager.

And self._loop should always be actually brand new event loop - please look at my other comment

Hope I haven't done any logical mistakes and hope it will help someone!