Skip to content

Commit

Permalink
Merge branch 'autorestv3' of https://github.com/Azure/autorest.python
Browse files Browse the repository at this point in the history
…into multiapiclient_test

* 'autorestv3' of https://github.com/Azure/autorest.python:
  Added case for deserializing error model to an anyschema (#516)
  • Loading branch information
iscai-msft committed Mar 24, 2020
2 parents 2cfc062 + 04b0a6f commit 2aef983
Show file tree
Hide file tree
Showing 25 changed files with 628 additions and 12 deletions.
4 changes: 2 additions & 2 deletions autorest/codegen/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ def remove_cloud_errors(yaml_data: Dict[str, Any]) -> None:
break

@staticmethod
def _build_exceptions_set(yaml_data: List[Dict[str, Any]]) -> Set[Dict[str, Any]]:
def _build_exceptions_set(yaml_data: List[Dict[str, Any]]) -> Set[int]:
exceptions_set = set()
for group in yaml_data:
for operation in group["operations"]:
Expand All @@ -51,7 +51,7 @@ def _build_exceptions_set(yaml_data: List[Dict[str, Any]]) -> Set[Dict[str, Any]
for exception in operation["exceptions"]:
if not exception.get("schema"):
continue
exceptions_set.add(exception["schema"]["language"]["python"]["name"])
exceptions_set.add(id(exception["schema"]))
return exceptions_set

def _create_code_model(self, yaml_data: Dict[str, Any], options: Dict[str, Union[str, bool]]) -> CodeModel:
Expand Down
2 changes: 1 addition & 1 deletion autorest/codegen/models/object_schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ def fill_instance_from_yaml(self, namespace: str, yaml_data: Dict[str, Any], **k
is_exception = False
exceptions_set = kwargs.pop("exceptions_set", None)
if exceptions_set:
if yaml_data["language"]["python"]["name"] in exceptions_set:
if id(yaml_data) in exceptions_set:
is_exception = True

self.yaml_data = yaml_data
Expand Down
14 changes: 10 additions & 4 deletions autorest/codegen/models/operation.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
from .parameter_list import ParameterList
from .base_schema import BaseSchema
from .schema_request import SchemaRequest
from .object_schema import ObjectSchema


_LOGGER = logging.getLogger(__name__)
Expand Down Expand Up @@ -205,11 +206,16 @@ def success_status_code(self) -> List[Union[str, int]]:
return [code for response in self.responses for code in response.status_codes if code != "default"]

@property
def default_exception(self) -> Optional[SchemaResponse]:
def default_exception(self) -> Optional[str]:
default_excp = [excp for excp in self.exceptions for code in excp.status_codes if code == "default"]
if default_excp:
return default_excp[0]
return None
if not default_excp:
return None
excep_schema = default_excp[0].schema
if isinstance(excep_schema, ObjectSchema):
return f"models.{excep_schema.name}"
# in this case, it's just an AnySchema
return "\'object\'"


@property
def status_code_exceptions(self) -> List[SchemaResponse]:
Expand Down
2 changes: 1 addition & 1 deletion autorest/codegen/templates/operation.py.jinja2
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@
if response.status_code not in {{ operation.success_status_code|string() }}:
map_error(status_code=response.status_code, response=response, error_map=error_map)
{% if operation.default_exception %}
error = self._deserialize(models.{{ operation.default_exception.schema.name }}, response)
error = self._deserialize({{ operation.default_exception }}, response)
{% endif %}
raise HttpResponseError(response=response{{ ", model=error" if operation.default_exception else "" }}{{ ", error_format=ARMErrorFormat" if code_model.options['azure_arm'] else "" }})

Expand Down
2 changes: 1 addition & 1 deletion autorest/codegen/templates/paging_operation.py.jinja2
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@

if response.status_code not in {{ operation.success_status_code|string() }}:
{% if operation.default_exception %}
error = self._deserialize(models.{{ operation.default_exception.schema.name }}, response)
error = self._deserialize({{ operation.default_exception }}, response)
{% endif %}
map_error(status_code=response.status_code, response=response, error_map=error_map)
raise HttpResponseError(response=response{{ ", model=error" if operation.default_exception else "" }}{{ ", error_format=ARMErrorFormat" if code_model.options['azure_arm'] else "" }})
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
"homepage": "https://github.com/Azure/autorest.python/blob/master/README.md",
"devDependencies": {
"@autorest/autorest": "^3.0.0",
"@microsoft.azure/autorest.testserver": "^2.10.15"
"@microsoft.azure/autorest.testserver": "^2.10.17"
},
"files": [
"autorest/**/*.py",
Expand Down
3 changes: 2 additions & 1 deletion tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,8 @@
'AcceptanceTests/Xml': ['xml-service.json', 'xmlservice'],
'AcceptanceTests/UrlMultiCollectionFormat' : 'url-multi-collectionFormat.json',
'AcceptanceTests/XmsErrorResponse': 'xms-error-responses.json',
'AcceptanceTests/MediaTypes': ['media_types.json', 0]
'AcceptanceTests/MediaTypes': ['media_types.json', 0],
'AcceptanceTests/ObjectType': 'object-type.json'
}

default_azure_mappings = {
Expand Down
54 changes: 54 additions & 0 deletions test/vanilla/AcceptanceTests/asynctests/test_object_type.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# --------------------------------------------------------------------------
#
# Copyright (c) Microsoft Corporation. All rights reserved.
#
# The MIT License (MIT)
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the ""Software""), to
# deal in the Software without restriction, including without limitation the
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
# sell copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
# IN THE SOFTWARE.
#
# --------------------------------------------------------------------------
from async_generator import yield_, async_generator
from objecttype.aio import ObjectTypeClient
from azure.core.exceptions import HttpResponseError

import pytest

@pytest.fixture
@async_generator
async def client():
async with ObjectTypeClient(base_url="http://localhost:3000") as client:
await yield_(client)

class TestObjectType(object):

@pytest.mark.asyncio
async def test_get_object(self, client):
response = await client.get()
assert response == {"message": "An object was successfully returned"}

@pytest.mark.asyncio
async def test_put_object_success(self, client):
response = await client.put({"foo": "bar"})
assert response is None

@pytest.mark.asyncio
async def test_put_object_fail(self, client):
with pytest.raises(HttpResponseError) as ex:
response = await client.put({"should": "fail"})
assert ex.value.model == {"message": "The object you passed was incorrect"}
50 changes: 50 additions & 0 deletions test/vanilla/AcceptanceTests/test_object_type.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# --------------------------------------------------------------------------
#
# Copyright (c) Microsoft Corporation. All rights reserved.
#
# The MIT License (MIT)
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the ""Software""), to
# deal in the Software without restriction, including without limitation the
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
# sell copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
# IN THE SOFTWARE.
#
# --------------------------------------------------------------------------

from objecttype import ObjectTypeClient
from azure.core.exceptions import HttpResponseError

import pytest

@pytest.fixture
def client():
with ObjectTypeClient(base_url="http://localhost:3000") as client:
yield client

class TestObjectType(object):

def test_get_object(self, client):
response = client.get()
assert response == {"message": "An object was successfully returned"}

def test_put_object_success(self, client):
response = client.put({"foo": "bar"})
assert response is None

def test_put_object_fail(self, client):
with pytest.raises(HttpResponseError) as ex:
response = client.put({"should": "fail"})
assert ex.value.model == {"message": "The object you passed was incorrect"}
1 change: 0 additions & 1 deletion test/vanilla/AcceptanceTests/test_zzz.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,6 @@ def test_ensure_coverage(self):
if "Multiapi" in name:
# multiapi is in a separate test folder
missing_features_or_bugs[name] = 1

print("Optional coverage:")
self._print_report(optional_report, not_supported, missing_features_or_bugs)

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# coding=utf-8
# --------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See License.txt in the project root for license information.
# Code generated by Microsoft (R) AutoRest Code Generator.
# Changes may cause incorrect behavior and will be lost if the code is regenerated.
# --------------------------------------------------------------------------

from ._object_type_client import ObjectTypeClient
from ._version import VERSION

__version__ = VERSION
__all__ = ['ObjectTypeClient']
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# coding=utf-8
# --------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See License.txt in the project root for license information.
# Code generated by Microsoft (R) AutoRest Code Generator.
# Changes may cause incorrect behavior and will be lost if the code is regenerated.
# --------------------------------------------------------------------------

from typing import Any

from azure.core.configuration import Configuration
from azure.core.pipeline import policies

from ._version import VERSION


class ObjectTypeClientConfiguration(Configuration):
"""Configuration for ObjectTypeClient.
Note that all parameters used to create this instance are saved as instance
attributes.
"""

def __init__(
self,
**kwargs # type: Any
):
# type: (...) -> None
super(ObjectTypeClientConfiguration, self).__init__(**kwargs)

kwargs.setdefault('sdk_moniker', 'objecttypeclient/{}'.format(VERSION))
self._configure(**kwargs)

def _configure(
self,
**kwargs # type: Any
):
# type: (...) -> None
self.user_agent_policy = kwargs.get('user_agent_policy') or policies.UserAgentPolicy(**kwargs)
self.headers_policy = kwargs.get('headers_policy') or policies.HeadersPolicy(**kwargs)
self.proxy_policy = kwargs.get('proxy_policy') or policies.ProxyPolicy(**kwargs)
self.logging_policy = kwargs.get('logging_policy') or policies.NetworkTraceLoggingPolicy(**kwargs)
self.retry_policy = kwargs.get('retry_policy') or policies.RetryPolicy(**kwargs)
self.custom_hook_policy = kwargs.get('custom_hook_policy') or policies.CustomHookPolicy(**kwargs)
self.redirect_policy = kwargs.get('redirect_policy') or policies.RedirectPolicy(**kwargs)
self.authentication_policy = kwargs.get('authentication_policy')
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# coding=utf-8
# --------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See License.txt in the project root for license information.
# Code generated by Microsoft (R) AutoRest Code Generator.
# Changes may cause incorrect behavior and will be lost if the code is regenerated.
# --------------------------------------------------------------------------

from typing import Any, Optional

from azure.core import PipelineClient
from msrest import Deserializer, Serializer

from ._configuration import ObjectTypeClientConfiguration
from .operations import ObjectTypeClientOperationsMixin


class ObjectTypeClient(ObjectTypeClientOperationsMixin):
"""Service client for testing basic type: object swaggers.
:param str base_url: Service URL
"""

def __init__(
self,
base_url=None, # type: Optional[str]
**kwargs # type: Any
):
# type: (...) -> None
if not base_url:
base_url = 'http://localhost:3000'
self._config = ObjectTypeClientConfiguration(**kwargs)
self._client = PipelineClient(base_url=base_url, config=self._config, **kwargs)

client_models = {}
self._serialize = Serializer(client_models)
self._deserialize = Deserializer(client_models)


def close(self):
# type: () -> None
self._client.close()

def __enter__(self):
# type: () -> ObjectTypeClient
self._client.__enter__()
return self

def __exit__(self, *exc_details):
# type: (Any) -> None
self._client.__exit__(*exc_details)
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# coding=utf-8
# --------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See License.txt in the project root for license information.
# Code generated by Microsoft (R) AutoRest Code Generator.
# Changes may cause incorrect behavior and will be lost if the code is regenerated.
# --------------------------------------------------------------------------

VERSION = "0.1.0"
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# coding=utf-8
# --------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See License.txt in the project root for license information.
# Code generated by Microsoft (R) AutoRest Code Generator.
# Changes may cause incorrect behavior and will be lost if the code is regenerated.
# --------------------------------------------------------------------------

from ._object_type_client_async import ObjectTypeClient
__all__ = ['ObjectTypeClient']
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# coding=utf-8
# --------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See License.txt in the project root for license information.
# Code generated by Microsoft (R) AutoRest Code Generator.
# Changes may cause incorrect behavior and will be lost if the code is regenerated.
# --------------------------------------------------------------------------

from typing import Any

from azure.core.configuration import Configuration
from azure.core.pipeline import policies

from .._version import VERSION


class ObjectTypeClientConfiguration(Configuration):
"""Configuration for ObjectTypeClient.
Note that all parameters used to create this instance are saved as instance
attributes.
"""

def __init__(
self,
**kwargs: Any
) -> None:
super(ObjectTypeClientConfiguration, self).__init__(**kwargs)

kwargs.setdefault('sdk_moniker', 'objecttypeclient/{}'.format(VERSION))
self._configure(**kwargs)

def _configure(
self,
**kwargs: Any
) -> None:
self.user_agent_policy = kwargs.get('user_agent_policy') or policies.UserAgentPolicy(**kwargs)
self.headers_policy = kwargs.get('headers_policy') or policies.HeadersPolicy(**kwargs)
self.proxy_policy = kwargs.get('proxy_policy') or policies.ProxyPolicy(**kwargs)
self.logging_policy = kwargs.get('logging_policy') or policies.NetworkTraceLoggingPolicy(**kwargs)
self.retry_policy = kwargs.get('retry_policy') or policies.AsyncRetryPolicy(**kwargs)
self.custom_hook_policy = kwargs.get('custom_hook_policy') or policies.CustomHookPolicy(**kwargs)
self.redirect_policy = kwargs.get('redirect_policy') or policies.AsyncRedirectPolicy(**kwargs)
self.authentication_policy = kwargs.get('authentication_policy')
Loading

0 comments on commit 2aef983

Please sign in to comment.