Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions autorest/codegen/models/parameter.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,20 @@ def constant(self) -> bool:
return False
return self.required

@property
def constant_declaration(self) -> str:
if self.schema:
if isinstance(self.schema, ConstantSchema):
return self.schema.get_declaration(self.schema.value)
raise ValueError(
"Trying to get constant declaration for a schema that is not ConstantSchema"
)
raise ValueError("Trying to get a declaration for a schema that doesn't exist")

@property
def xml_serialization_ctxt(self) -> str:
return self.schema.xml_serialization_ctxt() or ""

@property
def in_method_signature(self) -> bool:
return not(
Expand Down Expand Up @@ -153,6 +167,10 @@ def default_value(self) -> Optional[Any]:
# default values we bubble up from the schema
return self._default_value()[0]

@property
def serialization_type(self) -> str:
return self.schema.serialization_type

@property
def docstring_type(self) -> str:
return self.multiple_media_types_docstring_type or self.schema.docstring_type
Expand Down
20 changes: 20 additions & 0 deletions autorest/codegen/models/property.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,26 @@ def from_yaml(cls, yaml_data: Dict[str, Any], **kwargs) -> "Property":
flattened_names=yaml_data.get("flattenedNames", []),
)

@property
def constant_declaration(self) -> str:
if self.schema:
if isinstance(self.schema, ConstantSchema):
return self.schema.get_declaration(self.schema.value)
raise ValueError(
"Trying to get constant declaration for a schema that is not ConstantSchema"
)
raise ValueError("Trying to get a declaration for a schema that doesn't exist")

@property
def serialization_type(self) -> str:
return self.schema.serialization_type

@property
def xml_metadata(self) -> str:
if self.schema.has_xml_serialization_ctxt:
return f", 'xml': {{{self.schema.xml_serialization_ctxt()}}}"
return ""

@property
def type_annotation(self) -> str:
if self.required:
Expand Down
44 changes: 43 additions & 1 deletion autorest/codegen/models/schema_response.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,22 @@
# Licensed under the MIT License. See License.txt in the project root for
# license information.
# --------------------------------------------------------------------------
from typing import Dict, Optional, List, Union, Any
from typing import Dict, Optional, List, Union, Any, cast

from .base_model import BaseModel
from .base_schema import BaseSchema
from .object_schema import ObjectSchema


class HeaderResponse:
def __init__(self, name: str, schema) -> None:
self.name = name
self.schema = schema

@property
def serialization_type(self) -> str:
return self.schema.serialization_type


