def get_setting(self, name, section=None, throw_exception=None):
        """
            Setting names should always be lower_case_underscore
            Well check the config and environment variables for the name. Environment variables will be made all caps
            when checked

            Args:
                name (str): attribute name to get
                section (Optional[str]): section name to retrieve attribute from, will default to self.config_section
                throw_exception (Optional[bool]): throw exceptions or not if invalid, default to self.throw_exception

        """

        if not section:
            section = self.config_section

        env_key = section.upper() + "_" + name.upper()
        if env_key in os.environ:
            return os.environ.get(env_key)

        if self.secrets_dir:
            secrets_file = os.path.join(self.secrets_dir,
                                        "{}_{}".format(section, name))
            if os.path.isfile(secrets_file):
                with open(secrets_file, "r") as fh:
                    return fh.read().rstrip()

        if throw_exception is None:
            throw_exception = self.throw_exception

        # ensure section exists - needed here in addition to init for cases where user specifies section in
        # `get_setting()`
        if not self.parser.has_section(section):
            self.parser.add_section(section)

        if throw_exception:
            return self.parser.get(section, name)

        if py2:
            try:
                return self.parser.get(section, name)
            except configparser.NoOptionError:
                return None
        else:
            return self.parser.get(section, name, fallback=None)