Creates a new prepared query

        Parameters:
            Query (Object): Query definition
            dc (str): Specify datacenter that will be used.
                      Defaults to the agent's local datacenter.
        Returns:
            Object: New query ID

        The create operation expects a body that defines the prepared query,
        like this example::

            {
                "Name": "my-query",
                "Session": "adf4238a-882b-9ddc-4a9d-5b6758e4159e",
                "Token": "",
                "Near": "node1",
                "Service": {
                    "Service": "redis",
                    "Failover": {
                        "NearestN": 3,
                        "Datacenters": ["dc1", "dc2"]
                    },
                    "OnlyPassing": False,
                    "Tags": ["master", "!experimental"]
                },
                "DNS": {
                    "TTL": timedelta(seconds=10)
                }
            }

        Only the **Service** field inside the **Service** structure is
        mandatory, all other fields will take their default values if they
        are not included.

        **Name** is an optional friendly name that can be used to execute a
        query instead of using its ID.

        **Session** provides a way to automatically remove a prepared query
        when the given session is invalidated. This is optional, and if not
        given the prepared query must be manually removed when no longer
        needed.

        **Token**, if specified, is a captured ACL Token that is reused as the
        ACL Token every time the query is executed. This allows queries to be
        executed by clients with lesser or even no ACL Token, so this should
        be used with care. The token itself can only be seen by clients with a
        management token. If the **Token** field is left blank or omitted, the
        client's ACL Token will be used to determine if they have access to the
        service being queried. If the client does not supply an ACL Token, the
        anonymous token will be used.

        **Near** allows specifying a particular node to sort near based on
        distance sorting using Network Coordinates. The nearest instance to
        the specified node will be returned first, and subsequent nodes in the
        response will be sorted in ascending order of estimated round-trip
        times. If the node given does not exist, the nodes in the response
        will be shuffled. Using the magic **_agent** value is supported, and
        will automatically return results nearest the agent servicing the
        request. If unspecified, the response will be shuffled by default.

        The set of fields inside the **Service** structure define the
        query's behavior.

        **Service** is the name of the service to query. This is required.

        **Failover** contains two fields, both of which are optional, and
        determine what happens if no healthy nodes are available in the local
        datacenter when the query is executed. It allows the use of nodes in
        other datacenters with very little configuration.

        If **NearestN** is set to a value greater than zero, then the query
        will be forwarded to up to **NearestN** other datacenters based on
        their estimated network round trip time using Network Coordinates from
        the WAN gossip pool. The median round trip time from the server
        handling the query to the servers in the remote datacenter is used to
        determine the priority. The default value is zero. All Consul servers
        must be running version 0.6.0 or above in order for this feature to
        work correctly. If any servers are not running the required version of
        Consul they will be considered last since they won't have any
        available network coordinate information.

        **Datacenters** contains a fixed list of remote datacenters to forward
        the query to if there are no healthy nodes in the local datacenter.
        Datacenters are queried in the order given in the list. If this option
        is combined with **NearestN**, then the **NearestN** queries will be
        performed first, followed by the list given by **Datacenters**. A
        given datacenter will only be queried one time during a failover, even
        if it is selected by both **NearestN** and is listed in
        **Datacenters**. The default value is an empty list.

        **OnlyPassing** controls the behavior of the query's health check
        filtering. If this is set to false, the results will include nodes
        with checks in the passing as well as the warning states. If this is
        set to true, only nodes with checks in the passing state will be
        returned. The default value is False.

        **Tags** provides a list of service tags to filter the query results.
        For a service to pass the tag filter it must have all of the required
        tags, and none of the excluded tags (prefixed with ``!``).
        The default value is an empty list, which does no tag filtering.

        **TTL** in the **DNS** structure is a duration string that can use "s"
        as a suffix for seconds. It controls how the TTL is set when query
        results are served over DNS. If this isn't specified, then the Consul
        agent configuration for the given service will be used
        (see DNS Caching). If this is specified, it will take precedence over
        any Consul agent-specific configuration. If no TTL is specified here
        or at the Consul agent level, then the TTL will default to 0.

        It returns the ID of the created query::

            {
                "ID": "8f246b77-f3e1-ff88-5b48-8ec93abf3e05"
            }