class SchemaResponse(BaseModel):
def __init__(
Expand All @@ -31,6 +36,7 @@ def __init__(
self.status_codes = status_codes
self.headers = headers
self.binary = binary
self.nullable = self.yaml_data.get("nullable", False)

@property
def has_body(self) -> bool:
Expand All @@ -44,11 +50,47 @@ def has_headers(self) -> bool:
"""
return bool(self.headers)

@property
def serialization_type(self) -> str:
if self.schema:
return self.schema.serialization_type
return "None"

@property
def operation_type_annotation(self) -> str:
if not self.schema:
return "None"
if self.nullable:
return f"Optional[{self.schema.operation_type_annotation}]"
return self.schema.operation_type_annotation

@property
def docstring_text(self) -> str:
if not self.schema:
return "None"
if self.nullable:
return f"{self.schema.docstring_text} or None"
return self.schema.docstring_text

@property
def docstring_type(self) -> str:
if not self.schema:
return "None"
if self.nullable:
return f"{self.schema.docstring_type} or None"
return self.schema.docstring_type

@property
def is_stream_response(self) -> bool:
"""Is the response expected to be streamable, like a download."""
return self.binary

@property
def is_exception(self) -> bool:
if self.schema:
return cast(ObjectSchema, self.schema).is_exception
return False

@classmethod
def from_yaml(cls, yaml_data: Dict[str, Any]) -> "SchemaResponse":

Expand Down
4 changes: 2 additions & 2 deletions autorest/codegen/templates/config.py.jinja2
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ class {{ code_model.class_name }}Configuration(Configuration):
{% endif %}
{% for parameter in code_model.global_parameters.method %}
:param {{ parameter.serialized_name }}: {{ parameter.description }}
:type {{ parameter.serialized_name }}: {{ parameter.schema.docstring_type }}
:type {{ parameter.serialized_name }}: {{ parameter.docstring_type }}
{% endfor %}
"""

Expand All @@ -54,7 +54,7 @@ class {{ code_model.class_name }}Configuration(Configuration):
{% endfor %}
{% if code_model.global_parameters.constant %}
{% for constant_parameter in code_model.global_parameters.constant %}
self.{{ constant_parameter.serialized_name }} = {{ constant_parameter.schema.get_declaration(constant_parameter.schema.value) }}
self.{{ constant_parameter.serialized_name }} = {{ constant_parameter.constant_declaration }}
{% endfor %}
{% endif %}
{% if code_model.options['credential_scopes'] is not none %}
Expand Down
6 changes: 3 additions & 3 deletions autorest/codegen/templates/lro_operation.py.jinja2
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@
{% set trace_decorator = "@distributed_trace_async" if async_mode else "@distributed_trace" %}
{% set operation_name = "begin_"+operation.python_name %}
{% macro return_docstring(async_mode) %}
:return: An instance of {{ "Async" if async_mode }}LROPoller that returns either {{ operation.responses[0].schema.docstring_text if operation.responses[0].has_body else "None"}} or the result of cls(response)
:rtype: ~azure.core.polling.{{ "Async" if async_mode }}LROPoller[{{ operation.responses[0].schema.docstring_type if operation.responses[0].has_body else "None" }}]{% endmacro %}
:return: An instance of {{ "Async" if async_mode }}LROPoller that returns either {{ operation.responses[0].docstring_text }} or the result of cls(response)
:rtype: ~azure.core.polling.{{ "Async" if async_mode }}LROPoller[{{ operation.responses[0].docstring_type }}]{% endmacro %}
{% macro response_headers(response) %}
response_headers = {
{% for response_header in response.headers %}
'{{ response_header.name }}': self._deserialize('{{ response_header.schema.serialization_type }}', response.headers.get('{{ response_header.name }}')),
'{{ response_header.name }}': self._deserialize('{{ response_header.serialization_type }}', response.headers.get('{{ response_header.name }}')),
{% endfor %}
}
{% endmacro %}
Expand Down
2 changes: 1 addition & 1 deletion autorest/codegen/templates/lro_operation_helper.jinja2
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
{%- for doc_string in param_documentation_string(parameter).replace('\n', '\n ').split('\n') %}
{{ doc_string | wordwrap(width=95, break_long_words=False, wrapstring='\n ')}}
{% endfor %}
:type {{ parameter.serialized_name }}: {{ parameter.schema.docstring_type }}
:type {{ parameter.serialized_name }}: {{ parameter.docstring_type }}
{% endfor %}
:keyword callable cls: A custom type or function that will be passed the direct response
:keyword str continuation_token: A continuation token to restart a poller from a saved state.
Expand Down
4 changes: 2 additions & 2 deletions autorest/codegen/templates/lro_paging_operation.py.jinja2
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
{% set trace_decorator = "@distributed_trace_async" if async_mode else "@distributed_trace" %}
{% set operation_name = "begin_"+operation.python_name %}
{% macro return_docstring(async_mode) %}
:return: An instance of {{ "Async" if async_mode }}LROPoller that returns an iterator like instance of either {{ operation.responses[0].schema.docstring_text if operation.responses[0].has_body else "None"}} or the result of cls(response)
:rtype: ~azure.core.polling.{{ "Async" if async_mode }}LROPoller[~azure.core.{{ "async_" if async_mode else "" }}paging.{{ "Async" if async_mode }}ItemPaged[{{ operation.responses[0].schema.docstring_type if operation.responses[0].has_body else "None" }}]]{% endmacro %}
:return: An instance of {{ "Async" if async_mode }}LROPoller that returns an iterator like instance of either {{ operation.responses[0].docstring_text }} or the result of cls(response)
:rtype: ~azure.core.polling.{{ "Async" if async_mode }}LROPoller[~azure.core.{{ "async_" if async_mode else "" }}paging.{{ "Async" if async_mode }}ItemPaged[{{ operation.responses[0].docstring_type }}]]{% endmacro %}
{% macro operation_docstring(async_mode) %}
{{ lro_helper.operation_docstring_helper(operation, async_mode) }}
{{ return_docstring(async_mode) }}
Expand Down
6 changes: 3 additions & 3 deletions autorest/codegen/templates/metadata.json.jinja2
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
{{ gp.serialized_name | tojson }}: {
"method_signature": {{ gp.sync_method_signature | tojson }},
"description": {{ gp.description | tojson }},
"docstring_type": {{ gp.schema.docstring_type | tojson }},
"docstring_type": {{ gp.docstring_type | tojson }},
"required": {{ gp.required | tojson }}
}{{ "," if not loop.last else "" }}
{% endfor %}
Expand All @@ -29,15 +29,15 @@
{{ gp.serialized_name | tojson }}: {
"method_signature": {{ gp.sync_method_signature | tojson }},
"description": {{ gp.description | tojson }},
"docstring_type": {{ gp.schema.docstring_type | tojson }},
"docstring_type": {{ gp.docstring_type | tojson }},
"required": {{ gp.required | tojson }}
}{{ "," if not loop.last else "" }}
{% endfor %}
},
"constant": {
{% for gp in code_model.global_parameters.constant %}
{% if gp.serialized_name != "api_version" %}
{{ gp.serialized_name | tojson }}: {{ gp.schema.get_declaration(gp.schema.value) | tojson }}{{ "," if not loop.last else "" }}
{{ gp.serialized_name | tojson }}: {{ gp.constant_declaration | tojson }}{{ "," if not loop.last else "" }}
{% endif %}
{% endfor %}
},
Expand Down
5 changes: 2 additions & 3 deletions autorest/codegen/templates/model.py.jinja2
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,7 @@ class {{ model.name }}(msrest.serialization.Model):
_attribute_map = {
{% if model.properties != None %}
{% for p in model.properties %}
{% set xml_metadata = (", 'xml': {" + p.schema.xml_serialization_ctxt() + "}") if p.schema.has_xml_serialization_ctxt else "" %}
'{{ p.name }}': {'key': '{{ p.escaped_swagger_name }}', 'type': '{{ p.schema.serialization_type}}'{{ xml_metadata }}},
'{{ p.name }}': {'key': '{{ p.escaped_swagger_name }}', 'type': '{{ p.serialization_type}}'{{ p.xml_metadata }}},
{% endfor %}
{% else%}
{% endif %}
Expand All @@ -63,7 +62,7 @@ class {{ model.name }}(msrest.serialization.Model):
{% if (model.properties | selectattr('constant') | first) is defined %}

{% for p in model.properties | selectattr('constant')%}
{{ p.name }} = {{ p.schema.get_declaration(p.schema.value) }}
{{ p.name }} = {{ p.constant_declaration }}
{% endfor %}
{% endif %}

Expand Down
10 changes: 5 additions & 5 deletions autorest/codegen/templates/operation.py.jinja2
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@
:rtype: {{ return_type }}
{%- else -%}
{% if operation.responses | selectattr('has_body') | first %}
:return: {{ operation.responses|selectattr('has_body')|map(attribute='schema')| map(attribute='docstring_text')|unique|join(' or ') }}, or the result of cls(response)
:rtype: {{ operation.responses|selectattr('has_body')|map(attribute='schema')| map(attribute='docstring_type')|unique|join(' or ') }}{{ " or None" if operation.has_optional_return_type }}
:return: {{ operation.responses|selectattr('has_body')|map(attribute='docstring_text')|unique|join(' or ') }}, or the result of cls(response)
:rtype: {{ operation.responses|selectattr('has_body')| map(attribute='docstring_type')|unique|join(' or ') }}{{ " or None" if operation.has_optional_return_type }}
{%- else %}
:return: None, or the result of cls(response)
:rtype: None
Expand All @@ -39,7 +39,7 @@
{% endfor %}
{% if (operation.requests | length) > 1 %}
{% set content_type_constant = operation.parameters.constant|selectattr("implementation", "equalto", "Method")|selectattr("original_parameter", "equalto", None)|selectattr("in_method_code") | selectattr("serialized_name", "equalto", "content_type") | first %}
:keyword str content_type: Media type of the body sent to the API. Default value is {{ content_type_constant.schema.get_declaration(content_type_constant.schema.value) }}.
:keyword str content_type: Media type of the body sent to the API. Default value is {{ content_type_constant.constant_declaration }}.
Allowed values are: "{{ operation.requests | map(attribute="media_types") | sum(start = []) | unique | list | join ('", "') }}".
{% endif %}
:keyword callable cls: A custom type or function that will be passed the direct response
Expand Down Expand Up @@ -72,9 +72,9 @@
{% if operation.parameters.constant|selectattr("implementation", "equalto", "Method")|selectattr("original_parameter", "equalto", None)|selectattr("in_method_code") %}
{% for constant_parameter in operation.parameters.constant|selectattr("implementation", "equalto", "Method")|selectattr("original_parameter", "equalto", None)|selectattr("in_method_code") %}
{% if constant_parameter.serialized_name == "content_type" %}
content_type = kwargs.pop("content_type", {{ constant_parameter.schema.get_declaration(constant_parameter.schema.value) }})
content_type = kwargs.pop("content_type", {{ constant_parameter.constant_declaration }})
{% else %}
{{ constant_parameter.serialized_name }} = {{ constant_parameter.schema.get_declaration(constant_parameter.schema.value) }}
{{ constant_parameter.serialized_name }} = {{ constant_parameter.constant_declaration }}
{% endif %}
{% endfor %}
{% endif %}
Expand Down
18 changes: 9 additions & 9 deletions autorest/codegen/templates/operation_tools.jinja2
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
{%- if return_type -%}
{{ return_type }}
{%- else -%}
{{ ((return_type_wrapper | join("[") + "[") if return_type_wrapper else "") ~ ("Optional[" if operation.has_optional_return_type else "" ) ~ ("Union[" if operation.responses | selectattr('has_body') | map(attribute='schema') | map(attribute='operation_type_annotation') | unique | list | length > 1 else "") ~
(operation.responses | selectattr('has_body') | map(attribute='schema') | map(attribute='operation_type_annotation') | unique | join(', ')) ~
("]" if operation.responses | selectattr('has_body') | map(attribute='schema') | map(attribute='operation_type_annotation')| unique | list | length > 1 else "") ~ ("]" if operation.has_optional_return_type else "") ~ ( ("]" * return_type_wrapper | count ) if return_type_wrapper else "")
{{ ((return_type_wrapper | join("[") + "[") if return_type_wrapper else "") ~ ("Optional[" if operation.has_optional_return_type else "" ) ~ ("Union[" if operation.responses | selectattr('has_body') | map(attribute='operation_type_annotation') | unique | list | length > 1 else "") ~
(operation.responses | selectattr('has_body') | map(attribute='operation_type_annotation') | unique | join(', ')) ~
("]" if operation.responses | selectattr('has_body') | map(attribute='operation_type_annotation')| unique | list | length > 1 else "") ~ ("]" if operation.has_optional_return_type else "") ~ ( ("]" * return_type_wrapper | count ) if return_type_wrapper else "")
if operation.responses | selectattr('has_body') | first
else ((return_type_wrapper | join("[") + "[") if return_type_wrapper else "") ~ ("Optional[" if operation.has_optional_return_type else "" ) ~ "None" ~ ("]" if operation.has_optional_return_type else "") ~ ( ("]" * return_type_wrapper | count ) if return_type_wrapper else "") }}{%- endif -%}{% endmacro %}
{# get async mypy typing #}
Expand Down Expand Up @@ -47,7 +47,7 @@ error_map = {
{% endif %}
{% for excep in operation.status_code_exceptions %}
{% for status_code in excep.status_codes %}
{% set error_model = ", model=self._deserialize(models." + excep.schema.serialization_type + ", response)" if excep.schema.is_exception else "" %}
{% set error_model = ", model=self._deserialize(models." + excep.serialization_type + ", response)" if excep.is_exception else "" %}
{% set error_format = ", error_format=ARMErrorFormat" if code_model.options['azure_arm'] else "" %}
{% if status_code == 401 %}
401: lambda response: ClientAuthenticationError(response=response{{ error_model }}{{ error_format }}),
Expand All @@ -74,13 +74,13 @@ error_map.update(kwargs.pop('error_map', {})){%- endmacro -%}
{% macro response_handling(response) %}
{% if response.headers %}
{% for response_header in response.headers %}
response_headers['{{ response_header.name }}']=self._deserialize('{{ response_header.schema.serialization_type }}', response.headers.get('{{ response_header.name }}'))
response_headers['{{ response_header.name }}']=self._deserialize('{{ response_header.serialization_type }}', response.headers.get('{{ response_header.name }}'))
{% endfor %}
{% endif %}
{% if response.is_stream_response %}
deserialized = response.stream_download(self._client._pipeline)
{% elif response.has_body %}
deserialized = self._deserialize('{{ response.schema.serialization_type }}', pipeline_response)
deserialized = self._deserialize('{{ response.serialization_type }}', pipeline_response)
{% endif %}
{% endmacro %}
{# write grouped parameters #}
Expand Down Expand Up @@ -130,15 +130,15 @@ if {{ header_parameter.full_serialized_name }} is not None:
{% macro stream_body_params(operation) %}body_content_kwargs['stream_content'] = {{ operation.parameters.body[0].serialized_name }}{% endmacro %}
{# helper for non-stream body params with schema #}
{% macro non_stream_body_params(operation, send_xml, request_as_xml) %}
{% set ser_ctxt = operation.parameters.body[0].schema.xml_serialization_ctxt() if send_xml else None %}
{% set ser_ctxt = operation.parameters.body[0].xml_serialization_ctxt if send_xml else None %}
{% if ser_ctxt %}
serialization_ctxt = {'xml': {{ "{" }}{{ ser_ctxt }}{{ "}}" }}
{% endif %}
{% if operation.parameters.body[0].required %}
body_content = self._serialize.body({{ operation.parameters.body[0].serialized_name }}, '{{ operation.parameters.body[0].schema.serialization_type }}'{{ request_as_xml }}{{ ", serialization_ctxt=serialization_ctxt" if ser_ctxt else "" }})
body_content = self._serialize.body({{ operation.parameters.body[0].serialized_name }}, '{{ operation.parameters.body[0].serialization_type }}'{{ request_as_xml }}{{ ", serialization_ctxt=serialization_ctxt" if ser_ctxt else "" }})
{% else %}
if {{ operation.parameters.body[0].serialized_name }} is not None:
body_content = self._serialize.body({{ operation.parameters.body[0].serialized_name }}, '{{ operation.parameters.body[0].schema.serialization_type }}'{{ request_as_xml }}{{ ", serialization_ctxt=serialization_ctxt" if ser_ctxt else "" }})
body_content = self._serialize.body({{ operation.parameters.body[0].serialized_name }}, '{{ operation.parameters.body[0].serialization_type }}'{{ request_as_xml }}{{ ", serialization_ctxt=serialization_ctxt" if ser_ctxt else "" }})
else:
body_content = None
{% endif %}
Expand Down
Loading