diff --git a/src/quantum/azext_quantum/_params.py b/src/quantum/azext_quantum/_params.py index 80e6fdf266c..ffa8222aea1 100644 --- a/src/quantum/azext_quantum/_params.py +++ b/src/quantum/azext_quantum/_params.py @@ -56,6 +56,7 @@ def load_arguments(self, _): job_input_format_type = CLIArgumentType(help='The format of the file to submit. Omit this parameter on Q# jobs.') job_output_format_type = CLIArgumentType(help='The expected job output format. Ignored on Q# jobs.') entry_point_type = CLIArgumentType(help='The entry point for the QIR program or circuit. Required for QIR. Ignored on Q# jobs.') + item_type = CLIArgumentType(help='The item index in a batching job.') with self.argument_context('quantum workspace') as c: c.argument('workspace_name', workspace_name_type) @@ -83,6 +84,7 @@ def load_arguments(self, _): c.argument('storage', storage_type) c.argument('no_build', no_build_type) c.argument('max_poll_wait_secs', max_poll_wait_secs_type) + c.argument('item', item_type) with self.argument_context('quantum job submit') as c: c.argument('job_params', job_params_type) diff --git a/src/quantum/azext_quantum/commands.py b/src/quantum/azext_quantum/commands.py index b8767268d79..4e929989ce5 100644 --- a/src/quantum/azext_quantum/commands.py +++ b/src/quantum/azext_quantum/commands.py @@ -117,6 +117,40 @@ def one(key, value): ])) return table + elif isinstance(results, list) and len(results) > 0 and 'reportData' in results[0]: + table = [] + + indices = range(len(results)) + + for group_index, group in enumerate(results[0]['reportData']['groups']): + table.append(OrderedDict([ + ("Label", f"---{group['title']}---"), + *[(f"{i}", '---') for i in indices] + ])) + + visited_entries = set() + + for entry in [entry for index in indices for entry in results[index]['reportData']['groups'][group_index]['entries']]: + label = entry['label'] + if label in visited_entries: + continue + visited_entries.add(label) + + row = [("Label", label)] + + for index in indices: + val = results[index] + for key in entry['path'].split("/"): + if key in val: + val = val[key] + else: + val = "N/A" + break + row.append((f"{index}", val)) + table.append(OrderedDict(row)) + + return table + elif 'errorData' in results: notFound = 'Not found' errorData = results['errorData'] diff --git a/src/quantum/azext_quantum/operations/job.py b/src/quantum/azext_quantum/operations/job.py index 73219cf489d..56bd88fe568 100644 --- a/src/quantum/azext_quantum/operations/job.py +++ b/src/quantum/azext_quantum/operations/job.py @@ -517,7 +517,23 @@ def _parse_blob_url(url): } -def output(cmd, job_id, resource_group_name, workspace_name, location): +def _validate_item(provided_value, num_items): + valid_item = 0 + error_message = f"--item parameter is not valid: {provided_value}" + error_recommendation = f"Must be a non-negative number less than {num_items}" + + try: + valid_item = int(provided_value) + except ValueError as e: + raise InvalidArgumentValueError(error_message, error_recommendation) from e + + if valid_item >= num_items: + raise InvalidArgumentValueError(error_message, error_recommendation) + + return valid_item + + +def output(cmd, job_id, resource_group_name, workspace_name, location, item=None): """ Get the results of running a Q# job. """ @@ -572,6 +588,13 @@ def output(cmd, job_id, resource_group_name, workspace_name, location): else: json_file.seek(0) # Reset the file pointer before loading data = json.load(json_file) + + # Consider item if it's a batch job, otherwise ignore + import builtins # list has been overriden as a function above + if item and isinstance(data, builtins.list): + item = _validate_item(item, len(data)) + return data[item] + return data