<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 async def end(self):
 """Coroutine to end stream from the client-side. It should be used to finally end stream from the client-side when we're finished sending messages to the server and stream wasn't closed with last DATA frame. See :py:meth:`send_message` for more details. HTTP/2 stream will have half-closed (local) state after this coroutine call. """

        if self._end_done:
            raise ProtocolError('Stream was already ended')

        if (
            not self._cardinality.client_streaming
            and not self._send_message_count
        ):
            raise ProtocolError('Unary request requires a single message '
                                'to be sent')

        await self._stream.end()
        self._end_done = True