def _write_file_via_webrepl_file_protocol(
        self,
        source: BinaryIO,
        target_path: str,
        file_size: int,
        callback: Callable[[int, int], None],
    ) -> None:
        """
        Adapted from https://github.com/micropython/webrepl/blob/master/webrepl_cli.py
        """
        assert isinstance(self._connection, WebReplConnection)

        dest_fname = target_path.encode("utf-8")
        rec = struct.pack(WEBREPL_REQ_S, b"WA", WEBREPL_PUT_FILE, 0, 0,
                          file_size, len(dest_fname), dest_fname)
        self._write(WebreplBinaryMsg(rec[:10]))
        self._write(WebreplBinaryMsg(rec[10:]))
        assert self._read_websocket_response() == 0

        bytes_sent = 0
        callback(bytes_sent, file_size)
        while True:
            block = source.read(1024)
            if not block:
                break
            self._write(WebreplBinaryMsg(block))
            bytes_sent += len(block)
            callback(bytes_sent, file_size)

        assert self._read_websocket_response() == 0

        return bytes_sent
    def _read_file_via_webrepl_file_protocol(self, source_path: str,
                                             target_fp: BinaryIO,
                                             callback: Callable[[int, int],
                                                                None]):
        """
        Adapted from https://github.com/micropython/webrepl/blob/master/webrepl_cli.py
        """
        assert isinstance(self._connection, WebReplConnection)

        file_size = self._get_file_size(source_path)

        src_fname = source_path.encode("utf-8")
        rec = struct.pack(WEBREPL_REQ_S, b"WA", WEBREPL_GET_FILE, 0, 0, 0,
                          len(src_fname), src_fname)
        self._write(WebreplBinaryMsg(rec))
        assert self._read_websocket_response() == 0

        bytes_read = 0
        callback(bytes_read, file_size)
        while True:
            # report ready
            self._write(WebreplBinaryMsg(b"\0"))

            (block_size, ) = struct.unpack("<H", self._connection.read(2))
            if block_size == 0:
                break
            while block_size:
                buf = self._connection.read(block_size)
                if not buf:
                    raise OSError()
                bytes_read += len(buf)
                target_fp.write(buf)
                block_size -= len(buf)
                callback(bytes_read, file_size)

        assert self._read_websocket_response() == 0