diff --git a/src/quantum/azext_quantum/_params.py b/src/quantum/azext_quantum/_params.py index 5f662e0c7ca..9e473afd3bd 100644 --- a/src/quantum/azext_quantum/_params.py +++ b/src/quantum/azext_quantum/_params.py @@ -6,8 +6,10 @@ # pylint: disable=line-too-long,protected-access,no-self-use,too-many-statements import argparse +import json from knack.arguments import CLIArgumentType -from azure.cli.core.azclierror import InvalidArgumentValueError +from azure.cli.core.azclierror import InvalidArgumentValueError, CLIError +from azure.cli.core.util import shell_safe_json_parse class JobParamsAction(argparse._AppendAction): @@ -19,10 +21,14 @@ def get_action(self, values, option_string): params = {} for item in values: try: - key, value = item.split('=', 1) - params[key] = value - except ValueError as e: - raise InvalidArgumentValueError('Usage error: {} KEY=VALUE [KEY=VALUE ...]'.format(option_string)) from e + json_obj = shell_safe_json_parse(item) + params.update(json_obj) + except CLIError as e: + try: + key, value = item.split('=', 1) + params[key] = value + except ValueError as e: + raise InvalidArgumentValueError('Usage error: {} KEY=VALUE [KEY=VALUE ...], json string, or @file expected'.format(option_string)) from e return params @@ -34,7 +40,7 @@ def load_arguments(self, _): project_type = CLIArgumentType(help='The location of the Q# project to submit. Defaults to current folder.') job_name_type = CLIArgumentType(help='A friendly name to give to this run of the program.') job_id_type = CLIArgumentType(options_list=['--job-id', '-j'], help='Job unique identifier in GUID format.') - job_params_type = CLIArgumentType(options_list=['--job-params'], help='Job parameters passed to the target as a list of key=value pairs.', action=JobParamsAction, nargs='+') + job_params_type = CLIArgumentType(options_list=['--job-params'], help='Job parameters passed to the target as a list of key=value pairs, json string, or `@{file}` with json content.', action=JobParamsAction, nargs='+') target_capability_type = CLIArgumentType(options_list=['--target-capability'], help='Target-capability parameter passed to the compiler.') shots_type = CLIArgumentType(help='The number of times to run the Q# program on the given target.') no_build_type = CLIArgumentType(help='If specified, the Q# program is not built before submitting.') diff --git a/src/quantum/azext_quantum/commands.py b/src/quantum/azext_quantum/commands.py index 8b076a1b457..abcb7116e23 100644 --- a/src/quantum/azext_quantum/commands.py +++ b/src/quantum/azext_quantum/commands.py @@ -98,6 +98,25 @@ def one(key, value): histogram = results['histogram'] return [one(key, histogram[key]) for key in histogram] + elif 'reportData' in results: + table = [] + for group in results['reportData']['groups']: + table.append(OrderedDict([ + ("Label", (f"---{group['title']}---")), + ('Value', '---'), + ('Description', '---') + ])) + for entry in group['entries']: + val = results + for key in entry['path'].split("/"): + val = val[key] + table.append(OrderedDict([ + ("Label", entry['label']), + ('Value', val), + ('Description', entry['description']) + ])) + 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 1ca7b84dd6c..dc0e8a051a8 100644 --- a/src/quantum/azext_quantum/operations/job.py +++ b/src/quantum/azext_quantum/operations/job.py @@ -6,6 +6,7 @@ # pylint: disable=redefined-builtin,bare-except,inconsistent-return-statements import logging +import json import knack.log from azure.cli.core.azclierror import (FileOperationError, AzureInternalError, @@ -142,7 +143,11 @@ def _generate_submit_args(program_args, ws, target, token, project, job_name, sh if job_params: args.append("--job-params") for k, v in job_params.items(): - args.append(f"{k}={v}") + if isinstance(v, str): + # If value is string type already, do not use json.dumps(), since it will add extra escapes to the string + args.append(f"{k}={v}") + else: + args.append(f"{k}={json.dumps(v)}") args.extend(program_args) @@ -265,7 +270,7 @@ def output(cmd, job_id, resource_group_name=None, workspace_name=None, location= if len(lines) == 0: return - if job.target.startswith("microsoft.simulator"): + if job.target.startswith("microsoft.simulator") and job.target != "microsoft.simulator.resources-estimator": result_start_line = len(lines) - 1 is_result_string = lines[-1].endswith('"') if is_result_string: