python-binance icon indicating copy to clipboard operation
python-binance copied to clipboard

There is something wrong with the new version threading v1.0.16

Open saeedsamie opened this issue 3 years ago • 17 comments
trafficstars

I update my python-binance lib version to v1.0.16 and suddenly this error came up.

Traceback (most recent call last): File "C:\Users\saeed\AppData\Local\Programs\Python\Python38\lib\site-packages\binance\threaded_stream.py", line 46, in start_listener msg = await asyncio.wait_for(s.recv(), 3) File "C:\Users\saeed\AppData\Local\Programs\Python\Python38\lib\asyncio\tasks.py", line 483, in wait_for return fut.result() File "C:\Users\saeed\AppData\Local\Programs\Python\Python38\lib\site-packages\binance\streams.py", line 197, in recv res = await asyncio.wait_for(self._queue.get(), timeout=self.TIMEOUT) File "C:\Users\saeed\AppData\Local\Programs\Python\Python38\lib\asyncio\tasks.py", line 483, in wait_for return fut.result() File "C:\Users\saeed\AppData\Local\Programs\Python\Python38\lib\asyncio\queues.py", line 163, in get await getter RuntimeError: Task <Task pending name='Task-10' coro=<Queue.get() running at C:\Users\saeed\AppData\Local\Programs\Python\Python38\lib\asyncio\queues.py:163> cb=[_release_waiter(<Future pendi...151A77310>()]>)() at C:\Users\saeed\AppData\Local\Programs\Python\Python38\lib\asyncio\tasks.py:429]> got Future <Future pending> attached to a different loop

@sammchardy Is it caused by my code or this is a bug?

saeedsamie avatar Apr 09 '22 10:04 saeedsamie

I got the same error too. Here is code to reproduce the error, it's works with v1.0.15.

python version: 3.8.0 python-binance: 1.0.16

from binance import Client, ThreadedWebsocketManager


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


twm = ThreadedWebsocketManager()
twm.start()
twm.start_kline_socket(callback=handle_socket_message, symbol='BNBBTC')
twm.join()

jef0525 avatar Apr 09 '22 16:04 jef0525

same error here when I use start_futures_user_socket() right after I upgrade to 1.0.16.

jiancongs avatar Apr 10 '22 07:04 jiancongs

This error seems only thrown on python < 3.10. However, on 3.10, the threaded socket just hang there without any message processed.

I believe a quick fix could be done by set threaded event loop to the OS one:

https://github.com/sammchardy/python-binance/blob/master/binance/threaded_stream.py#L19

class ThreadedApiManager(threading.Thread):

    def __init__(
        self, api_key: Optional[str] = None, api_secret: Optional[str] = None,
        requests_params: Optional[Dict[str, str]] = None, tld: str = 'com',
        testnet: bool = False
    ):
        """Initialise the BinanceSocketManager
        """
        super().__init__()
        self._loop: asyncio.AbstractEventLoop = asyncio.new_event_loop()  # <-------- change this to `asyncio.get_event_loop()`
        self._client: Optional[AsyncClient] = None
        self._running: bool = True
        self._socket_running: Dict[str, bool] = {}
        self._client_params = {
            'api_key': api_key,
            'api_secret': api_secret,
            'requests_params': requests_params,
            'tld': tld,
            'testnet': testnet
        }

Hope someone could test this fix and open a pull request since I don't use threaded socket.

halfelf avatar Apr 11 '22 06:04 halfelf

@halfelf suggestion worked for issue #1172 , thanks.

MoeQatoum avatar Apr 20 '22 20:04 MoeQatoum

Same on my side. Went to my old machine that has an old installation and the code works but fails on the latest. Python 3.9

thisismygitrepo avatar May 01 '22 00:05 thisismygitrepo

tried @halfelf solution but when running two sockets got another problem

self.tdcm = ThreadedDepthCacheManager()
        self.twsm= ThreadedWebsocketManager()
        self.twsm.start()
        self.tdcm.start()

RuntimeError: This event loop is already running

any work around?

Kncokoff avatar May 15 '22 19:05 Kncokoff

any work around?

pip install python-binance==1.0.15

