<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def query(self, query, params=None, bind_params=None, epoch=None, expected_response_code=200, database=None, raise_errors=True, chunked=False, chunk_size=0, method="GET"):
 """Send a query to InfluxDB. .. danger:: In order to avoid injection vulnerabilities (similar to `SQL injection <https://www.owasp.org/index.php/SQL_Injection>`_ vulnerabilities), do not directly include untrusted data into the ``query`` parameter, use ``bind_params`` instead. :param query: the actual query string :type query: str :param params: additional parameters for the request, defaults to {} :type params: dict :param bind_params: bind parameters for the query: any variable in the query written as ``'$var_name'`` will be replaced with ``bind_params['var_name']``. Only works in the ``WHERE`` clause and takes precedence over ``params['params']`` :type bind_params: dict :param epoch: response timestamps to be in epoch format either 'h', 'm', 's', 'ms', 'u', or 'ns',defaults to `None` which is RFC3339 UTC format with nanosecond precision :type epoch: str :param expected_response_code: the expected status code of response, defaults to 200 :type expected_response_code: int :param database: database to query, defaults to None :type database: str :param raise_errors: Whether or not to raise exceptions when InfluxDB returns errors, defaults to True :type raise_errors: bool :param chunked: Enable to use chunked responses from InfluxDB. With ``chunked`` enabled, one ResultSet is returned per chunk containing all results within that chunk :type chunked: bool :param chunk_size: Size of each chunk to tell InfluxDB to use. :type chunk_size: int :param method: the HTTP method for the request, defaults to GET :type method: str :returns: the queried data :rtype: :class:`~.ResultSet` """

        if params is None:
            params = {}

        if bind_params is not None:
            params_dict = json.loads(params.get('params', '{}'))
            params_dict.update(bind_params)
            params['params'] = json.dumps(params_dict)

        params['q'] = query
        params['db'] = database or self._database

        if epoch is not None:
            params['epoch'] = epoch

        if chunked:
            params['chunked'] = 'true'
            if chunk_size > 0:
                params['chunk_size'] = chunk_size

        if query.lower().startswith("select ") and " into " in query.lower():
            method = "POST"

        response = self.request(
            url="query",
            method=method,
            params=params,
            data=None,
            expected_response_code=expected_response_code
        )

        if chunked:
            return self._read_chunked_response(response)

        data = response.json()

        results = [
            ResultSet(result, raise_errors=raise_errors)
            for result
            in data.get('results', [])
        ]

        # TODO(aviau): Always return a list. (This would be a breaking change)
        if len(results) == 1:
            return results[0]

        return results