Repository: deepset-ai/haystack

Issue:
Docstrings - `haystack.components.readers`



Discussion:

Resolving patch:
diff --git a/haystack/components/readers/extractive.py b/haystack/components/readers/extractive.py
--- a/haystack/components/readers/extractive.py
+++ b/haystack/components/readers/extractive.py
@@ -41,8 +41,9 @@ class ExtractiveReader:
     reader = ExtractiveReader()
     reader.warm_up()
 
-    question = "Who lives in Berlin?"
-    reader.run(query=question, documents=docs)
+    question = "What is a popular programming language?"
+    result = reader.run(query=question, documents=docs)
+    assert "Python" in result["answers"][0].data
     ```
     """
 
@@ -198,7 +199,7 @@ def _preprocess(
         self, queries: List[str], documents: List[Document], max_seq_length: int, query_ids: List[int], stride: int
     ) -> Tuple["torch.Tensor", "torch.Tensor", "torch.Tensor", List["Encoding"], List[int], List[int]]:
         """
-        Split and tokenize Documents and preserve structures by returning mappings to query and Document IDs.
+        Splits and tokenizes Documents and preserves structures by returning mappings to query and Document IDs.
         """
         texts = []
         document_ids = []
@@ -252,9 +253,10 @@ def _postprocess(
         encodings: List["Encoding"],
     ) -> Tuple[List[List[int]], List[List[int]], "torch.Tensor"]:
         """
-        Turn start and end logits into probabilities for each answer span. Unlike most other
-        implementations, it doesn't normalize the scores in each split to make them easier to compare across different
-        splits. Returns the top k answer spans.
+        Turns start and end logits into probabilities for each answer span.
+
+        Unlike most other implementations, it doesn't normalize the scores in each split to make them easier to
+        compare across different splits. Returns the top k answer spans.
         """
         mask = sequence_ids == 1  # Only keep tokens from the context (should ignore special tokens)
         mask = torch.logical_and(mask, attention_mask == 1)  # Definitely remove special tokens
@@ -319,10 +321,11 @@ def _nest_answers(
         overlap_threshold: Optional[float],
     ) -> List[List[ExtractedAnswer]]:
         """
-        Reconstructs the nested structure that existed before flattening. Also computes a no answer score.
-        This score is different from most other implementations because it does not consider the no answer
-        logit introduced with SQuAD 2. Instead, it just computes the probability that the answer does not exist
-        in the top k or top p.
+        Reconstructs the nested structure that existed before flattening.
+
+        Also computes a no answer score. This score is different from most other implementations because it does not
+        consider the no answer logit introduced with SQuAD 2. Instead, it just computes the probability that the
+        answer does not exist in the top k or top p.
         """
         answers_without_query = []
         for document_id, start_candidates_, end_candidates_, probabilities_ in zip(
@@ -369,8 +372,9 @@ def _calculate_overlap(self, answer1_start: int, answer1_end: int, answer2_start
         """
         Calculates the amount of overlap (in number of characters) between two answer offsets.
 
-        Stack overflow post explaining how to calculate overlap between two ranges:
-            https://stackoverflow.com/questions/325933/determine-whether-two-date-ranges-overlap/325964#325964
+        This Stack overflow
+        [post](https://stackoverflow.com/questions/325933/determine-whether-two-date-ranges-overlap/325964#325964)
+        explains how to calculate the overlap between two ranges.
         """
         # Check for overlap: (StartA <= EndB) and (StartB <= EndA)
         if answer1_start <= answer2_end and answer2_start <= answer1_end:
@@ -386,15 +390,18 @@ def _should_keep(
         self, candidate_answer: ExtractedAnswer, current_answers: List[ExtractedAnswer], overlap_threshold: float
     ) -> bool:
         """
-        Determine if the answer should be kept based on how much it overlaps with previous answers.
+        Determines if the answer should be kept based on how much it overlaps with previous answers.
 
         NOTE: We might want to avoid throwing away answers that only have a few character (or word) overlap:
             - E.g. The answers "the river in" and "in Maine" from the context "I want to go to the river in Maine."
             might both want to be kept.
 
-        :param candidate_answer: Candidate answer that will be checked if it should be kept.
-        :param current_answers: Current list of answers that will be kept.
-        :param overlap_threshold: If the overlap between two answers is greater than this threshold then return False.
+        :param candidate_answer:
+            Candidate answer that will be checked if it should be kept.
+        :param current_answers:
+            Current list of answers that will be kept.
+        :param overlap_threshold:
+            If the overlap between two answers is greater than this threshold then return False.
         """
         keep = True
 
@@ -493,30 +500,38 @@ def run(
         """
         Locates and extracts answers from the given Documents using the given query.
 
-        :param query: Query string.
-        :param documents: List of Documents in which you want to search for an answer to the query.
-        :param top_k: The maximum number of answers to return.
+        :param query:
+            Query string.
+        :param documents:
+            List of Documents in which you want to search for an answer to the query.
+        :param top_k:
+            The maximum number of answers to return.
             An additional answer is returned if no_answer is set to True (default).
-        :param score_threshold: Returns only answers with the score above this threshold.
-        :param max_seq_length: Maximum number of tokens.
-            If a sequence exceeds it, the sequence is split.
-            Default: 384
-        :param stride: Number of tokens that overlap when sequence is split because it exceeds max_seq_length.
-            Default: 128
-        :param max_batch_size: Maximum number of samples that are fed through the model at the same time.
-        :param answers_per_seq: Number of answer candidates to consider per sequence.
+        :param score_threshold:
+            Returns only answers with the score above this threshold.
+        :param max_seq_length:
+            Maximum number of tokens. If a sequence exceeds it, the sequence is split.
+        :param stride:
+            Number of tokens that overlap when sequence is split because it exceeds max_seq_length.
+        :param max_batch_size:
+            Maximum number of samples that are fed through the model at the same time.
+        :param answers_per_seq:
+            Number of answer candidates to consider per sequence.
             This is relevant when a Document was split into multiple sequences because of max_seq_length.
-            Default: 20
-        :param no_answer: Whether to return no answer scores.
-            Default: True
-        :param overlap_threshold: If set this will remove duplicate answers if they have an overlap larger than the
+        :param no_answer:
+            Whether to return no answer scores.
+        :param overlap_threshold:
+            If set this will remove duplicate answers if they have an overlap larger than the
             supplied threshold. For example, for the answers "in the river in Maine" and "the river" we would remove
             one of these answers since the second answer has a 100% (1.0) overlap with the first answer.
             However, for the answers "the river in" and "in Maine" there is only a max overlap percentage of 25% so
             both of these answers could be kept if this variable is set to 0.24 or lower.
             If None is provided then all answers are kept.
-            Default: 0.01
-        :return: List of ExtractedAnswers sorted by (desc.) answer score.
+        :returns:
+            List of answers sorted by (desc.) answer score.
+
+        :raises ComponentError:
+            If the component was not warmed up by calling 'warm_up()' before.
         """
         queries = [query]  # Temporary solution until we have decided what batching should look like in v2
         nested_documents = [documents]


Test patch: