0

I want to build a tiny REST api server returning the last 100 trades listened on Binance exchange websocket. I start the app with uvicorn but the json returned is '{}'. The listening of the websocket works if i execute the program with normal python command I want to have a standalone server that both respond to REST requests and listen to Binance's websocket.

This is my code:

import websocket
import json
import time
import uvicorn


app = FastAPI()
last_trade = []

def on_message(ws, message):
    global last_trade
    data = json.loads(message)
    if 'e' in data and data['e'] == 'trade':
        last_trades += data
        if len(last_trade) > LASTS:
            last_trade.pop(0)  
             
        # print(data)


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

def on_close(ws):
    print("Connexion fermée")
    reconnect()

def on_open(ws):
    ws.send(json.dumps({
        "method": "SUBSCRIBE",
        "params": ["btctusd@trade"],
        "id": 1
    }))

def reconnect():
    delay = 5  # Délai de reconnexion en secondes
    print(f"Reconnexion dans {delay} secondes...")
    time.sleep(delay)
    connect_to_binance_websocket()

def connect_to_binance_websocket():
    websocket_url = "wss://stream.binance.com:9443/ws"
    ws = websocket.WebSocketApp(websocket_url,
                                on_message=on_message,
                                on_error=on_error,
                                on_close=on_close)
    ws.on_open = on_open
    ws.run_forever()

@app.get("/")
async def root():
    return json.dumps(last_trade)



LASTS=100
if __name__ == '__main__':
    connect_to_binance_websocket()
    uvicorn.run(app, host="0.0.0.0", port=8000)

Thanks
  • If you are starting it using the `uvicorn` cli then the `if __name__ == '__main__':` block never executes. Uvicorn imports the module and access the `app` object. You'll need to find another way to start the websocket server. – larsks Jul 04 '23 at 17:42
  • You might find [this answer](https://stackoverflow.com/a/70873984/17865804) and [this answer](https://stackoverflow.com/a/76148361/17865804) helpful – Chris Jul 08 '23 at 05:11

1 Answers1

1

you can use on_event decorator with startup on the function that needs to be called after the uvicorn starts

@app.on_event("startup")
def connect_to_binance_websocket():
Prudhviraj
  • 441
  • 3
  • 12