async def METHOD_NAME(
    self, query: str, variables: Optional[Dict] = None
) -> Union[ExecutionResult, AsyncIterator[ExecutionResult]]:
    id_ = uuid.uuid4().hex
    sub_payload = SubscribeMessagePayload(query=query, variables=variables)
    if self.protocol == GRAPHQL_TRANSPORT_WS_PROTOCOL:
        await self.send_json_to(
            SubscribeMessage(
                id=id_,
                payload=sub_payload,
            ).as_dict()
        )
    else:
        await self.send_json_to(
            {
                "type": GQL_START,
                "id": id_,
                "payload": dataclasses.asdict(sub_payload),
            }
        )
    while True:
        response = await self.receive_json_from(timeout=5)
        message_type = response["type"]
        if message_type == NextMessage.type:
            payload = NextMessage(**response).payload
            ret = ExecutionResult(payload["data"], None)
            if "errors" in payload:
                ret.errors = self.process_errors(payload["errors"])
            ret.extensions = payload.get("extensions", None)
            yield ret
        elif message_type == ErrorMessage.type:
            error_payload = ErrorMessage(**response).payload
            yield ExecutionResult(
                data=None, errors=self.process_errors(error_payload)
            )
            return  # an error message is the last message for a subscription
        else:
            return