3

I want to send audio data over HTTP, but I don't understand why I'm getting this exception:

Exception happened during processing of request from ('127.0.0.1', 59976)
Traceback (most recent call last):
  File "/usr/lib/python3.6/socketserver.py", line 654, in process_request_thread
    self.finish_request(request, client_address)
  File "/usr/lib/python3.6/socketserver.py", line 364, in finish_request
    self.RequestHandlerClass(request, client_address, self)
  File "/usr/lib/python3.6/socketserver.py", line 724, in __init__
    self.handle()
  File "/usr/lib/python3.6/http/server.py", line 418, in handle
    self.handle_one_request()
  File "/usr/lib/python3.6/http/server.py", line 406, in handle_one_request
    method()
  File "/home/vivanov/temp.py", line 113, in do_GET
    data.append(bytearray(stream.read(CHUNK)))
TypeError: 'bytearray' object cannot be interpreted as an integer

The problem seems to have to do with passing values to wfile.write.

How can I resolve the issue?

This is the code I have:

class ChunkingRequestHandler(BaseHTTPRequestHandler):
    ALWAYS_SEND_SOME = False
    ALLOW_GZIP = False
    protocol_version = 'HTTP/1.1'
    def do_GET(self):
        ae = self.headers.get('accept-encoding') or ''

        # send some headers
        self.send_response(200)
        self.send_header('Transfer-Encoding', 'chunked')
        self.send_header('Content-type', 'audio/x-wav')

        self.end_headers()

        data = bytearray(wav_header)
        data.append(bytearray(stream.read(CHUNK)))
        print(data)
        self.wfile.write(b"%X\r\n%s\r\n" % (len(data), data))

        while True:
            data = bytearray(stream.read(CHUNK))
            self.wfile.write(b"%X\r\n%s\r\n" % (len(data), data))

        # send the chunked trailer
        self.wfile.write('0\r\n\r\n')
Dan Getz
  • 8,774
  • 6
  • 30
  • 64
valioiv
  • 393
  • 2
  • 5
  • 15
  • 2
    Please share any code and data necessary to reproduce the problem. – AMC Nov 29 '19 at 20:38
  • I've just put my code in a separate post below because it is a big snippet. – valioiv Nov 29 '19 at 20:51
  • Your error message contains a stack trace. It will tell you what triggered the error. If you look at it, it does not say that calling `wfile.write()` triggered it. Instead, it says you passed a `bytearray` into `data.append()`, and that's the problem. `bytearray`s act like lists, here's [the ordinary operations you can do on lists and bytearrays](https://docs.python.org/3/library/stdtypes.html#typesseq-mutable) – Dan Getz Nov 30 '19 at 15:50
  • @DanGetz , I've added the code I have. – valioiv Dec 01 '19 at 15:56

2 Answers2

9

Despite its name, if you want to append more than one element at a time to a list-like object in Python, you can't use the append method. A bytearray acts like a list of bytes, so the way to append or concatenate another bytearray onto it is with the extend method, or +=:

data += bytearray(...)
#  OR
data.extend(bytearray(...))

In fact, if whatever you're adding to your bytearray is already something that can be passed into the bytearray() constructor, you likely don't need to wrap it in a bytearray(). For example, bytes objects (like b'something') can be added directly:

data += b'something'

Once you fix that line of your code, you may have problems on other lines. For example, if wfile.write takes bytes, then sending it a unicode string like '0\r\n\r\n' will probably error; it looks like you meant to write b'0\r\n\r\n'.

Dan Getz
  • 8,774
  • 6
  • 30
  • 64
3

Actually this is the final code I end up working, might be useful for someone:

class ChunkingRequestHandler(BaseHTTPRequestHandler):
    ALWAYS_SEND_SOME = False
    ALLOW_GZIP = False
    protocol_version = 'HTTP/1.1'
    def do_GET(self):
        ae = self.headers.get('accept-encoding') or ''

        # send some headers
        self.send_response(200)
        self.send_header('Content-type', 'audio/x-wav')

        self.end_headers()

        data = []
        for i in wav_header:
            data.append(int(i))
        for i in stream.read(CHUNK):
            data.append(int(i))
        self.wfile.write(bytearray(data))

        while True:
            data = []
            for i in stream.read(CHUNK):
                data.append(int(i))
            self.wfile.write(bytearray(data))

        # send the chunked trailer
        self.wfile.write('0\r\n\r\n')
valioiv
  • 393
  • 2
  • 5
  • 15