Executes a prepared query

        Parameters:
            query (ObjectID): Query ID
            dc (str): Specify datacenter that will be used.
                      Defaults to the agent's local datacenter.
            near (str): Sort the resulting list in ascending order based on
                        the estimated round trip time from that node
            limit (int): Limit the list's size to the given number of nodes
            consistency (Consistency): Force consistency
        Returns:
            Object:
        Raises:
            NotFound: the query does not exist

        Returns a body like this::

            {
                "Service": "redis",
                "Nodes": [
                    {
                        "Node": {
                            "Node": "foobar",
                            "Address": "10.1.10.12",
                            "TaggedAddresses": {
                                "lan": "10.1.10.12",
                                "wan": "10.1.10.12"
                            }
                        },
                        "Service": {
                            "ID": "redis",
                            "Service": "redis",
                            "Tags": None,
                            "Port": 8000
                        },
                        "Checks": [
                            {
                                "Node": "foobar",
                                "CheckID": "service:redis",
                                "Name": "Service 'redis' check",
                                "Status": "passing",
                                "Notes": "",
                                "Output": "",
                                "ServiceID": "redis",
                                "ServiceName": "redis"
                            },
                            {
                                "Node": "foobar",
                                "CheckID": "serfHealth",
                                "Name": "Serf Health Status",
                                "Status": "passing",
                                "Notes": "",
                                "Output": "",
                                "ServiceID": "",
                                "ServiceName": ""
                            }
                        ],
                        "DNS": {
                            "TTL": timedelta(seconds=10)
                        },
                        "Datacenter": "dc3",
                        "Failovers": 2
                    }
                ]
            }

        The **Nodes** section contains the list of healthy nodes providing
        the given service, as specified by the constraints of the prepared
        query.

        **Service** has the service name that the query was selecting. This is
        useful for context in case an empty list of nodes is returned.

        **DNS** has information used when serving the results over DNS. This
        is just a copy of the structure given when the prepared query was
        created.

        **Datacenter** has the datacenter that ultimately provided the list of
        nodes and **Failovers** has the number of remote datacenters that were
        queried while executing the query. This provides some insight into
        where the data came from. This will be zero during non-failover
        operations where there were healthy nodes found in the local
        datacenter.

async def execute(self, query, *,
                      dc=None, near=None, limit=None, consistency=None):
        """Executes a prepared query

        Parameters:
            query (ObjectID): Query ID
            dc (str): Specify datacenter that will be used.
                      Defaults to the agent's local datacenter.
            near (str): Sort the resulting list in ascending order based on
                        the estimated round trip time from that node
            limit (int): Limit the list's size to the given number of nodes
            consistency (Consistency): Force consistency
        Returns:
            Object:
        Raises:
            NotFound: the query does not exist

        Returns a body like this::

            {
                "Service": "redis",
                "Nodes": [
                    {
                        "Node": {
                            "Node": "foobar",
                            "Address": "10.1.10.12",
                            "TaggedAddresses": {
                                "lan": "10.1.10.12",
                                "wan": "10.1.10.12"
                            }
                        },
                        "Service": {
                            "ID": "redis",
                            "Service": "redis",
                            "Tags": None,
                            "Port": 8000
                        },
                        "Checks": [
                            {
                                "Node": "foobar",
                                "CheckID": "service:redis",
                                "Name": "Service 'redis' check",
                                "Status": "passing",
                                "Notes": "",
                                "Output": "",
                                "ServiceID": "redis",
                                "ServiceName": "redis"
                            },
                            {
                                "Node": "foobar",
                                "CheckID": "serfHealth",
                                "Name": "Serf Health Status",
                                "Status": "passing",
                                "Notes": "",
                                "Output": "",
                                "ServiceID": "",
                                "ServiceName": ""
                            }
                        ],
                        "DNS": {
                            "TTL": timedelta(seconds=10)
                        },
                        "Datacenter": "dc3",
                        "Failovers": 2
                    }
                ]
            }

        The **Nodes** section contains the list of healthy nodes providing
        the given service, as specified by the constraints of the prepared
        query.

        **Service** has the service name that the query was selecting. This is
        useful for context in case an empty list of nodes is returned.

        **DNS** has information used when serving the results over DNS. This
        is just a copy of the structure given when the prepared query was
        created.

        **Datacenter** has the datacenter that ultimately provided the list of
        nodes and **Failovers** has the number of remote datacenters that were
        queried while executing the query. This provides some insight into
        where the data came from. This will be zero during non-failover
        operations where there were healthy nodes found in the local
        datacenter.
        """
        query_id = extract_attr(query, keys=["ID"])
        response = await self._api.get(
            "/v1/query/%s/execute" % query_id,
            params={"dc": dc, "near": near, "limit": limit},
            consistency=consistency)
        return response.body