How can I access data which is returned by a websocket in Python?

Viewed 3076

This question still has my attention. I edited it a bit to maybe attract more problem-solvers ;)

I am currently trying to set up a websocket connection to fetch data from a third party. The connection is set up and runs just well.

However, I am not able to access and use the returned data finally... How can I do this?

My code:

# Websocket Endpoint
socket = 'wss://data.alpaca.markets/stream'

# Websocket authentication dictionary
socket_login_message = {
    "action": "authenticate",
    "data": {
        "key_id": key,
        "secret_key": secret_key
    }
}

# Open Connection
ws = create_connection("wss://data.alpaca.markets/stream")

# Convert dictionary to str -> bytes object to transfer it via websocket
sck_login_credentials = json.dumps(socket_login_message).encode('utf-8')

# Send the credentials over the socket
ws.send(sck_login_credentials)

# Check if connected
result = ws.recv()
print(result)

# Define Stocks to listen
listen_stocks = {
    "action": "listen",
    "data": {
        "streams": ["Q.AAPl", "Q.CMRE", "Q.PLOW"]
    }
}

# Convert dictionary to str -> bytes object to transfer it via websocket
sck_listen_quotes = json.dumps(listen_stocks).encode('utf-8')

# Initialize Listen Process
ws.send(sck_listen_quotes)

# grab response
quotes_response = ws.recv()

# Decode bytes object again
response_str = json.loads(quotes_response)

print(type(quotes_response))
# Prints <class 'str'>

print(type(response_str))
# Prints <class 'dict'>

print(response_str)
# Prints {'stream': 'listening', 'data': {'streams': ['Q.AAPl', 'Q.CMRE', 'Q.PLOW']}}

# Now how to get the data of each stock in streams dict?!

The transferred structure for each stream according to the documentation of the third party is as follows:

{
  "ev": "Q",
  "T": "APPL",
  "x": 17,
  "p": 283.35,
  "s": 1,
  "X": 17,
  "P": 283.4,
  "S": 1,
  "c": [
    1
  ],
  "t": 1587407015152775000
}

So how can I assign e.g. T to the variable symbol for each item in streams?

2 Answers

Use json.loads()

# to load the JSON and convert it to a Python dictionary which you can access
response_ = json.loads(str(quotes_response))  # note the str(...), not 
                                              # sure which type this var 
                                              # is but most times str() 
                                              # works

# e.g you want to print out the value of "stream"
print(response_['stream'])   # output: listening

Note, it's important that quotes_response is a string if you do json.loads(quotes_response)

Okay, second try haha. So if I understand correctly what you're saying you want to give the variable symbol the value of t for each item in the list streams?

But I'm not sure if you want to add these values to a list or a string. I assume you want to work with one value at a time and than reset the value of symbol to ''. If you want to do so a simple for statement should solve your problem.

your_dictionary = {'ev': 'Q', 'T': 'APPL', 'x': 17, 'p': 283.35, 's': 1, 'X': 17, 'P': 283.4, 'S': 1, 'c': [1], 't': 1587407015152775000}

# I'm not sure if in this case str stands for string or stream, but if it stands for string note this is not a string but a dictionary
response_str = {'stream': 'listening', 'data': {'streams': ['Q.AAPl', 'Q.CMRE', 'Q.PLOW']}}

symbol = ''

for item in response_str['data']['streams']:
   symbol = item
   # do your stuff with the variable here

I also noticed in the code of your question is a line saying:

# Decode bytes object again
response_str = json.loads(quotes_response)

But the json.loads doesn't decode bytes it just converts JSON data into a python dictionary. Also I read a WS doc where it seems like ws.recv() is returning a string. Otherwise just do the following to decode the bytes into a string.

response_str = quotes_response.decode() # if this uses a special encoding you should check if python does support this encoding and than type .decode(TheEncoding)

Maybe you could add the link to the third party docs so it's easier t understand how this is supposed to work.

If I misinterpreted the question please let me know

Related