question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Async Read Stream Data from buffer

See original GitHub issue

Hello,

I went through the documentation and examples how to read data from the stream, and I would like to ask a question.

I found out there is the function pop_stream_data_from_stream_buffer and I saw data can be read from the stream with this snippet:

    msg = bwsm.pop_stream_data_from_stream_buffer(book_ticker_id)
    if msg:
        book_ticker(msg)
    msg = bwsm.pop_stream_data_from_stream_buffer(user_stream_id)
    if msg:
        order_status(msg)
    time.sleep(0.01)

Would it be possible to read the data in an asynchronous way without doing the “time.sleep” ?

Thank you 😃

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:25 (9 by maintainers)

github_iconTop GitHub Comments

3reactions
jon4hzcommented, Feb 3, 2021

Hoi @brianmori

I was working on a script to use UBWA in combination with asyncio but truth be told, I’m not an expert on asyncio so I am really not sure if it’s best practice. I was playing around with the following code:

from __future__ import print_function
from unicorn_binance_websocket_api.unicorn_binance_websocket_api_manager import BinanceWebSocketApiManager
import threading, os, time, asyncio


binance_websocket_api_manager = BinanceWebSocketApiManager(exchange="binance.com")


async def print_stream_data_from_stream_buffer(binance_websocket_api_manager):
    print("waiting 5 seconds, then we start flushing the stream_buffer")
    await asyncio.sleep(5)
    while True:
        if binance_websocket_api_manager.is_manager_stopping():
            exit(0)
        oldest_stream_data_from_stream_buffer = binance_websocket_api_manager.pop_stream_data_from_stream_buffer()
        if oldest_stream_data_from_stream_buffer is False:
            await asyncio.sleep(0.01)
        else:
            try:
                print(oldest_stream_data_from_stream_buffer)

            except Exception as e:
                # Any kind of error...
                # not able to process the data? write it back to the stream_buffer
                print(f"Error: {e}")
                binance_websocket_api_manager.add_to_stream_buffer(oldest_stream_data_from_stream_buffer)


def run_socket_function(loop, binance_websocket_api_manager):
    # set the event loop and execute it
    asyncio.set_event_loop(loop)
    loop.run_until_complete(print_stream_data_from_stream_buffer(binance_websocket_api_manager))


if __name__ == "__main__":
    # create event loop
    loop = asyncio.new_event_loop()
    
    # subscripe to the socket
    binance_websocket_api_manager.create_stream('miniTicker', 'BTCUSDT', output='dict')

    # start a worker process to process to move the received stream_data from the stream_buffer to a print function
    worker_thread = threading.Thread(target=run_socket_function, args=(loop, binance_websocket_api_manager))
    worker_thread.start()
    time.sleep(5)
2reactions
jon4hzcommented, Mar 24, 2021

That’s the same reason I wrote my async code, haha. But I don’t think that you can use an async function as a callback. However you can use a “normal” function as callback to add the ingestion function as a coroutine to the event loop.

from unicorn_binance_websocket_api.unicorn_binance_websocket_api_manager import BinanceWebSocketApiManager
import asyncio


async def ingestion(stream_data, stream_buffer_name=False):
    # filter of events
    print(stream_data)


def callback(stream_data, stream_buffer_name=False): 
    asyncio.ensure_future(ingestion(stream_data, stream_buffer_name))


async def main():
    bsm = BinanceWebSocketApiManager(exchange="binance.com", process_stream_data=callback)
    channels = ['trade', 'kline_1m']
    markets = ['bnbusdt', 'wtcusdt']
    bsm.create_stream(channels, markets, output='dict')
    


if __name__ == "__main__":
    loop = asyncio.new_event_loop()
    loop.run_until_complete(main())
Read more comments on GitHub >

github_iconTop Results From Across the Web

How to use ES8 async/await with streams? - Stack Overflow
async / await only works with promises, not with streams. There are ideas to make an extra stream-like data type that would get...
Read more >
Reading streams via async iteration in Node.js - 2ality
In this section, we examine two ways of reading data from a stream asynchronously: via callbacks and via asynchronous iteration.
Read more >
Streams and how they fit into Node.js async nature.
Since it acts as a readable and writable stream, internally it maintains two buffers, one for reading date and another one for writing...
Read more >
Understanding Streams in Node.js | NodeDev
You can use async iterator when reading from readable streams: ... The read() function reads some data from the internal buffer and returns...
Read more >
Stream | Node.js v19.3.0 Documentation
Two reading modes; Three states; Choose one API style; Class: stream.Readable ... Both Writable and Readable streams will store data in an internal...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found