async def create(self, query, *, dc=None):
        """Creates a new prepared query

        Parameters:
            Query (Object): Query definition
            dc (str): Specify datacenter that will be used.
                      Defaults to the agent's local datacenter.
        Returns:
            Object: New query ID

        The create operation expects a body that defines the prepared query,
        like this example::

            {
                "Name": "my-query",
                "Session": "adf4238a-882b-9ddc-4a9d-5b6758e4159e",
                "Token": "",
                "Near": "node1",
                "Service": {
                    "Service": "redis",
                    "Failover": {
                        "NearestN": 3,
                        "Datacenters": ["dc1", "dc2"]
                    },
                    "OnlyPassing": False,
                    "Tags": ["master", "!experimental"]
                },
                "DNS": {
                    "TTL": timedelta(seconds=10)
                }
            }

        Only the **Service** field inside the **Service** structure is
        mandatory, all other fields will take their default values if they
        are not included.

        **Name** is an optional friendly name that can be used to execute a
        query instead of using its ID.

        **Session** provides a way to automatically remove a prepared query
        when the given session is invalidated. This is optional, and if not
        given the prepared query must be manually removed when no longer
        needed.

        **Token**, if specified, is a captured ACL Token that is reused as the
        ACL Token every time the query is executed. This allows queries to be
        executed by clients with lesser or even no ACL Token, so this should
        be used with care. The token itself can only be seen by clients with a
        management token. If the **Token** field is left blank or omitted, the
        client's ACL Token will be used to determine if they have access to the
        service being queried. If the client does not supply an ACL Token, the
        anonymous token will be used.

        **Near** allows specifying a particular node to sort near based on
        distance sorting using Network Coordinates. The nearest instance to
        the specified node will be returned first, and subsequent nodes in the
        response will be sorted in ascending order of estimated round-trip
        times. If the node given does not exist, the nodes in the response
        will be shuffled. Using the magic **_agent** value is supported, and
        will automatically return results nearest the agent servicing the
        request. If unspecified, the response will be shuffled by default.

        The set of fields inside the **Service** structure define the
        query's behavior.

        **Service** is the name of the service to query. This is required.

        **Failover** contains two fields, both of which are optional, and
        determine what happens if no healthy nodes are available in the local
        datacenter when the query is executed. It allows the use of nodes in
        other datacenters with very little configuration.

        If **NearestN** is set to a value greater than zero, then the query
        will be forwarded to up to **NearestN** other datacenters based on
        their estimated network round trip time using Network Coordinates from
        the WAN gossip pool. The median round trip time from the server
        handling the query to the servers in the remote datacenter is used to
        determine the priority. The default value is zero. All Consul servers
        must be running version 0.6.0 or above in order for this feature to
        work correctly. If any servers are not running the required version of
        Consul they will be considered last since they won't have any
        available network coordinate information.

        **Datacenters** contains a fixed list of remote datacenters to forward
        the query to if there are no healthy nodes in the local datacenter.
        Datacenters are queried in the order given in the list. If this option
        is combined with **NearestN**, then the **NearestN** queries will be
        performed first, followed by the list given by **Datacenters**. A
        given datacenter will only be queried one time during a failover, even
        if it is selected by both **NearestN** and is listed in
        **Datacenters**. The default value is an empty list.

        **OnlyPassing** controls the behavior of the query's health check
        filtering. If this is set to false, the results will include nodes
        with checks in the passing as well as the warning states. If this is
        set to true, only nodes with checks in the passing state will be
        returned. The default value is False.

        **Tags** provides a list of service tags to filter the query results.
        For a service to pass the tag filter it must have all of the required
        tags, and none of the excluded tags (prefixed with ``!``).
        The default value is an empty list, which does no tag filtering.

        **TTL** in the **DNS** structure is a duration string that can use "s"
        as a suffix for seconds. It controls how the TTL is set when query
        results are served over DNS. If this isn't specified, then the Consul
        agent configuration for the given service will be used
        (see DNS Caching). If this is specified, it will take precedence over
        any Consul agent-specific configuration. If no TTL is specified here
        or at the Consul agent level, then the TTL will default to 0.

        It returns the ID of the created query::

            {
                "ID": "8f246b77-f3e1-ff88-5b48-8ec93abf3e05"
            }
        """

        if "Token" in query:
            # in case of a full token object...
            query["Token"] = extract_attr(query["Token"], keys=["ID"])

        response = await self._api.post("/v1/query",
                                        params={"dc": dc}, data=query)
        return response.body