docs: def build_api(packages, input, output, sanitizer, excluded_modules=None):
      """
      Builds the Sphinx documentation API.
  
      :param packages: Packages to include in the API.
      :type packages: list
      :param input: Input modules directory.
      :type input: unicode
      :param output: Output reStructuredText files directory.
      :type output: unicode
      :param sanitizer: Sanitizer python module.
      :type sanitizer: unicode
      :param excluded_modules: Excluded modules.
      :type excluded_modules: list
      :return: Definition success.
      :rtype: bool
      """
  
      LOGGER.info("{0} | Building Sphinx documentation API!".format(build_api.__name__))
  
      sanitizer = import_sanitizer(sanitizer)
  
      if os.path.exists(input):
          shutil.rmtree(input)
          os.makedirs(input)
  
      excluded_modules = [] if excluded_modules is None else excluded_modules
  
      packages_modules = {"apiModules": [],
                          "testsModules": []}
      for package in packages:
          package = __import__(package)
          path = foundations.common.get_first_item(package.__path__)
          package_directory = os.path.dirname(path)
  
          for file in sorted(
                  list(foundations.walkers.files_walker(package_directory, filters_in=("{0}.*\.ui$".format(path),)))):
              LOGGER.info("{0} | Ui file: '{1}'".format(build_api.__name__, file))
              target_directory = os.path.dirname(file).replace(package_directory, "")
              directory = "{0}{1}".format(input, target_directory)
              if not foundations.common.path_exists(directory):
                  os.makedirs(directory)
              source = os.path.join(directory, os.path.basename(file))
              shutil.copyfile(file, source)
  
          modules = []
          for file in sorted(
                  list(foundations.walkers.files_walker(package_directory, filters_in=("{0}.*\.py$".format(path),),
                                                        filters_out=excluded_modules))):
              LOGGER.info("{0} | Python file: '{1}'".format(build_api.__name__, file))
              module = "{0}.{1}".format((".".join(os.path.dirname(file).replace(package_directory, "").split("/"))),
                                        foundations.strings.get_splitext_basename(file)).strip(".")
              LOGGER.info("{0} | Module name: '{1}'".format(build_api.__name__, module))
              directory = os.path.dirname(os.path.join(input, module.replace(".", "/")))
              if not foundations.common.path_exists(directory):
                  os.makedirs(directory)
              source = os.path.join(directory, os.path.basename(file))
              shutil.copyfile(file, source)
  
              sanitizer.bleach(source)
  
              if "__init__.py" in file:
                  continue
  
              rst_file_path = "{0}{1}".format(module, FILES_EXTENSION)
              LOGGER.info("{0} | Building API file: '{1}'".format(build_api.__name__, rst_file_path))
              rst_file = File(os.path.join(output, rst_file_path))
              header = ["_`{0}`\n".format(module),
                        "==={0}\n".format("=" * len(module)),
                        "\n",
                        ".. automodule:: {0}\n".format(module),
                        "\n"]
              rst_file.content.extend(header)
  
              functions = OrderedDict()
              classes = OrderedDict()
              module_attributes = OrderedDict()
              for member, object in module_browser._readmodule(module, [source, ]).iteritems():
                  if object.__class__ == module_browser.Function:
                      if not member.startswith("_"):
                          functions[member] = [".. autofunction:: {0}\n".format(member)]
                  elif object.__class__ == module_browser.Class:
                      classes[member] = [".. autoclass:: {0}\n".format(member),
                                         "	:show-inheritance:\n",
                                         "	:members:\n"]
                  elif object.__class__ == module_browser.Global:
                      if not member.startswith("_"):
                          module_attributes[member] = [".. attribute:: {0}.{1}\n".format(module, member)]
  
              module_attributes and rst_file.content.append("Module Attributes\n-----------------\n\n")
              for module_attribute in module_attributes.itervalues():
                  rst_file.content.extend(module_attribute)
                  rst_file.content.append("\n")
  
              functions and rst_file.content.append("Functions\n---------\n\n")
              for function in functions.itervalues():
                  rst_file.content.extend(function)
                  rst_file.content.append("\n")
  
              classes and rst_file.content.append("Classes\n-------\n\n")
              for class_ in classes.itervalues():
                  rst_file.content.extend(class_)
                  rst_file.content.append("\n")
  
              rst_file.write()
              modules.append(module)
  
          packages_modules["apiModules"].extend([module for module in modules if not "tests" in module])
          packages_modules["testsModules"].extend([module for module in modules if "tests" in module])
  
      api_file = File("{0}{1}".format(output, FILES_EXTENSION))
      api_file.content.extend(TOCTREE_TEMPLATE_BEGIN)
      for module in packages_modules["apiModules"]:
          api_file.content.append("   {0} <{1}>\n".format(module, "api/{0}".format(module)))
      for module in packages_modules["testsModules"]:
          api_file.content.append("   {0} <{1}>\n".format(module, "api/{0}".format(module)))
      api_file.content.extend(TOCTREE_TEMPLATE_END)
      api_file.write()
  
      return True