3

Basic intended usage:

my_framework create Project_title /path/to/project

OR

my_framework create Project_title (ie. use current working directory)

OR

my_framework update (ie. update my_framework rather than creating a new project)

I know I can make name optional by providing it with a default, but, in reality name is not optional provided the user has entered create as the first argument.

Best solution I've come up with is to use a default value for name and then, if the argument name equals its default value, throw an error. But if there's a way to make argparse do this work for me I'd rather learn to do it.

Writing two scripts, my_framework_create and my_framework_update doesn't appeal to me aesthetically.

#!/usr/bin/env python


import argparse
import os
import shutil
from subprocess import call

template_path = "/usr/local/klibs/template"
parser = argparse.ArgumentParser("MY_FRAMEWORK CLI", description='Creates a new MY_FRAMEWORK project or updates MY_FRAMEWORK')
parser.add_argument('action', choices=['create', 'update'], type=str, help='<help text>')
parser.add_argument('name', type=str, help='<help text>')
parser.add_argument('path', default=os.getcwd(), nargs="?", type=str, help='<help text>')
args = parser.parse_args()

if args.action == "create":
    # do the create stuff

if args.action == "update":
    # do the update stuff
3
  • You want to use subparsers for this: docs.python.org/2/library/… Commented Jun 26, 2015 at 17:41
  • I do not fully understand the question. Why should my_framework called with update not require a name? Shouldn't it always require a name, in case a user has two of the frameworks? Commented Jun 26, 2015 at 17:46
  • Sorry; update applies to MY_FRAMEWORK not a project created therewith (ie. it basically checks for a new release on github and pulls it if one is found). Commented Jun 26, 2015 at 17:53

1 Answer 1

5

The best way to do this is with a subparser

An example from the docs:

>>> parser = argparse.ArgumentParser()
>>> subparsers = parser.add_subparsers(title='subcommands',
...                                    description='valid subcommands',
...                                    help='additional help')
>>> subparsers.add_parser('foo')
>>> subparsers.add_parser('bar')
>>> parser.parse_args(['-h'])
usage:  [-h] {foo,bar} ...

optional arguments:
  -h, --help  show this help message and exit

subcommands:
  valid subcommands

  {foo,bar}   additional help

In your case you would have create and update as separate subparsers.

Example:

def create(args):
    # do the create stuff
    print(args)


def update(args):
    # do the update stuff
    print(args)


parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers(title='subcommands',
                                   description='valid subcommands',
                                   help='additional help')

create_parser = subparsers.add_parser('create')
create_parser.add_argument('name', type=str)
create_parser.set_defaults(func=create)

update_parser = subparsers.add_parser('update')
update_parser.set_defaults(func=update)
Sign up to request clarification or add additional context in comments.

4 Comments

Elegant. And this will demand the subparser's arguments when create is the first argument whilst ignore additional arguments when update is entered?
@Jonline: yes, it will :) When update is entered it will go to the second subparser, with create it will go to the first. This should do exactly what you are looking for in a clean way :)
Yep I have this running now, charming solution. Two small syntactic bugs in your code (tried to edit but < 6 chars): update_parser subparsers.add_parser('update') needs = and both setdefaults should be snake case.
That's what you get for coding in a textarea I suppose. Without syntax highlighting I tend to make mistakes ;)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.