<commit_before>import logging
from pathlib import Path
from typing import Optional, Dict, Text, List, Any, Union

import rasa.shared.utils.common
import rasa.shared.utils.io
from rasa.shared.constants import NEXT_MAJOR_VERSION_FOR_DEPRECATIONS
from rasa.shared.core.constants import (
    LEGACY_ACTION_DEACTIVATE_LOOP_NAME,
    ACTION_DEACTIVATE_LOOP_NAME,
)
from rasa.shared.core.domain import Domain
from rasa.shared.core.events import SlotSet, ActionExecuted, Event
from rasa.shared.exceptions import RasaCoreException
from rasa.shared.core.training_data.story_reader.story_step_builder import (
    StoryStepBuilder,
)
from rasa.shared.core.training_data.structures import StoryStep

logger = logging.getLogger(__name__)


class StoryReader:
    """Helper class to read a story file."""

    def __init__(
        self,
        domain: Optional[Domain] = None,
        template_vars: Optional[Dict] = None,
        use_e2e: bool = False,
        source_name: Optional[Text] = None,
        is_used_for_training: bool = True,
    ) -> None:
        """Constructor for the StoryReader.

        Args:
            domain: Domain object.
            template_vars: Template variables to be replaced.
            use_e2e: Specifies whether to use the e2e parser or not.
            source_name: Name of the training data source.
            is_used_for_training: Identifies if the user utterances should be parsed
              (entities are extracted and removed from the original text) and
              OR statements should be unfolded. This parameter is used only to
              simplify the conversation from MD story files. Don't use it other ways,
              because it ends up in a invalid story that cannot be user for real
              training. Default value is `False`, which preserves the expected behavior
              of the reader.
        """
        self.story_steps = []
        self.current_step_builder: Optional[StoryStepBuilder] = None
        self.domain = domain
        self.template_variables = template_vars if template_vars else {}
        self.use_e2e = use_e2e
        self.source_name = source_name
        self._is_used_for_training = is_used_for_training
        self._is_parsing_conditions = False

    def read_from_file(self, filename: Text, skip_validation: bool) -> List[StoryStep]:
        raise NotImplementedError

    @staticmethod
    def is_test_stories_file(filename: Text) -> bool:
        """Checks if the specified file is a test story file.

        Args:
            filename: File to check.

        Returns:
            `True` if specified file is a test story file, `False` otherwise.
        """
        raise NotImplementedError

    @staticmethod
    def is_stories_file(filename: Union[Text, Path]) -> bool:
        """Checks if the specified file is a story file.<commit_msg>add docstring for story reader<commit_after>import logging
from pathlib import Path
from typing import Optional, Dict, Text, List, Any, Union

import rasa.shared.utils.common
import rasa.shared.utils.io
from rasa.shared.constants import NEXT_MAJOR_VERSION_FOR_DEPRECATIONS
from rasa.shared.core.constants import (
    LEGACY_ACTION_DEACTIVATE_LOOP_NAME,
    ACTION_DEACTIVATE_LOOP_NAME,
)
from rasa.shared.core.domain import Domain
from rasa.shared.core.events import SlotSet, ActionExecuted, Event
from rasa.shared.exceptions import RasaCoreException
from rasa.shared.core.training_data.story_reader.story_step_builder import (
    StoryStepBuilder,
)
from rasa.shared.core.training_data.structures import StoryStep

logger = logging.getLogger(__name__)


class StoryReader:
    """Helper class to read a story file."""

    def __init__(
        self,
        domain: Optional[Domain] = None,
        template_vars: Optional[Dict] = None,
        use_e2e: bool = False,
        source_name: Optional[Text] = None,
        is_used_for_training: bool = True,
    ) -> None:
        """Constructor for the StoryReader.

        Args:
            domain: Domain object.
            template_vars: Template variables to be replaced.
            use_e2e: Specifies whether to use the e2e parser or not.
            source_name: Name of the training data source.
            is_used_for_training: Identifies if the user utterances should be parsed
              (entities are extracted and removed from the original text) and
              OR statements should be unfolded. This parameter is used only to
              simplify the conversation from MD story files. Don't use it other ways,
              because it ends up in a invalid story that cannot be user for real
              training. Default value is `False`, which preserves the expected behavior
              of the reader.
        """
        self.story_steps = []
        self.current_step_builder: Optional[StoryStepBuilder] = None
        self.domain = domain
        self.template_variables = template_vars if template_vars else {}
        self.use_e2e = use_e2e
        self.source_name = source_name
        self._is_used_for_training = is_used_for_training
        self._is_parsing_conditions = False

    def read_from_file(self, filename: Text, skip_validation: bool) -> List[StoryStep]:
        """Reads stories or rules from file.

        Args:
            filename: Path to the story/rule file.
            skip_validation: `True` if the file was already validated
                e.g. when it was stored in the database.

        Returns:
            `StoryStep`s read from `filename`.
        """
        raise NotImplementedError

    @staticmethod
    def is_test_stories_file(filename: Text) -> bool:
        """Checks if the specified file is a test story file.

        Args:
            filename: File to check.

        Returns:
            `True` if specified file is a test story file, `False` otherwise.
        """
        raise NotImplementedError

    @staticmethod
    def is_stories_file(filename: Union[Text, Path]) -> bool:
        """Checks if the specified file is a story file.
{'fraction_non_alphanumeric': 0.06501496508147656, 'fraction_numerical': 0.0016627868307283007, 'mean_word_length': 2.669920683343502, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2401777', 'n_tokens_mistral': 1649, 'n_tokens_neox': 1607, 'n_words': 553}