Search code examples
pythoncommand-line-argumentsoptparse

python - elegantly handle sequence of multiple arguments


Thus far I was handling multiple arguments via Optparse as a string, Eg:

--update_entities="host_group hostname entity_type entities2monitor"

where entities2monitor has variable arguments, grabbing them inside the callback function via (notice the [3:]),

host = value.split()
(host_group, hostname, entity_type, entities2monitor) = (host[0], host[1], host[2], host[3:])

But how should I approach it when I need to feed parameters of the following form into a callback? (I have control over the SQL which will generate the Optparse input string)

  • action_name: a space delimited string. (Eg: 'TEST ACTION')

  • hostgroup: a string

  • actions_holder: a list comprised by:

    • condition_type (string)
    • condition_operator (string)
    • condition_filter (space delimited string)

and

  • operations_holder: a list comprised by:
    • operation_type: (string)
    • operation_sendto: (string)

Example:

--create_action='''TEST ACTION | client_service_platform | "CONDITION_TYPE_TRIGGER_NAME CONDITION_OPERATOR_LIKE Weighted Successful" "CONDITION_TYPE_HOST CONDITION_OPERATOR_EQUAL host01" | "OPERATION_TYPE_MESSAGE userid1" "OPERATION_TYPE_EMAIL userid1" "OPERATION_TYPE_EMAIL userid2"'''

This is what I have so far,

actions_splits = actions_parameters.split(" | ")
action_name = actions_splits[0]
hostgroup = actions_splits[1]
actions_holder = actions_splits[2].strip('"').split('" "')
operations_holder = actions_splits[3].strip('"').split('" "')

which kind of works but is there a more seamless way to get these parameters?


Solution

  • what about using a namedtuple here:

    import collections
    Action = collections.namedtuple('Action', 'name hostgroup actions operations')
    

    use ; and , to differentiate your command components:

    command= "TEST ACTION;client_service_platform;CONDITION_TYPE_TRIGGER_NAME CONDITION_OPERATOR_LIKE Weighted Successful,CONDITION_TYPE_HOST CONDITION_OPERATOR_EQUAL tt1scp1; OPERATION_TYPE_MESSAGE userid1,OPERATION_TYPE_EMAIL userid1,OPERATION_TYPE_EMAIL userid2"
    

    now instantiate with:

    a = Action(*command.split(';'))
    

    which allows you to call:

    a.name
    a.hostgroup
    a.actions.split(',')
    a.operations.split(',')
    

    of which the elements of last two can then be split again with just .split()