# Adding Abseil (absl) flags quickstart ## Defining a flag absl flag definitions are similar to argparse, although they are defined on a global namespace. For instance defining a string flag looks like: ```$xslt from absl import flags flags.DEFINE_string( name="my_flag", default="a_sensible_default", help="Here is what this flag does." ) ``` All three arguments are required, but default may be `None`. A common optional argument is short_name for defining abreviations. Certain `DEFINE_*` methods will have other required arguments. For instance `DEFINE_enum` requires the `enum_values` argument to be specified. ## Key Flags absl has the concept of a key flag. Any flag defined in `__main__` is considered a key flag by default. Key flags are displayed in `--help`, others only appear in `--helpfull`. In order to handle key flags that are defined outside the module in question, absl provides the `flags.adopt_module_key_flags()` method. This adds the key flags of a different module to one's own key flags. For example: ```$xslt File: flag_source.py --------------------------------------- from absl import flags flags.DEFINE_string(name="my_flag", default="abc", help="a flag.") ``` ```$xslt File: my_module.py --------------------------------------- from absl import app as absl_app from absl import flags import flag_source flags.adopt_module_key_flags(flag_source) def main(_): pass absl_app.run(main, [__file__, "-h"] ``` when `my_module.py` is run it will show the help text for `my_flag`. Because not all flags defined in a file are equally important, `official/utils/flags/core.py` (generally imported as flags_core) provides an abstraction for handling key flag declaration in an easy way through the `register_key_flags_in_core()` function, which allows a module to make a single `adopt_key_flags(flags_core)` call when using the util flag declaration functions. ## Validators Often the constraints on a flag are complicated. absl provides the validator decorator to allow one to mark a function as a flag validation function. Suppose we want users to provide a flag which is a palindrome. ```$xslt from absl import flags flags.DEFINE_string(name="pal_flag", short_name="pf", default="", help="Give me a palindrome") @flags.validator("pal_flag") def _check_pal(provided_pal_flag): return provided_pal_flag == provided_pal_flag[::-1] ``` Validators take the form that returning True (truthy) passes, and all others (False, None, exception) fail. ## Testing To test using absl, simply declare flags in the setupClass method of TensorFlow's TestCase. ```$xslt from absl import flags import tensorflow as tf def define_flags(): flags.DEFINE_string(name="test_flag", default="abc", help="an example flag") class BaseTester(unittest.TestCase): @classmethod def setUpClass(cls): super(BaseTester, cls).setUpClass() define_flags() def test_trivial(self): flags_core.parse_flags([__file__, "test_flag", "def"]) self.AssertEqual(flags.FLAGS.test_flag, "def") ```