mikkokotila avatar May 26 '22 20:05 mikkokotila

Any news?! Still not working and it makes the module kinda useless (((

alxkos avatar May 27 '22 16:05 alxkos

Since lots of attention to this thread, it comes to me that I have to say, one can always try the coroutine way, which should be a better solution for python. Threaded socket is hard to maintain and causes much trouble in several releases.

For anyone with skilled python programming, I have a forked and modified version of this module, working only in trio event loop.

halfelf avatar May 28 '22 17:05 halfelf

any work around?

pip install python-binance==1.0.15

same issue on 1.0.15 and 1.016 as well

curiouscod3 avatar Jun 29 '22 20:06 curiouscod3

@halfelf solution worked on my machine Ubuntu 21.10

slikdijit avatar Aug 04 '22 23:08 slikdijit

For this problem in my own code I changed the async websocket method to Thread. I hope it works.

from binance.client import Client
from helpers import socket_parser
from threading import Thread
from time import sleep
import binance
import asyncio


# ignore
from logic.exchange.streams.helpers import kline_stream_formatter
from api import request


class WebSocket:
    def __init__(self, client) -> None:
        self.client = client
        self.klines = dict()

    async def kline_async(self, socket: str, limit: int = 40):
        symbol, interval = socket_parser(socket)
        klines = self.client.futures_klines(symbol=symbol, interval=interval, limit=limit)
        value = request('/klines', 'post', value=f'/{socket}', json=klines)  # ignore
        async_client = await binance.AsyncClient.create()
        bm = binance.BinanceSocketManager(async_client)
        ts = bm.futures_multiplex_socket(streams=[socket])
        self.klines[socket] = True
        async with ts as tscm:
            while self.klines[socket]:
                res = await tscm.recv()
                kline_stream_formatter(res)  # ignore 
        await async_client.close_connection()

    def kline(self, **kwargs):
        loop = asyncio.new_event_loop()
        asyncio.set_event_loop(loop)
        loop.run_until_complete(self.kline_async(**kwargs))
        loop.close()

    def kline_thread(self, **kwargs):
        Thread(target=self.kline, kwargs=kwargs).start()

    def kline_close(self, socket:str):
        self.klines[socket]=False


ws = WebSocket(Client())
ws.kline_thread(socket="btcusdt@kline_1m", limit=50)

sleep(15)# for thread still running
ws.kline_close(socket="btcusdt@kline_1m")

qraxiss avatar Sep 17 '22 18:09 qraxiss

I have the same problem. Is there any solution or update?

sinaqahremani avatar Jan 11 '23 06:01 sinaqahremani

It is really shameful. They updated the library 9 months ago, and still it has bugs.

sinaqahremani avatar Jan 11 '23 08:01 sinaqahremani

@sinaqahremani

  • 9 months is forever in Python terms.
  • As you can see, there are almost 500 reported bugs. So, if you are just getting started, it is highly recommended not to use this library as it's undermaintained. Go for the official binance-connector by binance.
  • If you have already used it heavily, then opt for the simple solution of reverting to python 3.9 and python-binance 1.0.15.

thisismygitrepo avatar Jan 11 '23 08:01 thisismygitrepo

@thisismygitrepo Thank you Alex,

If someone from the team is available and can help me just by answering basic questions, I can work voluntarily on this bug. Actually, we have used this library since 2021. Moreover, I need to use start_futures_user_socket which is available in 1.0.16.

sinaqahremani avatar Jan 11 '23 08:01 sinaqahremani

@sinaqahremani

I don't think there is a "team". And the license has declared clearly there is no liability or warranty this SDK works as anyone expects.

Back to this perticular issue, as I said before, forget about threads and switch to pure async codes is the pythonic way and best shot.

This codes of this library, IMHO, have been organized very well, for both reading and writing with. It won't be a big trouble to fix this bug. As you can see, it has been located and there is a way to fix it (just need some additional effort to make it work with multiple websockets.)

@thisismygitrepo

I almost read every issue from time to time. At least 95% of them are not bugs, but programming issues suitable for stackoverflow.

halfelf avatar Jan 11 '23 08:01 halfelf