-
Notifications
You must be signed in to change notification settings - Fork 61
switch structure of multiapi section into classes instead of dicts #755
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 22 commits
Commits
Show all changes
25 commits
Select commit
Hold shift + click to select a range
1af685a
initial reordering to pass metadata to code model
iscai-msft fb6cfca
introduce CodeModel model
iscai-msft 95d1ac4
change some values to properties of the MultiAPI class
iscai-msft 1de62dc
add client model
iscai-msft 2407898
add config model
iscai-msft a567662
add operation group model
iscai-msft 17ba92d
add operation mixin group
iscai-msft 354fea5
add mixin operation
iscai-msft b9575b9
sort operations and operaiton groups by name
iscai-msft 2d65d35
Merge branch 'autorestv3' of https://github.com/Azure/autorest.python…
iscai-msft 3c78add
move _get_default_api_version_from_list to utils
iscai-msft f73d119
move last_rt_list to code model
iscai-msft 4bcb3da
trim operations from main init
iscai-msft f452b09
add global parameters model
iscai-msft c081016
add final necessary properties from multiapi init to code model
iscai-msft 6d43a9a
switch serializer to serializer init file, remove conf
iscai-msft 082b953
change templates to accept code_model
iscai-msft 32bbd38
fix mypy and pylint
iscai-msft 25aa848
fix removal of _extract_version from utils to client model file
iscai-msft bac6b3e
Merge branch 'autorestv3' of https://github.com/Azure/autorest.python…
iscai-msft 9c283c9
differentiate operation group class name by api version
iscai-msft 5d59d67
Merge branch 'autorestv3' of https://github.com/Azure/autorest.python…
iscai-msft aaa830f
Merge branch 'autorestv3' of https://github.com/Azure/autorest.python…
iscai-msft 8b7608e
get rid of unnecessary class inheritance from object
iscai-msft 83b84f1
Merge branch 'autorestv3' of https://github.com/Azure/autorest.python…
iscai-msft File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,55 @@ | ||
| # ------------------------------------------------------------------------- | ||
| # Copyright (c) Microsoft Corporation. All rights reserved. | ||
| # Licensed under the MIT License. See License.txt in the project root for | ||
| # license information. | ||
| # -------------------------------------------------------------------------- | ||
| import sys | ||
| from typing import Any, Dict, List | ||
| from pathlib import Path | ||
|
|
||
| def _extract_version(metadata_json: Dict[str, Any], version_path: Path) -> str: | ||
| version = metadata_json['chosen_version'] | ||
| total_api_version_list = metadata_json['total_api_version_list'] | ||
| if not version: | ||
| if total_api_version_list: | ||
| sys.exit( | ||
| f"Unable to match {total_api_version_list} to label {version_path.stem}" | ||
| ) | ||
| else: | ||
| sys.exit( | ||
| f"Unable to extract api version of {version_path.stem}" | ||
| ) | ||
| return version | ||
|
|
||
| class Client(): | ||
| def __init__( | ||
| self, | ||
| azure_arm: bool, | ||
| default_version_metadata: Dict[str, Any], | ||
| version_path_to_metadata: Dict[Path, Dict[str, Any]] | ||
| ): | ||
| self.name = default_version_metadata["client"]["name"] | ||
| self.pipeline_client = "ARMPipelineClient" if azure_arm else "PipelineClient" | ||
| self.filename = default_version_metadata["client"]["filename"] | ||
| self.base_url = default_version_metadata["client"]["base_url"] | ||
| self.description = default_version_metadata["client"]["description"] | ||
| self.client_side_validation = default_version_metadata["client"]["client_side_validation"] | ||
| self.version_path_to_metadata = version_path_to_metadata | ||
|
|
||
| @property | ||
| def custom_base_url_to_api_version(self) -> Dict[str, List[str]]: | ||
| custom_base_url_to_api_version: Dict[str, List[str]] = {} | ||
| for version_path, metadata_json in self.version_path_to_metadata.items(): | ||
| custom_base_url = metadata_json["client"]["custom_base_url"] | ||
| version = _extract_version(metadata_json, version_path) | ||
| custom_base_url_to_api_version.setdefault(custom_base_url, []).append(version) | ||
| return custom_base_url_to_api_version | ||
|
|
||
| @property | ||
| def has_lro_operations(self) -> bool: | ||
| has_lro_operations = False | ||
| for _, metadata_json in self.version_path_to_metadata.items(): | ||
| current_client_has_lro_operations = metadata_json["client"]["has_lro_operations"] | ||
| if current_client_has_lro_operations: | ||
| has_lro_operations = True | ||
| return has_lro_operations | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,131 @@ | ||
| # ------------------------------------------------------------------------- | ||
| # Copyright (c) Microsoft Corporation. All rights reserved. | ||
| # Licensed under the MIT License. See License.txt in the project root for | ||
| # license information. | ||
| # -------------------------------------------------------------------------- | ||
|
|
||
| from typing import Any, Dict, List, Optional | ||
| from pathlib import Path | ||
| from .client import Client | ||
| from .config import Config | ||
| from .operation_group import OperationGroup | ||
| from .operation_mixin_group import OperationMixinGroup | ||
| from .global_parameters import GlobalParameters | ||
| from ..utils import _get_default_api_version_from_list | ||
|
|
||
| class CodeModel(object): # pylint: disable=too-many-instance-attributes | ||
iscai-msft marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| def __init__( | ||
| self, | ||
| module_name: str, | ||
| package_name: str, | ||
| default_api_version: str, | ||
| preview_mode: bool, | ||
| default_version_metadata: Dict[str, Any], | ||
| mod_to_api_version: Dict[str, str], | ||
| version_path_to_metadata: Dict[Path, Dict[str, Any]], | ||
| user_specified_default_api: Optional[str] = None | ||
| ): | ||
| self.module_name = module_name | ||
| self.package_name = package_name | ||
| self.mod_to_api_version = mod_to_api_version | ||
| self.default_api_version = default_api_version | ||
| self.preview_mode = preview_mode | ||
| self.azure_arm = default_version_metadata["client"]["azure_arm"] | ||
| self.default_version_metadata = default_version_metadata | ||
| self.version_path_to_metadata = version_path_to_metadata | ||
| self.service_client = Client(self.azure_arm, default_version_metadata, version_path_to_metadata) | ||
| self.config = Config(default_version_metadata) | ||
| self.operation_mixin_group = OperationMixinGroup(version_path_to_metadata, default_api_version) | ||
| self.global_parameters = GlobalParameters(default_version_metadata["global_parameters"]) | ||
| self.user_specified_default_api = user_specified_default_api | ||
|
|
||
| @property | ||
| def operation_groups(self) -> List[OperationGroup]: | ||
| operation_groups: List[OperationGroup] = [] | ||
| for version_path, metadata_json in self.version_path_to_metadata.items(): | ||
| if not metadata_json.get('operation_groups'): | ||
| continue | ||
| operation_groups_metadata = metadata_json['operation_groups'] | ||
| for operation_group_name, operation_group_class_name in operation_groups_metadata.items(): | ||
| try: | ||
| operation_group = [og for og in operation_groups if og.name == operation_group_name][0] | ||
| except IndexError: | ||
| operation_group = OperationGroup(operation_group_name) | ||
| operation_groups.append(operation_group) | ||
| operation_group.append_available_api(version_path.name) | ||
| operation_group.append_api_class_name_pair(version_path.name, operation_group_class_name) | ||
| operation_groups.sort(key=lambda x: x.name) | ||
| return operation_groups | ||
|
|
||
| @property | ||
| def last_rt_list(self) -> Dict[str, str]: | ||
| """Build the a mapping RT => API version if RT doesn't exist in latest detected API version. | ||
|
|
||
| Example: | ||
| last_rt_list = { | ||
| 'check_dns_name_availability': '2018-05-01' | ||
| } | ||
|
|
||
| There is one subtle scenario if PREVIEW mode is disabled: | ||
| - RT1 available on 2019-05-01 and 2019-06-01-preview | ||
| - RT2 available on 2019-06-01-preview | ||
| - RT3 available on 2019-07-01-preview | ||
|
|
||
| Then, if I put "RT2: 2019-06-01-preview" in the list, this means I have to make | ||
| "2019-06-01-preview" the default for models loading (otherwise "RT2: 2019-06-01-preview" won't work). | ||
| But this likely breaks RT1 default operations at "2019-05-01", with default models at "2019-06-01-preview" | ||
| since "models" are shared for the entire set of operations groups (I wished models would be split by | ||
| operation groups, but meh, that's not the case) | ||
|
|
||
| So, until we have a smarter Autorest to deal with that, only preview RTs which do not share models with | ||
| a stable RT can be added to this map. In this case, RT2 is out, RT3 is in. | ||
| """ | ||
|
|
||
| def there_is_a_rt_that_contains_api_version(rt_dict, api_version): | ||
| "Test in the given api_version is is one of those RT." | ||
| for rt_api_version in rt_dict.values(): | ||
| if api_version in rt_api_version: | ||
| return True | ||
| return False | ||
|
|
||
| last_rt_list = {} | ||
|
|
||
| # First let's map operation groups to their available APIs | ||
| versioned_dict = { | ||
| operation_group.name: operation_group.available_apis | ||
| for operation_group in self.operation_groups | ||
| } | ||
|
|
||
| # Now let's also include mixins to their available APIs | ||
| versioned_dict.update( | ||
| { | ||
| mixin_operation.name: mixin_operation.available_apis | ||
| for mixin_operation in self.operation_mixin_group.mixin_operations | ||
| } | ||
| ) | ||
| for operation, api_versions_list in versioned_dict.items(): | ||
| local_default_api_version = _get_default_api_version_from_list( | ||
| self.mod_to_api_version, | ||
| api_versions_list, | ||
| self.preview_mode, | ||
| self.user_specified_default_api | ||
| ) | ||
| if local_default_api_version == self.default_api_version: | ||
| continue | ||
| # If some others RT contains "local_default_api_version", and | ||
| # if it's greater than the future default, danger, don't profile it | ||
| if ( | ||
| there_is_a_rt_that_contains_api_version( | ||
| versioned_dict, local_default_api_version | ||
| ) | ||
| and local_default_api_version > self.default_api_version | ||
| ): | ||
| continue | ||
| last_rt_list[operation] = local_default_api_version | ||
| return last_rt_list | ||
|
|
||
| @property | ||
| def default_models(self): | ||
| return sorted( | ||
| {self.default_api_version} | {versions for _, versions in self.last_rt_list.items()} | ||
| ) | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| # ------------------------------------------------------------------------- | ||
| # Copyright (c) Microsoft Corporation. All rights reserved. | ||
| # Licensed under the MIT License. See License.txt in the project root for | ||
| # license information. | ||
| # -------------------------------------------------------------------------- | ||
| from typing import Any, Dict | ||
|
|
||
| class Config(object): | ||
iscai-msft marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| def __init__(self, default_version_metadata: Dict[str, Any]): | ||
| self.credential = default_version_metadata["config"]["credential"] | ||
| self.credential_scopes = default_version_metadata["config"]["credential_scopes"] | ||
| self.credential_default_policy_type = default_version_metadata["config"]["credential_default_policy_type"] | ||
| self.credential_default_policy_type_has_async_version = ( | ||
| default_version_metadata["config"]["credential_default_policy_type_has_async_version"] | ||
| ) | ||
| self.credential_key_header_name = default_version_metadata["config"]["credential_key_header_name"] | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| # ------------------------------------------------------------------------- | ||
| # Copyright (c) Microsoft Corporation. All rights reserved. | ||
| # Licensed under the MIT License. See License.txt in the project root for | ||
| # license information. | ||
| # -------------------------------------------------------------------------- | ||
|
|
||
| class ConstantGlobalParameter(object): | ||
| def __init__(self, name: str, value: str): | ||
| self.name = name | ||
| self.value = value |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,32 @@ | ||
| # ------------------------------------------------------------------------- | ||
| # Copyright (c) Microsoft Corporation. All rights reserved. | ||
| # Licensed under the MIT License. See License.txt in the project root for | ||
| # license information. | ||
| # -------------------------------------------------------------------------- | ||
| from typing import Any, Dict | ||
|
|
||
| class GlobalParameter(object): | ||
| def __init__( | ||
| self, | ||
| name: str, | ||
| global_parameter_metadata_sync: Dict[str, Any], | ||
| global_parameter_metadata_async: Dict[str, Any] | ||
| ): | ||
| self.name = name | ||
| self.global_parameter_metadata_sync = global_parameter_metadata_sync | ||
| self.global_parameter_metadata_async = global_parameter_metadata_async | ||
| self.required = global_parameter_metadata_sync["required"] | ||
|
|
||
| def _global_parameter_metadata(self, async_mode: bool) -> Dict[str, Any]: | ||
| if async_mode: | ||
| return self.global_parameter_metadata_async | ||
| return self.global_parameter_metadata_sync | ||
|
|
||
| def signature(self, async_mode: bool) -> str: | ||
| return self._global_parameter_metadata(async_mode)["signature"] | ||
|
|
||
| def description(self, async_mode: bool) -> str: | ||
| return self._global_parameter_metadata(async_mode)["description"] | ||
|
|
||
| def docstring_type(self, async_mode: bool) -> str: | ||
| return self._global_parameter_metadata(async_mode)["docstring_type"] |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,34 @@ | ||
| # ------------------------------------------------------------------------- | ||
| # Copyright (c) Microsoft Corporation. All rights reserved. | ||
| # Licensed under the MIT License. See License.txt in the project root for | ||
| # license information. | ||
| # -------------------------------------------------------------------------- | ||
| from typing import Any, Dict, List | ||
| from .global_parameter import GlobalParameter | ||
| from .constant_global_parameter import ConstantGlobalParameter | ||
|
|
||
| class GlobalParameters(object): | ||
| def __init__(self, global_parameters_metadata: Dict[str, Any]): | ||
| self.call = global_parameters_metadata["call"] | ||
| self.global_parameters_metadata = global_parameters_metadata | ||
|
|
||
| @property | ||
| def parameters(self) -> List[GlobalParameter]: | ||
| global_parameters_metadata_sync = self.global_parameters_metadata["sync"] | ||
| global_parameters_metadata_async = self.global_parameters_metadata["async"] | ||
|
|
||
| return [ | ||
| GlobalParameter( | ||
| name=parameter_name, | ||
| global_parameter_metadata_sync=gp_sync, | ||
| global_parameter_metadata_async=global_parameters_metadata_async[parameter_name] | ||
| ) | ||
| for parameter_name, gp_sync in global_parameters_metadata_sync.items() | ||
| ] | ||
|
|
||
| @property | ||
| def constant_parameters(self) -> List[ConstantGlobalParameter]: | ||
| return [ | ||
| ConstantGlobalParameter(constant_name, constant_value) | ||
| for constant_name, constant_value in self.global_parameters_metadata["constant"].items() | ||
| ] |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,38 @@ | ||
| # ------------------------------------------------------------------------- | ||
| # Copyright (c) Microsoft Corporation. All rights reserved. | ||
| # Licensed under the MIT License. See License.txt in the project root for | ||
| # license information. | ||
| # -------------------------------------------------------------------------- | ||
| from typing import Any, Dict, List, TypeVar | ||
| from ..utils import _sync_or_async | ||
|
|
||
| T = TypeVar('T') | ||
| OrderedSet = Dict[T, None] | ||
|
|
||
| class MixinOperation(object): | ||
| def __init__(self, name: str, mixin_operation_metadata: Dict[str, Any]): | ||
| self.name = name | ||
| self.mixin_operation_metadata = mixin_operation_metadata | ||
| self._available_apis: OrderedSet[str] = {} | ||
|
|
||
| def signature(self, async_mode: bool) -> str: | ||
| return self.mixin_operation_metadata[_sync_or_async(async_mode)]["signature"] | ||
|
|
||
| def description(self, async_mode: bool) -> str: | ||
| return self.mixin_operation_metadata[_sync_or_async(async_mode)]["doc"] | ||
|
|
||
| def coroutine(self, async_mode: bool) -> bool: | ||
| if not async_mode: | ||
| return False | ||
| return self.mixin_operation_metadata["async"]["coroutine"] | ||
|
|
||
| @property | ||
| def call(self) -> str: | ||
| return self.mixin_operation_metadata["call"] | ||
|
|
||
| @property | ||
| def available_apis(self) -> List[str]: | ||
| return list(self._available_apis.keys()) | ||
|
|
||
| def append_available_api(self, val: str) -> None: | ||
| self._available_apis[val] = None |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,28 @@ | ||
| # ------------------------------------------------------------------------- | ||
| # Copyright (c) Microsoft Corporation. All rights reserved. | ||
| # Licensed under the MIT License. See License.txt in the project root for | ||
| # license information. | ||
| # -------------------------------------------------------------------------- | ||
| from typing import Dict, List, TypeVar | ||
|
|
||
| T = TypeVar('T') | ||
| OrderedSet = Dict[T, None] | ||
|
|
||
| class OperationGroup(object): | ||
| def __init__(self, name: str): | ||
| self.name = name | ||
| self._available_apis: OrderedSet[str] = {} | ||
| self._api_to_class_name: Dict[str, str] = {} | ||
|
|
||
| @property | ||
| def available_apis(self) -> List[str]: | ||
| return list(self._available_apis.keys()) | ||
|
|
||
| def append_available_api(self, val: str) -> None: | ||
| self._available_apis[val] = None | ||
|
|
||
| def append_api_class_name_pair(self, api_version: str, class_name: str): | ||
| self._api_to_class_name[api_version] = class_name | ||
|
|
||
| def class_name(self, api_version: str): | ||
| return self._api_to_class_name[api_version] |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.