I want to be able to call this script with a single id, a list of ids, a url, or a csv file.

Is there a simple way to express it? Here I’ve only added options to call the script with nothing, a single id or a list of ids. But it already looks too messy for my taste.

def parse_args():
    try:
        if len(sys.argv) == 3:
            # List
            if sys.argv[2].startswith("[") and sys.argv[2].endswith("]"):
                work_ids = sys.argv[2].strip("[").strip("]").split(",")
                download_ao3_fics_and_import_tags(work_ids)
            else: # single work_id
                download_ao3_fic_and_import_tags(sys.argv[2])
        elif len(sys.argv) != 3:
            main()
        else:
            usage()
    except Exception:
        usage()
  • Arthur Besse@lemmy.ml
    link
    fedilink
    arrow-up
    3
    ·
    2 years ago

    i highly recommend using click for all of your argument parsing needs.

    click makes it easy to build very nice commandline interfaces.

    You can install it on debian/ubuntu with apt install python3-click and it is also packaged in many other distributions, making it a very reasonable dependency to add to any program. Aside from that missing piece of information (and a silly recommendation to install it via pip), its quickstart is good and the place to start.

  • pancake@lemmy.ml
    link
    fedilink
    arrow-up
    2
    arrow-down
    1
    ·
    2 years ago

    I’d use regex myself, but I doubt it would make the code much cleaner, maybe slightly shorter…

    • zergling_man@lemmy.perthchat.org
      link
      fedilink
      arrow-up
      1
      ·
      2 years ago

      This is exactly what I was getting at. It would actually be a lot cleaner, because capture; pull them all out to a list and iterate (or just shove it where it needs to go). If it’s empty it’ll fix itself shortly.

  • thann@heapoverflow.mlM
    link
    fedilink
    arrow-up
    2
    arrow-down
    1
    ·
    2 years ago

    you have a really simple use-case, so you probably don’t need and argument parsing lib, which I would normally recommend…

    You can just iterate through the arguments array and categorize them by type, then add them to the appropriate collection to be handled later.

    Something like this:

    ids = []
    urls = []
    csvs = []
    for arg in sys.argv:
      if arg.startswith('http'):
        urls.push(arg)
      else if arg.endswith('.csv'):
        csvs.push(arg)
      else:
        ids.push(arg)
    
    • Arthur Besse@lemmy.ml
      link
      fedilink
      arrow-up
      2
      ·
      2 years ago

      That approach would work if you replace push with append (there is no push method on Python lists) but even for a simple use case, if you’re writing a program for other people to use it is nicer to use an argument parsing library like click to get input validation, useful error messages (eg telling you when a file argument is non existent, or permission denied, etc), and generate output for --help etc.

      • thann@heapoverflow.mlM
        link
        fedilink
        arrow-up
        2
        ·
        2 years ago

        nice catch!
        I constantly switch between Js and python, and cant remember the differences lol
        yeah, the --help generation is a very convenient part of the libs.
        I just wrote this to demonstrate the simplest possible answer.