nodes: 0, module; 1, function_definition; 2, function_name:get_threads; 3, parameters; 4, block; 5, identifier:self; 6, identifier:querystring; 7, default_parameter; 8, default_parameter; 9, expression_statement; 10, assert_statement; 11, expression_statement; 12, expression_statement; 13, if_statement; 14, return_statement; 15, identifier:sort; 16, string; 17, identifier:exclude_tags; 18, None; 19, comment:"""
          asynchronously look up thread ids matching `querystring`.
  
          :param querystring: The query string to use for the lookup
          :type querystring: str.
          :param sort: Sort order. one of ['oldest_first', 'newest_first',
                       'message_id', 'unsorted']
          :type query: str
          :param exclude_tags: Tags to exclude by default unless included in the
                               search
          :type exclude_tags: list of str
          :returns: a pipe together with the process that asynchronously
                    writes to it.
          :rtype: (:class:`multiprocessing.Pipe`,
                  :class:`multiprocessing.Process`)
          """; 20, comparison_operator:sort in self._sort_orders; 21, assignment; 22, call; 23, identifier:exclude_tags; 24, block; 25, call; 26, string_content:newest_first; 27, identifier:sort; 28, attribute; 29, identifier:q; 30, call; 31, attribute; 32, argument_list; 33, for_statement; 34, attribute; 35, argument_list; 36, identifier:self; 37, identifier:_sort_orders; 38, attribute; 39, argument_list; 40, identifier:q; 41, identifier:set_sort; 42, subscript; 43, identifier:tag; 44, identifier:exclude_tags; 45, block; 46, identifier:self; 47, identifier:async_; 48, attribute; 49, parenthesized_expression; 50, identifier:self; 51, identifier:query; 52, identifier:querystring; 53, attribute; 54, identifier:sort; 55, expression_statement; 56, identifier:q; 57, identifier:search_threads; 58, lambda; 59, identifier:self; 60, identifier:_sort_orders; 61, call; 62, lambda_parameters; 63, call; 64, attribute; 65, argument_list; 66, identifier:a; 67, attribute; 68, argument_list; 69, identifier:q; 70, identifier:exclude_tag; 71, identifier:tag; 72, identifier:a; 73, identifier:get_thread_id
code: def get_threads(self, querystring, sort='newest_first', exclude_tags=None):
          """
          asynchronously look up thread ids matching `querystring`.
  
          :param querystring: The query string to use for the lookup
          :type querystring: str.
          :param sort: Sort order. one of ['oldest_first', 'newest_first',
                       'message_id', 'unsorted']
          :type query: str
          :param exclude_tags: Tags to exclude by default unless included in the
                               search
          :type exclude_tags: list of str
          :returns: a pipe together with the process that asynchronously
                    writes to it.
          :rtype: (:class:`multiprocessing.Pipe`,
                  :class:`multiprocessing.Process`)
          """
          assert sort in self._sort_orders
          q = self.query(querystring)
          q.set_sort(self._sort_orders[sort])
          if exclude_tags:
              for tag in exclude_tags:
                  q.exclude_tag(tag)
          return self.async_(q.search_threads, (lambda a: a.get_thread_id()))