# Path: gql/transport/async_transport.py
# class AsyncTransport:
#     @abc.abstractmethod
#     async def connect(self):
#         """Coroutine used to create a connection to the specified address
#         """
#         raise NotImplementedError(
#             "Any AsyncTransport subclass must implement connect method"
#         )  # pragma: no cover
# 
#     @abc.abstractmethod
#     async def close(self):
#         """Coroutine used to Close an established connection
#         """
#         raise NotImplementedError(
#             "Any AsyncTransport subclass must implement close method"
#         )  # pragma: no cover
# 
#     @abc.abstractmethod
#     async def execute(
#         self,
#         document: DocumentNode,
#         variable_values: Optional[Dict[str, Any]] = None,
#         operation_name: Optional[str] = None,
#     ) -> ExecutionResult:
#         """Execute the provided document AST for either a remote or local GraphQL Schema.
#         """
#         raise NotImplementedError(
#             "Any AsyncTransport subclass must implement execute method"
#         )  # pragma: no cover
# 
#     @abc.abstractmethod
#     def subscribe(
#         self,
#         document: DocumentNode,
#         variable_values: Optional[Dict[str, Any]] = None,
#         operation_name: Optional[str] = None,
#     ) -> AsyncGenerator[ExecutionResult, None]:
#         """Send a query and receive the results using an async generator
# 
#         The query can be a graphql query, mutation or subscription
# 
#         The results are sent as an ExecutionResult object
#         """
#         raise NotImplementedError(
#             "Any AsyncTransport subclass must implement subscribe method"
#         )  # pragma: no cover
# 
# Path: gql/transport/exceptions.py
# class TransportAlreadyConnected(TransportError):
#     """Transport is already connected.
# 
#     Exception generated when the client is trying to connect to the transport
#     while the transport is already connected.
#     """
# 
# class TransportClosed(TransportError):
#     """Transport is already closed.
# 
#     This exception is generated when the client is trying to use the transport
#     while the transport was previously closed.
#     """
# 
# class TransportProtocolError(TransportError):
#     """Transport protocol error.
# 
#     The answer received from the server does not correspond to the transport protocol.
#     """
# 
# class TransportQueryError(Exception):
#     """The server returned an error for a specific query.
# 
#     This exception should not close the transport connection.
#     """
# 
#     query_id: Optional[int]
#     errors: Optional[List[Any]]
#     data: Optional[Any]
#     extensions: Optional[Any]
# 
#     def __init__(
#         self,
#         msg: str,
#         query_id: Optional[int] = None,
#         errors: Optional[List[Any]] = None,
#         data: Optional[Any] = None,
#         extensions: Optional[Any] = None,
#     ):
#         super().__init__(msg)
#         self.query_id = query_id
#         self.errors = errors
#         self.data = data
#         self.extensions = extensions
# 
# class TransportServerError(TransportError):
#     """The server returned a global error.
# 
#     This exception will close the transport connection.
#     """
# 
#     code: Optional[int]
# 
#     def __init__(self, message: str, code: Optional[int] = None):
#         super(TransportServerError, self).__init__(message)
#         self.code = code


import asyncio
import logging
import warnings
import websockets
from abc import abstractmethod
from contextlib import suppress
from ssl import SSLContext
from typing import Any, AsyncGenerator, Dict, List, Optional, Tuple, Union, cast
from graphql import DocumentNode, ExecutionResult
from websockets.client import WebSocketClientProtocol
from websockets.datastructures import HeadersLike
from websockets.exceptions import ConnectionClosed
from websockets.typing import Data, Subprotocol
from .async_transport import AsyncTransport
from .exceptions import (
    TransportAlreadyConnected,
    TransportClosed,
    TransportProtocolError,
    TransportQueryError,
    TransportServerError,
)

            self.websocket = None
            self.close_task = None
            self.check_keep_alive_task = None
            self._wait_closed.set()

        log.debug("_close_coro: exiting")

    async def _fail(self, e: Exception, clean_close: bool = True) -> None:
        log.debug("_fail: starting with exception: " + repr(e))

        if self.close_task is None:

            if self.websocket is None:
                log.debug("_fail started with self.websocket == None -> already closed")
            else:
                self.close_task = asyncio.shield(
                    asyncio.ensure_future(self._close_coro(e, clean_close=clean_close))
                )
        else:
            log.debug(
                "close_task is not None in _fail. Previous exception is: "
                + repr(self.close_exception)
                + " New exception is: "
                + repr(e)
            )

    async def close(self) -> None:
        log.debug("close: starting")


