Search code examples
pythonoopsqlalchemyargparsetraceback

ArgParse ERROR. but working in Test.py file


My test.py file in create_assessment (and all the CRUD operations) are working, e.g. populating the database that I have created. However, the ArgParse command line, made to interact with the database, is failing in create_assessment because of the category area. Assessment-Category share a many-to-many relationship.

I believe the issue is due to the parser's category line (as shown in the TracebackError, but I haven't been able to figure this conundrum. The categories do exist in the db, the parser is not recognizing the categories, but recognizing them in the test.py file. It could be that args = parser.parse_args() isn't parsing correctly.

ERROR:

(venv)acks-MacBook-Pro:notssdb ack$ notssdb-cmd create_assessment 'Learning new things' 'this' dancinglady 'movie' ['Bats', 'Development', 'Swinging at nothing']
usage: API_ArgParse [-h]
                    {create_user,retrieve_user,update_user,update_user_lastname,delete_user,create_assessment,retrieve_assessment,update_assessment,delete_assessment,create_video,retrieve_video,update_video,update_video_url,delete_video,create_category,retrieve_category,update_category,delete_category,create_element,retrieve_element,update_element,delete_element,create_assessment_results,retrieve_assessment_results,delete_assessment_results,create_category_rating,retrieve_category_rating,update_category_rating,delete_category_rating,create_element_rating,retrieve_element_rating,update_element_rating,delete_element_rating,create_comment,retrieve_comment,update_comment,delete_comment}
                    ...
API_ArgParse: error: unrecognized arguments: Development, Swinging at nothing]

ADDED the parser = config.

Code:

parser = argparse.ArgumentParser(prog='API_ArgParse', description='Create, Read, Update, and Delete (CRUD) Interface Commands for NOTSSdb')
subparsers = parser.add_subparsers(dest='cmd', title='subcommands', description='type subcommand name with -h for more details : e.g. notssdb-cmd create_user -h', help='additional help')
api = ConvenienceAPI() 

# Create command for 'assessment'  
create_parser = subparsers.add_parser('create_assessment', help='create an assessment')
create_parser.add_argument('name', type=str, help='name of the assessment')
create_parser.add_argument('text', type=str, help='assessment text')
create_parser.add_argument('username', type=str, help='name of user')
create_parser.add_argument('videoname', type=str, help='name of video')
create_parser.add_argument('category_names', type=str, help='list all category names')#THIS LINE

# Parse the arguments
args = parser.parse_args()

api = ConvenienceAPI()
api_method = getattr(api, args.cmd)
arg_dict = vars(args)
del arg_dict['cmd']
api_method(**arg_dict)

Create_assessment method with category retrieval (convenience.py - inherits base):

class ConvenienceAPI(BaseAPI):          

    def create_assessment(self, name, text, username, videoname, category_names):
        user = self.retrieve_user(username)
        video = self.retrieve_video(videoname) 
        cat_objects = [self.retrieve_category(category_name) for category_name in category_names]
        return super(ConvenienceAPI, self).create_assessment(name, text, user, video, cat_objects) 

Retrieve method for category (base.py):

def retrieve_category(self, something_unique):
    if isinstance(something_unique, int):
        return self.session.query(Category).\
        filter(Category.category_id == something_unique).all() # multiple categories
    elif isinstance(something_unique, basestring):
        print(something_unique) # added 
        return self.session.query(Category).\
        filter(Category.category_name == something_unique).one()

Working test.py file example:

api.create_assessment('How to be a leader', 'better decisions', 'wizard', 'good leadership', ['Leadership', 'Decision-Making', 'Teamwork and Communication', 'Situation Awareness'])

Solution

  • The problem is the stuff in brackets. The comandline processor in the shell does not recognize them. Look at the sys.avgv that the parse works with.

    With a simple script that just echos the argv, your line produces:

    ['echoargv.py', 'create_assessment', 'Learning new things', 'this',
       'dancinglady', 'movie', '[Bats,', 'Development,', 'Swinging at nothing]']
    

    Notice the 2 strings in the error message:

    'Development,'
    'Swinging at nothing]'
    

    The positional 'category_names' gets '[Bats,', but there's no place to put the other strings.

    Putting extra quotes around the brackets, "['Bats', 'Development', 'Swinging at nothing']", would solve this, but assign that whole thing to 'category_names'. You'd then have to strip and parse it.

    Another option is to give 'category_names' a nargs='+' parameter and enter

    notssdb-cmd create_assessment 'Learning new things' 'this' dancinglady 'movie' 'Bats', 'Development', 'Swinging at nothing'