# Path: aioconsul/client/bases.py
# class EndpointBase:
# 
#     def __init__(self, api):
#         self._api = api
# 
#     def __repr__(self):
#         return "<%s(%r)>" % (self.__class__.__name__, str(self._api.address))
# 
# Path: aioconsul/util.py
# def extract_attr(obj, *, keys):
#     if isinstance(obj, Mapping):
#         for key in keys:
#             if key in obj:
#                 return obj[key]
#         raise TypeError("%s not found in obj %s" % (keys, obj))
#     return obj


from .bases import EndpointBase
from aioconsul.util import extract_attr

        Parameters:
            address (str): Address of node
            wan (bool): Attempt to join using the WAN pool
        Returns:
            bool: ``True`` on success

        This endpoint is used to instruct the agent to attempt to connect to
        a given address. For agents running in server mode, providing ``wan``
        parameter causes the agent to attempt to join using the WAN pool.
        """
        response = await self._api.get("/v1/agent/join", address,
                                       params={"wan": wan})
        return response.status == 200

    async def force_leave(self, node):
        """Forces removal of a node

        Parameters:
            node (ObjectID): Node name
        Returns:
            bool: ``True`` on success

        This endpoint is used to instruct the agent to force a node into the
        ``left`` state. If a node fails unexpectedly, then it will be in a
        ``failed`` state. Once in the ``failed`` state, Consul will attempt to
        reconnect, and the services and checks belonging to that node will not
        be cleaned up. Forcing a node into the ``left`` state allows its old
        entries to be removed.
        """

# Path: aioconsul/client/bases.py
# class EndpointBase:
# 
#     def __init__(self, api):
#         self._api = api
# 
#     def __repr__(self):
#         return "<%s(%r)>" % (self.__class__.__name__, str(self._api.address))
# 
# Path: aioconsul/util.py
# def extract_attr(obj, *, keys):
#     if isinstance(obj, Mapping):
#         for key in keys:
#             if key in obj:
#                 return obj[key]
#         raise TypeError("%s not found in obj %s" % (keys, obj))
#     return obj


# Path: aioconsul/client/members_endpoint.py
from .bases import EndpointBase
from aioconsul.util import extract_attr


        Parameters:
            address (str): Address of node
            wan (bool): Attempt to join using the WAN pool
        Returns:
            bool: ``True`` on success

        This endpoint is used to instruct the agent to attempt to connect to
        a given address. For agents running in server mode, providing ``wan``
        parameter causes the agent to attempt to join using the WAN pool.
        """
        response = await self._api.get("/v1/agent/join", address,
                                       params={"wan": wan})
        return response.status == 200

    async def force_leave(self, node):
        """Forces removal of a node

        Parameters:
            node (ObjectID): Node name
        Returns:
            bool: ``True`` on success

        This endpoint is used to instruct the agent to force a node into the
        ``left`` state. If a node fails unexpectedly, then it will be in a
        ``failed`` state. Once in the ``failed`` state, Consul will attempt to
        reconnect, and the services and checks belonging to that node will not
        be cleaned up. Forcing a node into the ``left`` state allows its old
        entries to be removed.
        """

        node_id = extract_attr(node, keys=["Node", "ID"])