Repository: ansible/awx
File: awxkit/awxkit/cli/custom.py (Python)

Code before:
        if with_pk:
            parser.choices[self.action].add_argument('id', type=functools.partial(pk_or_name, None, self.resource, page=self.page), help='')
        parser.choices[self.action].add_argument('--monitor', action='store_true', help='If set, prints stdout of the launched job until it finishes.')
        parser.choices[self.action].add_argument('--action-timeout', type=int, help='If set with --monitor or --wait, time out waiting on job completion.')
        parser.choices[self.action].add_argument('--wait', action='store_true', help='If set, waits until the launched job finishes.')
        parser.choices[self.action].add_argument(
            '--interval',
            type=float,
            help='If set with --monitor or --wait, amount of time to wait in seconds between api calls. Minimum value is 2.5 seconds to avoid overwhelming the api',
        )

        launch_time_options = self.page.connection.options(self.options_endpoint)
        if launch_time_options.ok:
            launch_time_options = launch_time_options.json()['actions']['POST']
            resource_options_parser.options['LAUNCH'] = launch_time_options
            resource_options_parser.build_query_arguments(self.action, 'LAUNCH')

    def monitor(self, response, **kwargs):
        mon = monitor_workflow if response.type == 'workflow_job' else monitor
        if kwargs.get('monitor') or kwargs.get('wait'):
            status = mon(
                response,
                self.page.connection.session,
                print_stdout=not kwargs.get('wait'),
                action_timeout=kwargs.get('action_timeout'),
                interval=kwargs.get('interval'),
            )
            if status:
                response.json['status'] = status
                if status in ('failed', 'error'):
                    setattr(response, 'rc', 1)
        return response

    def perform(self, **kwargs):
        monitor_kwargs = {
            'monitor': kwargs.pop('monitor', False),
            'wait': kwargs.pop('wait', False),
            'action_timeout': kwargs.pop('action_timeout', False),
            'interval': kwargs.pop('interval', 5),
        }
        response = self.page.get().related.get(self.action).post(kwargs)
        self.monitor(response, **monitor_kwargs)
        return response


class JobTemplateLaunch(Launchable, CustomAction):
    action = 'launch'
    resource = 'job_templates'


class BulkJobLaunch(Launchable, CustomAction):

Review comment (suggestion):
`kwargs.get('interval')` will return `None` if this is called with no keyword arguments... in case that wasn't already painfully clear. And `None` is not an integer where `mon` here assumes an integer value.

Code after:
        if with_pk:
            parser.choices[self.action].add_argument('id', type=functools.partial(pk_or_name, None, self.resource, page=self.page), help='')
        parser.choices[self.action].add_argument('--monitor', action='store_true', help='If set, prints stdout of the launched job until it finishes.')
        parser.choices[self.action].add_argument('--action-timeout', type=int, help='If set with --monitor or --wait, time out waiting on job completion.')
        parser.choices[self.action].add_argument('--wait', action='store_true', help='If set, waits until the launched job finishes.')
        parser.choices[self.action].add_argument(
            '--interval',
            type=float,
            help='If set with --monitor or --wait, amount of time to wait in seconds between api calls. Minimum value is 2.5 seconds to avoid overwhelming the api',
        )

        launch_time_options = self.page.connection.options(self.options_endpoint)
        if launch_time_options.ok:
            launch_time_options = launch_time_options.json()['actions']['POST']
            resource_options_parser.options['LAUNCH'] = launch_time_options
            resource_options_parser.build_query_arguments(self.action, 'LAUNCH')

    def monitor(self, response, **kwargs):
        mon = monitor_workflow if response.type == 'workflow_job' else monitor
        if kwargs.get('monitor') or kwargs.get('wait'):
            monitor_kwargs = {'print_stdout': bool(not kwargs.get('wait'))}
            for key in ('action_timeout', 'interval'):
                if key in kwargs:
                    monitor_kwargs[key] = kwargs[key]
            status = mon(response, self.page.connection.session, **monitor_kwargs)
            if status:
                response.json['status'] = status
                if status in ('failed', 'error'):
                    setattr(response, 'rc', 1)
        return response

    def perform(self, **kwargs):
        monitor_kwargs = {
            'monitor': kwargs.pop('monitor', False),
            'wait': kwargs.pop('wait', False),
            'action_timeout': kwargs.pop('action_timeout', False),
            'interval': kwargs.pop('interval', 5),
        }
        response = self.page.get().related.get(self.action).post(kwargs)
        self.monitor(response, **monitor_kwargs)
        return response


class JobTemplateLaunch(Launchable, CustomAction):
    action = 'launch'
    resource = 'job_templates'


class BulkJobLaunch(Launchable, CustomAction):
    action = 'job_launch'
    resource = 'bulk'