'Deribit Python API ; websocket only returns 1 valid message

I've connected to the Deribit websocket for option data, but the following code snippet only gets one valid response of data, and then stops updating, but says it's still running.

The website recommends using the asyncio module, but was able to pull data using below code snippet. I would like to be able to stream data continuously.

import json
import websocket

def on_open(ws):
    msg = {
      "jsonrpc" : "2.0",
      "id" : 8106,
      "method" : "public/ticker",
      "params" : {
        "instrument_name" : "BTC-28JAN22-45000-C",
        "depth" : 1
      }
    }

    ws.send(json.dumps(msg))
    print('opened')

def on_error(ws, msg):
    print('error')
    print(msg)

def on_message(ws, msg):
    d = json.loads(msg)
    print(d)

def on_close(ws):
    print("closed connection")        

socket='wss://www.deribit.com/ws/api/v2/public/get_order_book'
ws = websocket.WebSocketApp(
    socket, 
    on_error=on_error,
    on_open=on_open, 
    on_message=on_message, 
    on_close=on_close)
ws.run_forever()


Solution 1:[1]

You need to introduce the asyncio event loop into your code. I highly recommend this tutorial to get quickly up to speed with asyncio event loops and specifically the run_forever() method which is most relevant here.

You can run the code below which will demonstrate how the loop is calling the server to get "continuous" prices for the BTC-PERPETUAL order book and can modify it for other products:

import asyncio
import websockets
import json

async def call_dapi():

    # connect to the api
    async with websockets.connect('wss://test.deribit.com/ws/api/v2') as websocket:

        # once connected run while connected loop
        while True:

            # send parameter request message 
            msg = {"jsonrpc": "2.0", "method": "public/get_order_book", "id": 1, "params": {"instrument_name": "BTC-PERPETUAL"}, "depth": "5"}
            await websocket.send(json.dumps(msg))

            # wait to receive message and print
            response = await websocket.recv()
            response = json.loads(response)
            print(response)

            # timer to avoid too many requests error
            await asyncio.sleep(1)

asyncio.ensure_future(call_dapi())
asyncio.get_event_loop().run_forever()

A few things to note are that we are using await asyncio.sleep(1) at the end of the task because there is a limit on the number of requests you can make to the server as specified in the deribit docs. With await asyncio.sleep(1) the limit is 1 second but one can reduce that to 0.05 seconds for faster price refresh.

Finally, i'm using websockets library as opposed to what you are using which is websocket-client which implements WebSocketApp.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Alex B