Reputation: 17
I'm having problems with a bytes encoding problem and hoping for help please as stuck (python beginner, trying to adapt some code from github to python3). I 'think' the issue is that I need to encode the 'data' variable to bytes, however I'm struggling to do so as .encode() isn't working. The error returned is:
Traceback (most recent call last):
File "C:/Users/DR/Desktop/iqfeed3.py", line 51, in <module>
data = read_historical_data_socket(sock)
File "C:/Users/DR/Desktop/iqfeed3.py", line 21, in read_historical_data_socket
buffer += data
TypeError: can only concatenate str (not "bytes") to str
The underlying code (which attempts to buffer stock price data and write to csv) is below (highlighted lines 21 & 51 with comments):
# iqfeed3.py
import sys
import socket
# iqfeed3.py
def read_historical_data_socket(sock, recv_buffer=4096):
"""
Read the information from the socket, in a buffered
fashion, receiving only 4096 bytes at a time.
Parameters:
sock - The socket object
recv_buffer - Amount in bytes to receive per read
"""
buffer = ""
data = ""
while True:
data = sock.recv(recv_buffer)
buffer += data #TRACEBACK ERROR LINE 21
# Check if the end message string arrives
if "!ENDMSG!" in buffer:
break
# Remove the end message string
buffer = buffer[:-12]
return buffer
if __name__ == "__main__":
# Define server host, port and symbols to download
host = "127.0.0.1" # Localhost
port = 9100 # Historical data socket port
syms = ["AAPL", "GOOG", "AMZN"]
# Download each symbol to disk
for sym in syms:
print ("Downloading symbol: %s..." % sym)
# Construct the message needed by IQFeed to retrieve data
message = "HIT,%s,60,20180601 075000,,,093000,160000,1\n" % sym
# Open a streaming socket to the IQFeed server locally
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((host, port))
# Send the historical data request
# message and buffer the data
sock.sendall(message.encode()) #Formerly gave error "TypeError: a bytes-like object is required, not 'str'" before adding .encode()
data = read_historical_data_socket(sock) #TRACEBACK ERROR LINE 51
sock.close
# Remove all the endlines and line-ending
# comma delimiter from each record
data = "".join(data.split("\r"))
data = data.replace(",\n","\n")[:-1]
# Write the data stream to disk
f = open("%s.csv" % sym, "w")
f.write(data)
f.close()
Thanks in advance for any help or pointers.
Dean
Upvotes: 1
Views: 535
Reputation: 8646
You are confusing strings and raw bytes. Your buffer
is a string, while socket input is normally bytes
.
Best approach is simply convert received bytes into string.
Try this code:
data = sock.recv(recv_buffer)
buffer += data.decode()
This will use default utf-8
encoding. If you want another, specify it explicitly.
Upvotes: 3