class_docstr: Detects offensive language using a list of offensive language and phrases from
  https://github.com/LDNOOBW.
class_docstr_tok: ["Detects","offensive","language","using","a","list","of","offensive","language","and","phrases","from","https",":","\/\/github.com\/LDNOOBW","."]
docstr: Get data from external sources and build data representation.
  
  If datapath ends in '.txt' it is assumed a custom model file is already given.
docstr_tok: ["Get","data","from","external","sources","and","build","data","representation",".","If","datapath","ends","in","'.txt","'","it","is","assumed","a","custom","model","file","is","already","given","."]
code: def __init__(self, datapath: str = None):
      """
      Get data from external sources and build data representation.
  
      If datapath ends in '.txt' it is assumed a custom model file is already given.
      """
      import parlai.core.build_data as build_data
      from parlai.core.dict import DictionaryAgent
  
      self.tokenize = DictionaryAgent.split_tokenize
  
      def _path():
          # Build the data if it doesn't exist.
          build()
          return os.path.join(
              self.datapath,
              "OffensiveLanguage",
              "OffensiveLanguage.txt",
          )
  
      def build():
          version = "v1.0"
          dpath = os.path.join(self.datapath, "OffensiveLanguage")
          if not build_data.built(dpath, version):
              logging.info(f"building data: {dpath}")
              if build_data.built(dpath):
                  # An older version exists, so remove these outdated files.
                  build_data.remove_dir(dpath)
              build_data.make_dir(dpath)
  
              # Download the data.
              fname = "OffensiveLanguage.txt"
              url = (
                  "http://parl.ai/downloads/offensive_language/" + fname
              )
              build_data.download(url, dpath, fname)
  
              # Mark the data as built.
              build_data.mark_done(dpath, version)
  
      if datapath is not None and datapath.endswith(".txt"):
          # Load custom file.
          self.datafile = datapath
      else:
          # Build data from zoo, and place in given datapath.
          if datapath is None:
              # Build data from zoo.
              from parlai.core.params import ParlaiParser
  
              parser = ParlaiParser(False, False)
              self.datapath = parser.parse_args([])["datapath"]
          else:
              self.datapath = datapath
          self.datafile = _path()
  
      # store a token trie: e.g.
      # {'2': {'girls': {'1': {'cup': {'__END__': True}}}}
      self.END = "__END__"
      self.max_len = 1
      self.offensive_trie = {}
      self.word_prefixes = [
          "de",
          "de-",
          "dis",
          "dis-",
          "ex",
          "ex-",
          "mis",
          "mis-",
          "pre",
          "pre-",
          "non",
          "non-",
          "semi",
          "semi-",
          "sub",
          "sub-",
          "un",
          "un-",
      ]
      self.word_suffixes = [
          "a",
          "able",
          "as",
          "dom",
          "ed",
          "er",
          "ers",
          "ery",
          "es",
          "est",
          "ful",
          "fy",
          "ies",
          "ify",
          "in",
          "ing",
          "ish",
          "less",
          "ly",
          "s",
          "y",
      ]
      self.allow_list = [
          "butter",
          "buttery",
          "spicy",
          "spiced",
          "spices",
          "spicier",
          "spicing",
          "twinkies",
      ]
  
      with PathManager.open(self.datafile, "r") as f:
          for p in f.read().splitlines():
              mod_ps = [p]
              mod_ps += [pref + p for pref in self.word_prefixes]
              mod_ps += [p + suff for suff in self.word_suffixes]
              for mod_p in mod_ps:
                  if mod_p not in self.allow_list:
                      self.add_phrase(mod_p)
  
imports: from parlai.agents.transformer.transformer import TransformerClassifierAgent
  from parlai.core.agents import create_agent, create_agent_from_shared
  from parlai.tasks.dialogue_safety.agents import OK_CLASS, NOT_OK_CLASS
  from parlai.utils.typing import TShared
  from parlai.utils.io import PathManager
  import parlai.utils.logging
  import os
label_desc: Use image node_id 1 to create a new OffensiveStringMatcher object  with example: obj = OffensiveStringMatcher(datapath)