nodes: 0, module; 1, function_definition; 2, function_name:query; 3, parameters; 4, block; 5, identifier:self; 6, default_parameter; 7, default_parameter; 8, default_parameter; 9, default_parameter; 10, default_parameter; 11, default_parameter; 12, default_parameter; 13, dictionary_splat_pattern; 14, expression_statement; 15, expression_statement; 16, expression_statement; 17, expression_statement; 18, expression_statement; 19, expression_statement; 20, return_statement; 21, identifier:area; 22, None; 23, identifier:date; 24, None; 25, identifier:raw; 26, None; 27, identifier:area_relation; 28, string; 29, identifier:order_by; 30, None; 31, identifier:limit; 32, None; 33, identifier:offset; 34, integer:0; 35, identifier:keywords; 36, comment:"""Query the OpenSearch API with the coordinates of an area, a date interval
          and any other search keywords accepted by the API.
  
          Parameters
          ----------
          area : str, optional
              The area of interest formatted as a Well-Known Text string.
          date : tuple of (str or datetime) or str, optional
              A time interval filter based on the Sensing Start Time of the products.
              Expects a tuple of (start, end), e.g. ("NOW-1DAY", "NOW").
              The timestamps can be either a Python datetime or a string in one of the
              following formats:
  
                  - yyyyMMdd
                  - yyyy-MM-ddThh:mm:ss.SSSZ (ISO-8601)
                  - yyyy-MM-ddThh:mm:ssZ
                  - NOW
                  - NOW-<n>DAY(S) (or HOUR(S), MONTH(S), etc.)
                  - NOW+<n>DAY(S)
                  - yyyy-MM-ddThh:mm:ssZ-<n>DAY(S)
                  - NOW/DAY (or HOUR, MONTH etc.) - rounds the value to the given unit
  
              Alternatively, an already fully formatted string such as "[NOW-1DAY TO NOW]" can be
              used as well.
          raw : str, optional
              Additional query text that will be appended to the query.
          area_relation : {'Intersects', 'Contains', 'IsWithin'}, optional
              What relation to use for testing the AOI. Case insensitive.
  
                  - Intersects: true if the AOI and the footprint intersect (default)
                  - Contains: true if the AOI is inside the footprint
                  - IsWithin: true if the footprint is inside the AOI
  
          order_by: str, optional
              A comma-separated list of fields to order by (on server side).
              Prefix the field name by '+' or '-' to sort in ascending or descending order,
              respectively. Ascending order is used if prefix is omitted.
              Example: "cloudcoverpercentage, -beginposition".
          limit: int, optional
              Maximum number of products returned. Defaults to no limit.
          offset: int, optional
              The number of results to skip. Defaults to 0.
          **keywords
              Additional keywords can be used to specify other query parameters,
              e.g. `relativeorbitnumber=70`.
              See https://scihub.copernicus.eu/twiki/do/view/SciHubUserGuide/3FullTextSearch
              for a full list.
  
  
          Range values can be passed as two-element tuples, e.g. `cloudcoverpercentage=(0, 30)`.
          `None` can be used in range values for one-sided ranges, e.g. `orbitnumber=(16302, None)`.
          Ranges with no bounds (`orbitnumber=(None, None)`) will not be included in the query.
  
          The time interval formats accepted by the `date` parameter can also be used with
          any other parameters that expect time intervals (that is: 'beginposition', 'endposition',
          'date', 'creationdate', and 'ingestiondate').
  
          Returns
          -------
          dict[string, dict]
              Products returned by the query as a dictionary with the product ID as the key and
              the product's attributes (a dictionary) as the value.
          """; 37, assignment; 38, call; 39, assignment; 40, assignment; 41, call; 42, call; 43, string_content:Intersects; 44, identifier:query; 45, call; 46, attribute; 47, argument_list; 48, identifier:formatted_order_by; 49, call; 50, pattern_list; 51, call; 52, attribute; 53, argument_list; 54, identifier:_parse_opensearch_response; 55, argument_list; 56, attribute; 57, argument_list; 58, attribute; 59, identifier:debug; 60, string:"Running query: order_by=%s, limit=%s, offset=%s, query=%s"; 61, identifier:order_by; 62, identifier:limit; 63, identifier:offset; 64, identifier:query; 65, identifier:_format_order_by; 66, argument_list; 67, identifier:response; 68, identifier:count; 69, attribute; 70, argument_list; 71, attribute; 72, identifier:info; 73, string:"Found %s products"; 74, identifier:count; 75, identifier:response; 76, identifier:self; 77, identifier:format_query; 78, identifier:area; 79, identifier:date; 80, identifier:raw; 81, identifier:area_relation; 82, dictionary_splat; 83, identifier:self; 84, identifier:logger; 85, identifier:order_by; 86, identifier:self; 87, identifier:_load_query; 88, identifier:query; 89, identifier:formatted_order_by; 90, identifier:limit; 91, identifier:offset; 92, identifier:self; 93, identifier:logger; 94, identifier:keywords
