Custom Components

import typing
from typing import Any, Optional, Text, Dict, List, Type
from rasa.nlu.components import Component
from rasa.nlu import utils
if typing.TYPE_CHECKING:
   from rasa.nlu.model import Metadata
import rasa.utils.io as io_utils
from textblob import TextBlob

from rasa.nlu.config import RasaNLUModelConfig
from rasa.nlu.training_data import Message, TrainingData
from rasa.nlu.tokenizers.tokenizer import Tokenizer


class SentimentAnalyzer(Component):
    """A custom sentiment analysis component"""
    """A new component"""

    @classmethod
    def required_components(cls) -> List[Type[Component]]:
        """Specify which components need to be present in the pipeline."""
        return [Tokenizer]

    #language_list = ["en", "fr"]
    language_list = None
    defaults = {}
    provides = ["entities"]
    name = "sentiment"

    def __init__(self, component_config: Optional[Dict[Text, Any]] = None) -> None:
        super().__init__(component_config)

    def train(
        self,
        training_data: TrainingData,
        config: Optional[RasaNLUModelConfig] = None,
        **kwargs: Any,
    ) -> None:
        pass

    def convert_to_rasa(self, sentiment, confidence):
        """Convert model output into the Rasa NLU compatible output format."""
        entity = {"value": sentiment,
                  "entity": "sentiment",
                  "confidence":confidence,
                  "extractor": "sentiment_extractor"}
        return entity

    def preprocessing(self, tokens):
        pass


    def process(self, message: Message, **kwargs: Any) -> None:
        testimonial = TextBlob(str(message.text))
        if (testimonial.sentiment.polarity>0):
                sentiment="pos"
        elif (testimonial.sentiment.polarity<0):
                sentiment="neg"
        else:
                sentiment="neu"
      # To introduce confidence we can use and 'recenter' polarity (0 is neutral, 1 is positive, -1 is negative)
      # It doesn't give very good confidence results though
        confidence = (abs(abs(testimonial.sentiment.polarity)-0.5))/0.5
        entity = self.convert_to_rasa(sentiment, confidence)
        message.set("entities", [entity], add_to_output=True)

    def persist(self, file_name: Text, model_dir: Text) -> Optional[Dict[Text, Any]]:
        pass

    @classmethod
    def load(
        cls,
        meta: Dict[Text, Any],
        model_dir: Optional[Text] = None,
        model_metadata: Optional["Metadata"] = None,
        cached_component: Optional["Component"] = None,
        **kwargs: Any,
    ) -> "Component":
        if cached_component:
            return cached_component
        else:
            return cls(meta)