Skip to content

Commit

Permalink
{Core} Add dict transformation for typespec generated SDKs (#30339)
Browse files Browse the repository at this point in the history
* Add dict transformation for typespec generated SDKs

* camel case

* exclude autorest model

* fix typo

* remove keyvault security domain output transformer

* rewrite knack.todict

* remove unused func

* fix typo
  • Loading branch information
evelyn-ys authored Dec 2, 2024
1 parent 616496b commit f8cc79f
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 18 deletions.
3 changes: 2 additions & 1 deletion src/azure-cli-core/azure/cli/core/commands/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
from knack.preview import ImplicitPreviewItem, PreviewItem, resolve_preview_info
from knack.experimental import ImplicitExperimentalItem, ExperimentalItem, resolve_experimental_info
from knack.log import get_logger, CLILogging
from knack.util import CLIError, CommandResultItem, todict
from knack.util import CLIError, CommandResultItem
from knack.events import EVENT_INVOKER_TRANSFORM_RESULT
from knack.validators import DefaultStr

Expand Down Expand Up @@ -715,6 +715,7 @@ def _run_job(self, expanded_arg, cmd_copy):
elif _is_paged(result):
result = list(result)

from ..util import todict
result = todict(result, AzCliCommandInvoker.remove_additional_prop_layer)

event_data = {'result': result}
Expand Down
36 changes: 35 additions & 1 deletion src/azure-cli-core/azure/cli/core/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
from urllib.request import urlopen

from knack.log import get_logger
from knack.util import CLIError, to_snake_case
from knack.util import CLIError, to_snake_case, to_camel_case

logger = get_logger(__name__)

Expand Down Expand Up @@ -624,6 +624,40 @@ def b64_to_hex(s):
return hex_data


def todict(obj, post_processor=None):
"""
Convert an object to a dictionary. Use 'post_processor(original_obj, dictionary)' to update the
dictionary in the process
"""
from datetime import date, time, datetime, timedelta
from enum import Enum
if isinstance(obj, dict):
result = {k: todict(v, post_processor) for (k, v) in obj.items()}
return post_processor(obj, result) if post_processor else result
if isinstance(obj, list):
return [todict(a, post_processor) for a in obj]
if isinstance(obj, Enum):
return obj.value
if isinstance(obj, (date, time, datetime)):
return obj.isoformat()
if isinstance(obj, timedelta):
return str(obj)
# This is the only difference with knack.util.todict because for typespec generated SDKs
# The base model stores data in obj.__dict__['_data'] instead of in obj.__dict__
# We need to call obj.as_dict() to extract data for this kind of model
if hasattr(obj, 'as_dict') and not hasattr(obj, '_attribute_map'):
result = {to_camel_case(k): todict(v, post_processor) for k, v in obj.as_dict().items()}
return post_processor(obj, result) if post_processor else result
if hasattr(obj, '_asdict'):
return todict(obj._asdict(), post_processor)
if hasattr(obj, '__dict__'):
result = {to_camel_case(k): todict(v, post_processor)
for k, v in obj.__dict__.items()
if not callable(v) and not k.startswith('_')}
return post_processor(obj, result) if post_processor else result
return obj


def random_string(length=16, force_lower=False, digits_only=False):
from string import ascii_letters, digits, ascii_lowercase
from random import choice
Expand Down
10 changes: 0 additions & 10 deletions src/azure-cli/azure/cli/command_modules/keyvault/_transformers.py
Original file line number Diff line number Diff line change
Expand Up @@ -474,13 +474,3 @@ def transform_certificate_issuer_admin_list(result, **command_args):
} for contact in admin_contacts]
return ret
return result


def transform_security_domain_output(result, **command_args):
if not result or isinstance(result, dict):
return result
ret = {
'status': getattr(result, 'status', None),
'statusDetails': getattr(result, 'status_details', None)
}
return ret
10 changes: 4 additions & 6 deletions src/azure-cli/azure/cli/command_modules/keyvault/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
get_client, get_client_factory, Clients, is_azure_stack_profile)

from azure.cli.command_modules.keyvault._transformers import (
filter_out_managed_resources, transform_security_domain_output,
filter_out_managed_resources,
multi_transformers, transform_key_decryption_output, keep_max_results, transform_key_list_output,
transform_key_output, transform_key_encryption_output, transform_key_random_output,
transform_secret_list, transform_deleted_secret_list, transform_secret_set,
Expand Down Expand Up @@ -145,11 +145,9 @@ def load_command_table(self, _):
with self.command_group('keyvault security-domain', data_security_domain_entity.command_type) as g:
g.keyvault_custom('init-recovery', 'security_domain_init_recovery')
g.keyvault_custom('restore-blob', 'security_domain_restore_blob')
g.keyvault_custom('upload', 'security_domain_upload', supports_no_wait=True,
transform=transform_security_domain_output)
g.keyvault_custom('download', 'security_domain_download', supports_no_wait=True,
transform=transform_security_domain_output)
g.keyvault_custom('wait', '_wait_security_domain_operation', transform=transform_security_domain_output)
g.keyvault_custom('upload', 'security_domain_upload', supports_no_wait=True)
g.keyvault_custom('download', 'security_domain_download', supports_no_wait=True)
g.keyvault_custom('wait', '_wait_security_domain_operation')

with self.command_group('keyvault key', data_key_entity.command_type) as g:
g.keyvault_custom('create', 'create_key', transform=transform_key_output, validator=validate_key_create)
Expand Down

0 comments on commit f8cc79f

Please sign in to comment.