Search code examples
pythonpython-asyncio

Python asyncio streams: No stop byte


While I was writing a program that sends and receive some JSON from a service, I stumbled upon a challenge. The server doesn't send a stop-byte (not going to lie, took me a few hours to realize it), it's just byte-by-byte JSON. Not even single quotes.

I was looking for an elegant solution before giving up and doing a while loop that keeps adding byte by byte in a buffer and checking if it's a valid JSON.

Has anyone ever had to deal with something similar?


Solution

  • The problem was solved by reading byte by byte and adding it to a buffer. Every time I read a byte, I check if the buffer is a valid JSON.

    def is_json(string: str) -> bool:
        try:
            json.loads(string)
        except ValueError as e:
            return False
        return True
    
    
    class MyClient:
    # ... my implementation of asyncio's client streams using OOP...
    
        async def receive(self) -> str:
        # Method used to read data from the server
            msg = ''
            while self.connected:
                data = await self.reader.read(1)
                log.debug(f"Read: {data}")
                msg = msg + data.decode()
                if is_json(msg):
                    log.info(f"Received: {msg}")
                    return msg
            log.warning(f"Client disconnected!")
    

    Hope this helps someone.

    Also, if you have a better/more elegant alternative, please, share.