9

I've been using the vanilla

def main():
    # Do stuff


if __name__ == '__main__':
    main()

but recently saw people doing

from absl import app

def main(_):
    # Do things

if __name__ == '__main__':
    app.run(main)

Abseil provides flags.FLAGS, but I've been using ArgumentParser, which works perfectly fine, so there is no win for Abseil in this aspect.

Then, why bother go the Abseil route?

PS: Related discussion on Reddit (which doesn't really answer this question): https://www.reddit.com/r/Python/comments/euhl81/is_using_googles_abseil_library_worth_the/

Ismael Padilla
  • 5,246
  • 4
  • 23
  • 35
Sibbs Gambling
  • 19,274
  • 42
  • 103
  • 174
  • 1
    I'm not sure I understand what you're asking for in this question. The `abseil` library seems to do similar stuff to `ArgumentParser`, but with its own syntax and style (and maybe integration with other tools?). But if you don't want to rewrite your argument handling code, I'm not sure what it offers you. So just like any other library, if you don't need it, don't use it. Is there something more to your question? I'm not really sure "is this library any good" is an appropriate Stack Overflow question. If you know "people" who are using `abseil` a lot, maybe you should ask them about it? – Blckknght Jul 31 '20 at 02:15
  • @Blckknght thx for the thoughtful comment. I was asking this question because this particular library seems to provide nothing more than what the basic Python already provides. I doubt this is really the case and wish to learn what I can gain by using this library. – Sibbs Gambling Jul 31 '20 at 02:18
  • Looking at the [documentation](https://abseil.io/docs/python/), the library also provides logging and testing features. The [`app.run` thing apparently also can useful if you use Bazel](https://abseil.io/docs/python/guides/app). – jamesdlin Aug 20 '20 at 01:48
  • Great question! – Key Jun Apr 08 '21 at 09:40
  • 2
    I am not sure what ArgumentParser does but I think what Absiel does is provide access to your command line arguments through all modules used in you program via the flags so you don't have to pass them around. – Brian Reinhold Jun 20 '22 at 19:34

1 Answers1

1

Consider a design pattern, where you are passing a json file (that contains say site-specific constants) at the cmd line as input to your Python script. Say,the json file contains immutable constants and you want to maintain it that way.

You want the constants from json file contents to be made available to all the modules within your project.

One way to do this is by implementing a central module that deserializes the json into a Python object. ABSL helps you to solve this by accessing (via the FLAGS) the input file in the central module and then storing it into a class variable so all modules across your project can use this.

Without ABSL, you would need to first argparse the input file in main module, then send it to the central module.

A code example of this can be something like: main.py:

from centralmod import DeserializeClass
import centralmod
from absl import flags
from absl import app

_JSON_FILE = flags.DEFINE_string("json_file", None, "Constants", short_name='j', required=True)


def scenario():
    import someothermodule
    someothermodule.do_something()


def populate_globalvar():
    centralmod.populate_somevar()
    deserialized_data = DeserializeClass.somevar


def main(argv):
    populate_globalvar()
    scenario()


if __name__ == '__main__':
    app.run(main)

centralmod.py:

from absl import flags
import json

FLAGS = flags.FLAGS


class DeserializeClass:
    @classmethod
    def get_value(cls, key):
        return DeserializeClass.somevar[key]


def populate_somevar():
    with open(FLAGS.json_file) as json_constants_fh:
        deserialized_data = json.load(json_constants_fh)
    setattr(DeserializeClass, 'somevar', deserialized_data)

and someothermod.py:

from centralmod import DeserializeClass
site_specific_consts = DeserializeClass.somevar

def do_something():
    print(f"\nScenario: Testing. The site-specific constants are:\n{site_specific_consts}")
    print(f"the value of key ssh_key_file is {DeserializeClass.get_value('ssh_key_file')}")
    print(f"the value of key nodes is {DeserializeClass.get_value('nodes')}")
Jcnars
  • 11
  • 3