python - call_command argument is required -
i'm trying use django's call_command
in manner similar this question without answer.
the way i'm calling is:
args = [] kwargs = { 'solr_url': 'http://127.0.0.1:8983/solr/collection1', 'type': 'opinions', 'update': true, 'everything': true, 'do_commit': true, 'traceback': true, } call_command('cl_update_index', **kwargs)
in theory, should work, according the docs. doesn't work, doesn't.
here's add_arguments
method command class:
def add_arguments(self, parser): parser.add_argument( '--type', type=valid_obj_type, required=true, help='because solr indexes loosely bound database, ' 'commands require correct model provided in ' 'argument. current choices "audio" or "opinions".' ) parser.add_argument( '--solr-url', required=true, type=str, help='when swapping cores, can valuable use temporary ' 'solr url, overriding default value that\'s in ' 'settings, e.g., http://127.0.0.1:8983/solr/swap_core' ) actions_group = parser.add_mutually_exclusive_group() actions_group.add_argument( '--update', action='store_true', default=false, help='run command in update mode. use add or update ' 'items.' ) actions_group.add_argument( '--delete', action='store_true', default=false, help='run command in delete mode. use remove items ' 'from index. note not delete items ' 'the index not continue exist in database.' ) parser.add_argument( '--optimize', action='store_true', default=false, help='run optimize command against current index after ' 'any updates or deletions completed.' ) parser.add_argument( '--do-commit', action='store_true', default=false, help='performs simple commit , nothing more.' ) act_upon_group = parser.add_mutually_exclusive_group() act_upon_group.add_argument( '--everything', action='store_true', default=false, help='take action on in database', ) act_upon_group.add_argument( '--query', help='take action on items fulfilling query. queries should ' 'formatted python dicts such as: "{\'court_id\':\'haw\'}"' ) act_upon_group.add_argument( '--items', type=int, nargs='*', help='take action on list of items using single ' 'celery task' ) act_upon_group.add_argument( '--datetime', type=valid_date_time, help='take action on items newer date (yyyy-mm-dd) or ' 'date , time (yyyy-mm-dd hh:mm:ss)' )
no matter here, get:
commanderror: error: argument --type required
any ideas? if you're curious, can see entire code here.
you defined argument '--type'
flag, , made required
. command line require string or strings --type avalue
.
this looks relevant part of call_command
:
def call_command(name, *args, **options): .... parser = command.create_parser('', name) if command.use_argparse: # use `dest` option name parser option opt_mapping = {sorted(s_opt.option_strings)[0].lstrip('-').replace('-', '_'): s_opt.dest s_opt in parser._actions if s_opt.option_strings} arg_options = {opt_mapping.get(key, key): value key, value in options.items()} defaults = parser.parse_args(args=args) defaults = dict(defaults._get_kwargs(), **arg_options) # move positional args out of options mimic legacy optparse args = defaults.pop('args', ())
it creates parser, using it's own arguments plus ones add.
parser._actions if s_opt.option_strings
arguments (actions) take option flag (start - or --). opt_mapping
map between flag strings (minus leading -s) , 'dest' attribute.
arg_options
converts **kwargs
can merged parser
output.
defaults = parser.parse_args(args=args)
actual parsing. is, it's code uses argparse
parsing mechanism. *args
part of call simulates generating sys.argv[1:]
interactive call.
based on reading think should work:
args = [ '--solr-url', 'http://127.0.0.1:8983/solr/collection1', '--type', 'opinions', '--update' '--everything', '--do_commit', '--traceback', } call_command('cl_update_index', *args)
instead of **kwargs
passing in values list of strings. or 2 required arguments passed in args
, , rest in **kwargs
.
args = ['--solr-url', 'http://127.0.0.1:8983/solr/collection1', '--type', 'opinions'] kwargs = { 'update': true, 'everything': true, 'do_commit': true, 'traceback': true, } call_command('cl_update_index', *args, **kwargs)
if argument required
needs passed in through *args
. **kwargs
bypass parser, causing object missing arguments.
i've downloaded latest django
, haven't installed it. here's simulation of call_command
should test calling options:
import argparse def call_command(name, *args, **options): """ calls given command, given options , args/kwargs. standalone simulation of django.core.mangement call_command """ command = name """ .... """ # simulate argument parsing option defaults (see #10080 details). parser = command.create_parser('', name) if command.use_argparse: # use `dest` option name parser option opt_mapping = {sorted(s_opt.option_strings)[0].lstrip('-').replace('-', '_'): s_opt.dest s_opt in parser._actions if s_opt.option_strings} arg_options = {opt_mapping.get(key, key): value key, value in options.items()} defaults = parser.parse_args(args=args) defaults = dict(defaults._get_kwargs(), **arg_options) # move positional args out of options mimic legacy optparse args = defaults.pop('args', ()) else: # legacy optparse method defaults, _ = parser.parse_args(args=[]) defaults = dict(defaults.__dict__, **options) if 'skip_checks' not in options: defaults['skip_checks'] = true return command.execute(*args, **defaults) class basecommand(): def __init__(self): self.use_argparse = true self.stdout= sys.stdout self.stderr=sys.stderr def execute(self, *args, **kwargs): self.handle(*args, **kwargs) def handle(self, *args, **kwargs): print('args: ', args) print('kwargs: ', kwargs) def create_parser(self, *args, **kwargs): parser = argparse.argumentparser() self.add_arguments(parser) return parser def add_arguments(self, parser): parser.add_argument('--type', required=true) parser.add_argument('--update', action='store_true') parser.add_argument('--optional', default='default') parser.add_argument('foo') parser.add_argument('args', nargs='*') if __name__=='__main__': testcmd = basecommand() # testcmd.execute('one','tow', three='four') call_command(testcmd, '--type','typevalue','foovalue', 'argsvalue', update=true) args = ['--type=argvalue', 'foovalue', '1', '2'] kwargs = { 'solr_url': 'http://127.0.0.1...', 'type': 'opinions', 'update': true, 'everything': true, } call_command(testcmd, *args, **kwargs)
which produces:
python3 stack32036562.py args: ('argsvalue',) kwargs: {'optional': 'default', 'type': 'typevalue', 'update': true, 'skip_checks': true, 'foo': 'foovalue'} args: ('1', '2') kwargs: {'optional': 'default', 'update': true, 'foo': 'foovalue', 'type': 'opinions', 'skip_checks': true, 'everything': true, 'solr_url': 'http://127.0.0.1...'}
with bunch of stubs, can make cl
command
work basecommand
, , following call works:
clupdate = command() args = ['--type','opinions','--solr-url','dummy'] kwargs = { 'solr_url': 'http://127.0.0.1:8983/solr/collection1', #'type': 'opinions', 'update': true, 'everything': true, 'do_commit': true, 'traceback': true, } call_command(clupdate, *args, **kwargs)
performing stub everything
.
running in update mode... args: () options: {'type': 'opinions', 'query': none, 'solr_url': 'http://127.0.0.1:8983/solr/collection1', 'items': none, 'do_commit': true, 'update': true, 'delete': false, 'datetime': none, 'optimize': false, 'skip_checks': true, 'everything': true, 'traceback': true}
Comments
Post a Comment