code: def query(self, area=None, date=None, raw=None, area_relation='Intersects',
                order_by=None, limit=None, offset=0, **keywords):
          """Query the OpenSearch API with the coordinates of an area, a date interval
          and any other search keywords accepted by the API.
  
          Parameters
          ----------
          area : str, optional
              The area of interest formatted as a Well-Known Text string.
          date : tuple of (str or datetime) or str, optional
              A time interval filter based on the Sensing Start Time of the products.
              Expects a tuple of (start, end), e.g. ("NOW-1DAY", "NOW").
              The timestamps can be either a Python datetime or a string in one of the
              following formats:
  
                  - yyyyMMdd
                  - yyyy-MM-ddThh:mm:ss.SSSZ (ISO-8601)
                  - yyyy-MM-ddThh:mm:ssZ
                  - NOW
                  - NOW-<n>DAY(S) (or HOUR(S), MONTH(S), etc.)
                  - NOW+<n>DAY(S)
                  - yyyy-MM-ddThh:mm:ssZ-<n>DAY(S)
                  - NOW/DAY (or HOUR, MONTH etc.) - rounds the value to the given unit
  
              Alternatively, an already fully formatted string such as "[NOW-1DAY TO NOW]" can be
              used as well.
          raw : str, optional
              Additional query text that will be appended to the query.
          area_relation : {'Intersects', 'Contains', 'IsWithin'}, optional
              What relation to use for testing the AOI. Case insensitive.
  
                  - Intersects: true if the AOI and the footprint intersect (default)
                  - Contains: true if the AOI is inside the footprint
                  - IsWithin: true if the footprint is inside the AOI
  
          order_by: str, optional
              A comma-separated list of fields to order by (on server side).
              Prefix the field name by '+' or '-' to sort in ascending or descending order,
              respectively. Ascending order is used if prefix is omitted.
              Example: "cloudcoverpercentage, -beginposition".
          limit: int, optional
              Maximum number of products returned. Defaults to no limit.
          offset: int, optional
              The number of results to skip. Defaults to 0.
          **keywords
              Additional keywords can be used to specify other query parameters,
              e.g. `relativeorbitnumber=70`.
              See https://scihub.copernicus.eu/twiki/do/view/SciHubUserGuide/3FullTextSearch
              for a full list.
  
  
          Range values can be passed as two-element tuples, e.g. `cloudcoverpercentage=(0, 30)`.
          `None` can be used in range values for one-sided ranges, e.g. `orbitnumber=(16302, None)`.
          Ranges with no bounds (`orbitnumber=(None, None)`) will not be included in the query.
  
          The time interval formats accepted by the `date` parameter can also be used with
          any other parameters that expect time intervals (that is: 'beginposition', 'endposition',
          'date', 'creationdate', and 'ingestiondate').
  
          Returns
          -------
          dict[string, dict]
              Products returned by the query as a dictionary with the product ID as the key and
              the product's attributes (a dictionary) as the value.
          """
          query = self.format_query(area, date, raw, area_relation, **keywords)
  
          self.logger.debug("Running query: order_by=%s, limit=%s, offset=%s, query=%s",
                            order_by, limit, offset, query)
          formatted_order_by = _format_order_by(order_by)
          response, count = self._load_query(query, formatted_order_by, limit, offset)
          self.logger.info("Found %s products", count)
          return _parse_opensearch_response(response)