# Path: gql/transport/async_transport.py
# class AsyncTransport:
#     @abc.abstractmethod
#     async def connect(self):
#         """Coroutine used to create a connection to the specified address
#         """
#         raise NotImplementedError(
#             "Any AsyncTransport subclass must implement connect method"
#         )  # pragma: no cover
# 
#     @abc.abstractmethod
#     async def close(self):
#         """Coroutine used to Close an established connection
#         """
#         raise NotImplementedError(
#             "Any AsyncTransport subclass must implement close method"
#         )  # pragma: no cover
# 
#     @abc.abstractmethod
#     async def execute(
#         self,
#         document: DocumentNode,
#         variable_values: Optional[Dict[str, Any]] = None,
#         operation_name: Optional[str] = None,
#     ) -> ExecutionResult:
#         """Execute the provided document AST for either a remote or local GraphQL Schema.
#         """
#         raise NotImplementedError(
#             "Any AsyncTransport subclass must implement execute method"
#         )  # pragma: no cover
# 
#     @abc.abstractmethod
#     def subscribe(
#         self,
#         document: DocumentNode,
#         variable_values: Optional[Dict[str, Any]] = None,
#         operation_name: Optional[str] = None,
#     ) -> AsyncGenerator[ExecutionResult, None]:
#         """Send a query and receive the results using an async generator
# 
#         The query can be a graphql query, mutation or subscription
# 
#         The results are sent as an ExecutionResult object
#         """
#         raise NotImplementedError(
#             "Any AsyncTransport subclass must implement subscribe method"
#         )  # pragma: no cover
# 
# Path: gql/transport/exceptions.py
# class TransportAlreadyConnected(TransportError):
#     """Transport is already connected.
# 
#     Exception generated when the client is trying to connect to the transport
#     while the transport is already connected.
#     """
# 
# class TransportClosed(TransportError):
#     """Transport is already closed.
# 
#     This exception is generated when the client is trying to use the transport
#     while the transport was previously closed.
#     """
# 
# class TransportProtocolError(TransportError):
#     """Transport protocol error.
# 
#     The answer received from the server does not correspond to the transport protocol.
#     """
# 
# class TransportQueryError(Exception):
#     """The server returned an error for a specific query.
# 
#     This exception should not close the transport connection.
#     """
# 
#     query_id: Optional[int]
#     errors: Optional[List[Any]]
#     data: Optional[Any]
#     extensions: Optional[Any]
# 
#     def __init__(
#         self,
#         msg: str,
#         query_id: Optional[int] = None,
#         errors: Optional[List[Any]] = None,
#         data: Optional[Any] = None,
#         extensions: Optional[Any] = None,
#     ):
#         super().__init__(msg)
#         self.query_id = query_id
#         self.errors = errors
#         self.data = data
#         self.extensions = extensions
# 
# class TransportServerError(TransportError):
#     """The server returned a global error.
# 
#     This exception will close the transport connection.
#     """
# 
#     code: Optional[int]
# 
#     def __init__(self, message: str, code: Optional[int] = None):
#         super(TransportServerError, self).__init__(message)
#         self.code = code


# Path: gql/transport/websockets_base.py
import asyncio
import logging
import warnings
import websockets
from abc import abstractmethod
from contextlib import suppress
from ssl import SSLContext
from typing import Any, AsyncGenerator, Dict, List, Optional, Tuple, Union, cast
from graphql import DocumentNode, ExecutionResult
from websockets.client import WebSocketClientProtocol
from websockets.datastructures import HeadersLike
from websockets.exceptions import ConnectionClosed
from websockets.typing import Data, Subprotocol
from .async_transport import AsyncTransport
from .exceptions import (
    TransportAlreadyConnected,
    TransportClosed,
    TransportProtocolError,
    TransportQueryError,
    TransportServerError,
)


            self.websocket = None
            self.close_task = None
            self.check_keep_alive_task = None
            self._wait_closed.set()

        log.debug("_close_coro: exiting")

    async def _fail(self, e: Exception, clean_close: bool = True) -> None:
        log.debug("_fail: starting with exception: " + repr(e))

        if self.close_task is None:

            if self.websocket is None:
                log.debug("_fail started with self.websocket == None -> already closed")
            else:
                self.close_task = asyncio.shield(
                    asyncio.ensure_future(self._close_coro(e, clean_close=clean_close))
                )
        else:
            log.debug(
                "close_task is not None in _fail. Previous exception is: "
                + repr(self.close_exception)
                + " New exception is: "
                + repr(e)
            )

    async def close(self) -> None:
        log.debug("close: starting")


        await self._fail(TransportClosed("Websocket GraphQL transport closed by user"))