Skip to content
This repository has been archived by the owner on Dec 25, 2024. It is now read-only.

Commit

Permalink
v3 fix operation overloads (#176)
Browse files Browse the repository at this point in the history
* Fixes SerializedRequestBody['fields'] type

* Updates ApiCLient fields type

* Fixes fields type, moves RequestField into rest, fixes _get_headers

* Fixes _get_used_path

* Updates x_params to default to None

* When x_params are required, none is not an allowed value

* Moves required x_params earlier than optional ones

* tweaks skip_deserilization

* Adds new template for required variables

* Updated templates

* Simplifies operation overloads

* Reorders required and optional parameters

* Writes content_type on one line if there is only one

* Adds generic types to request bodies

* Adds generic types to request bodies

* Fixes test_fake_api errors

* Fixes inputs to RequestField

* FIxes new signature for arays, adds newlines

* Updates required properties to use newlines

* Adds newlines to new optional properties

* Uses newlines in additionalProperties new signature

* Moves array with usages higher

* Adds new arry ref generic types

* Adds array generics in new

* Input arg in new for more than one type uses newline

* Adds newline to new anytype types

* Adds parameterization to reuired ref properties in schema new

* Adds required prop generic types when from properties

* Adds required prop from additional prop generic types

* Adds helper for new property type hints

* Adds AnyTypeSchema parameterization

* Adds new ref generic helper

* Adds new optional property ref generic types

* Adds kwarg generics when set

* Changes new list/tuple input into sequence

* Adds newlines to kwargs in new signature

* Adds typing.Sequence for ListSchema inputs

* Tweaks operation type hint, sets ApiResponseWithoutDeserialization body + headers always as unset

* Regenerates samples
  • Loading branch information
spacether committed Aug 16, 2023
1 parent 4bb4a4c commit 646c57c
Show file tree
Hide file tree
Showing 607 changed files with 15,583 additions and 13,216 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,13 @@ public class CodegenOperation {
public final CodegenRequestBody requestBody;
public final List<CodegenParameter> allParams;
public final List<CodegenParameter> pathParams;
public final boolean hasRequiredPathParams;
public final List<CodegenParameter> queryParams;
public final boolean hasRequiredQueryParams;
public final List<CodegenParameter> headerParams;
public final boolean hasRequiredHeaderParams;
public final List<CodegenParameter> cookieParams;
public final boolean hasRequiredCookieParams;
public final boolean hasRequiredParamOrBody;
public final boolean hasOptionalParamOrBody;
public final List<HashMap<String, CodegenSecurityRequirementValue>> security;
Expand All @@ -61,9 +65,57 @@ public CodegenOperation(Boolean deprecated, boolean hasErrorResponseObject, Stri
this.requestBody = requestBody;
this.allParams = allParams;
this.pathParams = pathParams;
if (pathParams == null) {
this.hasRequiredPathParams = false;
} else {
boolean val = false;
for (CodegenParameter p: pathParams) {
if (Boolean.TRUE.equals(p.required)) {
val = true;
break;
}
}
this.hasRequiredPathParams = val;
}
this.queryParams = queryParams;
if (queryParams == null) {
this.hasRequiredQueryParams = false;
} else {
boolean val = false;
for (CodegenParameter p: queryParams) {
if (Boolean.TRUE.equals(p.required)) {
val = true;
break;
}
}
this.hasRequiredQueryParams = val;
}
this.headerParams = headerParams;
if (headerParams == null) {
this.hasRequiredHeaderParams = false;
} else {
boolean val = false;
for (CodegenParameter p: headerParams) {
if (Boolean.TRUE.equals(p.required)) {
val = true;
break;
}
}
this.hasRequiredHeaderParams = val;
}
this.cookieParams = cookieParams;
if (cookieParams == null) {
this.hasRequiredCookieParams = false;
} else {
boolean val = false;
for (CodegenParameter p: cookieParams) {
if (Boolean.TRUE.equals(p.required)) {
val = true;
break;
}
}
this.hasRequiredCookieParams = val;
}
this.hasRequiredParamOrBody = hasRequiredParamOrBody;
this.hasOptionalParamOrBody = hasOptionalParamOrBody;
this.security = security;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,6 @@ from {{packageName}} import exceptions, rest, schemas, security_schemes, api_res
from {{packageName}}.configurations import api_configuration, schema_configuration as schema_configuration_


class RequestField(fields.RequestField):
def __eq__(self, other):
if not isinstance(other, fields.RequestField):
return False
return self.__dict__ == other.__dict__


class JSONEncoder(json.JSONEncoder):
compact_separators = (',', ':')

Expand Down Expand Up @@ -771,7 +764,10 @@ class HeaderParameter(__HeaderParameterBase):

class TypedDictInputVerifier:
@staticmethod
def _verify_typed_dict_inputs(tdict_cls: typing.Type[typing_extensions.TypedDict], data: typing.Mapping[str, typing.Any]):
def _verify_typed_dict_inputs(
tdict_cls: typing.Type[typing_extensions.TypedDict],
data: typing.Optional[typing.Mapping[str, typing.Any]]
):
"""
Ensures that:
- required keys are present
Expand All @@ -782,7 +778,7 @@ class TypedDictInputVerifier:
missing_required_keys = []
required_keys_with_unset_values = []
for required_key in tdict_cls.__required_keys__:
if required_key not in data:
if data is None or required_key not in data:
missing_required_keys.append(required_key)
continue
value = data[required_key]
Expand All @@ -802,10 +798,11 @@ class TypedDictInputVerifier:
)

disallowed_additional_keys = []
for key in data:
if key in tdict_cls.__required_keys__ or key in tdict_cls.__optional_keys__:
continue
disallowed_additional_keys.append(key)
if data is not None:
for key in data:
if key in tdict_cls.__required_keys__ or key in tdict_cls.__optional_keys__:
continue
disallowed_additional_keys.append(key)
if disallowed_additional_keys:
raise exceptions.ApiTypeError(
'{} got {} unexpected keyword arguments: {}'.format(
Expand Down Expand Up @@ -1020,7 +1017,7 @@ class ApiClient:
host: str,
headers: typing.Optional[_collections.HTTPHeaderDict] = None,
body: typing.Union[str, bytes, None] = None,
fields: typing.Optional[typing.Tuple[typing.Tuple[str, str], ...]] = None,
fields: typing.Optional[typing.Tuple[rest.RequestField, ...]] = None,
security_requirement_object: typing.Optional[security_schemes.SecurityRequirementObject] = None,
stream: bool = False,
timeout: typing.Union[int, float, typing.Tuple, None] = None,
Expand Down Expand Up @@ -1090,7 +1087,7 @@ class ApiClient:
method: str,
url: str,
headers: typing.Optional[_collections.HTTPHeaderDict] = None,
fields: typing.Optional[typing.Tuple[typing.Tuple[str, str], ...]] = None,
fields: typing.Optional[typing.Tuple[rest.RequestField, ...]] = None,
body: typing.Union[str, bytes, None] = None,
stream: bool = False,
timeout: typing.Union[int, float, typing.Tuple, None] = None,
Expand Down Expand Up @@ -1189,16 +1186,17 @@ class Api(TypedDictInputVerifier):
def _get_used_path(
used_path: str,
path_parameters: typing.Tuple[typing.Type[PathParameter], ...] = (),
path_params: typing.Optional[typing.Dict[str, _SERIALIZE_TYPES]] = None,
path_params: typing.Optional[typing_extensions.TypedDict] = None,
query_parameters: typing.Tuple[typing.Type[QueryParameter], ...] = (),
query_params: typing.Optional[typing.Dict[str, _SERIALIZE_TYPES]] = None
query_params: typing.Optional[typing_extensions.TypedDict] = None
) -> str:
used_path_params = {}
if path_params is not None:
for parameter in path_parameters:
parameter_data = path_params.get(parameter.name, schemas.unset)
if isinstance(parameter_data, schemas.Unset):
continue
parameter_data = typing.cast(_SERIALIZE_TYPES, parameter_data)
serialized_data = parameter.serialize(parameter_data)
used_path_params.update(serialized_data)

Expand All @@ -1213,6 +1211,7 @@ class Api(TypedDictInputVerifier):
continue
if prefix_separator_iterator is None:
prefix_separator_iterator = parameter.get_prefix_separator_iterator()
parameter_data = typing.cast(_SERIALIZE_TYPES, parameter_data)
serialized_data = parameter.serialize(parameter_data, prefix_separator_iterator)
for serialized_value in serialized_data.values():
used_path += serialized_value
Expand All @@ -1221,7 +1220,7 @@ class Api(TypedDictInputVerifier):
@staticmethod
def _get_headers(
header_parameters: typing.Tuple[typing.Type[HeaderParameter], ...] = (),
header_params: typing.Optional[typing.Dict[str, _SERIALIZE_TYPES]] = None,
header_params: typing.Optional[typing_extensions.TypedDict] = None,
accept_content_types: typing.Tuple[str, ...] = (),
) -> _collections.HTTPHeaderDict:
headers = _collections.HTTPHeaderDict()
Expand All @@ -1230,6 +1229,7 @@ class Api(TypedDictInputVerifier):
parameter_data = header_params.get(parameter.name, schemas.unset)
if isinstance(parameter_data, schemas.Unset):
continue
parameter_data = typing.cast(_SERIALIZE_TYPES, parameter_data)
serialized_data = parameter.serialize(parameter_data)
headers.extend(serialized_data)
if accept_content_types:
Expand All @@ -1239,7 +1239,7 @@ class Api(TypedDictInputVerifier):

@staticmethod
def _get_fields_and_body(
request_body: 'RequestBody',
request_body: typing.Type[RequestBody],
body: typing.Any,
headers: _collections.HTTPHeaderDict,
content_type: str
Expand Down Expand Up @@ -1271,7 +1271,7 @@ class Api(TypedDictInputVerifier):

class SerializedRequestBody(typing_extensions.TypedDict, total=False):
body: typing.Union[str, bytes]
fields: typing.Tuple[typing.Union[RequestField, typing.Tuple[str, str]], ...]
fields: typing.Tuple[rest.RequestField, ...]


class RequestBody(StyleFormSerializer, JSONDetector):
Expand Down Expand Up @@ -1307,24 +1307,24 @@ class RequestBody(StyleFormSerializer, JSONDetector):
return {'body': str(in_data)}

@classmethod
def __multipart_json_item(cls, key: str, value: schemas.Schema) -> RequestField:
def __multipart_json_item(cls, key: str, value: schemas.Schema) -> rest.RequestField:
json_value = cls.__json_encoder.default(value)
request_field = RequestField(name=key, data=json.dumps(json_value))
request_field = rest.RequestField(name=key, data=json.dumps(json_value))
request_field.make_multipart(content_type='application/json')
return request_field

@classmethod
def __multipart_form_item(cls, key: str, value: schemas.Schema) -> RequestField:
def __multipart_form_item(cls, key: str, value: schemas.Schema) -> rest.RequestField:
if isinstance(value, str):
request_field = RequestField(name=key, data=str(value))
request_field = rest.RequestField(name=key, data=str(value))
request_field.make_multipart(content_type='text/plain')
elif isinstance(value, bytes):
request_field = RequestField(name=key, data=value)
request_field = rest.RequestField(name=key, data=value)
request_field.make_multipart(content_type='application/octet-stream')
elif isinstance(value, schemas.FileIO):
# TODO use content.encoding to limit allowed content types if they are present
request_field = RequestField.from_tuples(key, (os.path.basename(str(value.name)), value.read()))
request_field = typing.cast(RequestField, request_field)
request_field = rest.RequestField.from_tuples(key, (os.path.basename(str(value.name)), value.read()))
request_field = typing.cast(rest.RequestField, request_field)
value.close()
else:
request_field = cls.__multipart_json_item(key=key, value=value)
Expand Down Expand Up @@ -1353,7 +1353,7 @@ class RequestBody(StyleFormSerializer, JSONDetector):
for key, value in in_data.items():
if isinstance(value, tuple):
if value:
# values use explode = True, so the code makes a RequestField for each item with name=key
# values use explode = True, so the code makes a rest.RequestField for each item with name=key
for item in value:
request_field = cls.__multipart_form_item(key=key, value=item)
fields.append(request_field)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,5 @@ class ApiResponse:
@dataclasses.dataclass
class ApiResponseWithoutDeserialization(ApiResponse):
response: urllib3.HTTPResponse
body: typing.Union[schemas.Unset, schemas.Schema] = schemas.unset
headers: typing.Union[schemas.Unset, typing_extensions.TypedDict] = schemas.unset
body: schemas.Unset = schemas.unset
headers: schemas.Unset = schemas.unset
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ class {{jsonPathPiece.camelCase}}(api_client.RequestBody):
class {{@key.camelCase}}MediaType(api_client.MediaType):
{{#with this}}
{{#with schema}}
schema: typing.Type[{{../@key.snakeCase}}_{{jsonPathPiece.snakeCase}}.{{jsonPathPiece.camelCase}}] = {{../@key.snakeCase}}_{{jsonPathPiece.snakeCase}}.{{jsonPathPiece.camelCase}}
{{> components/_helper_content_schema_type paramName="schema" modulePrefix=../@key.snakeCase }}
{{/with}}
{{/with}}
{{/each}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,18 @@ def __new__(
{{#if types}}
{{#eq types.size 1}}
{{#contains types "array"}}
arg_: typing.Union[
typing.Tuple[
{{#with ../items}}{{#if refInfo.refClass}}typing.Union['{{> components/schemas/_helper_refclass_with_module }}', {{#with getDeepestRef}}{{> _helper_schema_python_types }}{{/with}}]{{else}}typing.Union[Schema_.{{jsonPathPiece.camelCase}}, {{> _helper_schema_python_types }}]{{/if}}{{/with}}, ...
],
typing.List[
{{#with ../items}}{{#if refInfo.refClass}}typing.Union['{{> components/schemas/_helper_refclass_with_module }}', {{#with getDeepestRef}}{{> _helper_schema_python_types }}{{/with}}]{{else}}typing.Union[Schema_.{{jsonPathPiece.camelCase}}, {{> _helper_schema_python_types }}]{{/if}}{{/with}}
],
arg_: typing.Sequence[
{{#with ../items}}
{{#if refInfo.refClass}}
typing.Union[
{{> components/schemas/_helper_new_ref_property_value_type optional=false }}
]
{{else}}
typing.Union[
{{> components/schemas/_helper_new_property_value_type propertyClass=null optional=false }}
]
{{/if}}
{{/with}}
],
{{/contains}}
{{#contains types "object"}}
Expand All @@ -32,13 +37,19 @@ def __new__(
{{/contains}}
{{else}}
{{#contains types "object"}}
*args_: typing.Union[{{> _helper_schema_python_types }}],
*args_: typing.Union[
{{> _helper_schema_python_types_newline }}
],
{{else}}
arg_: typing.Union[{{> _helper_schema_python_types }}],
arg_: typing.Union[
{{> _helper_schema_python_types_newline }}
],
{{/contains}}
{{/eq}}
{{else}}
*args_: typing.Union[{{> _helper_schema_python_types }}],
*args_: typing.Union[
{{> _helper_schema_python_types_newline }}
],
{{/if}}
{{#if types}}
{{#eq types.size 1}}
Expand All @@ -47,16 +58,27 @@ def __new__(
{{#if @key.isValid}}
{{#with this}}
{{#if refInfo.refClass}}
{{@key.original}}: typing.Union['{{> components/schemas/_helper_refclass_with_module }}', {{#with getDeepestRef}}{{> _helper_schema_python_types }}{{/with}}],
{{@key.original}}: typing.Union[
{{> components/schemas/_helper_new_ref_property_value_type optional=false }}
],
{{else}}
{{#if jsonPathPiece}}
{{#if schemaIsFromAdditionalProperties}}
{{@key.original}}: typing.Union[Schema_.{{jsonPathPiece.camelCase}}, {{> _helper_schema_python_types }}],
{{@key.original}}: typing.Union[
{{> components/schemas/_helper_new_property_value_type propertyClass=null optional=false }}
],
{{else}}
{{@key.original}}: typing.Union[Schema_.Properties.{{jsonPathPiece.camelCase}}, {{> _helper_schema_python_types }}],
{{@key.original}}: typing.Union[
{{> components/schemas/_helper_new_property_value_type propertyClass="Properties" optional=false }}
],
{{/if}}
{{else}}
{{@key.original}}: typing.Union[schemas.AnyTypeSchema, {{> _helper_schema_python_types }}],
{{@key.original}}: typing.Union[
schemas.AnyTypeSchema[typing.Union[
{{> components/schemas/_helper_schema_python_base_types_newline }}
]],
{{> _helper_schema_python_types_newline }}
],
{{/if}}
{{/if}}
{{/with}}
Expand All @@ -68,27 +90,39 @@ def __new__(
{{#each optionalProperties}}
{{#if @key.isValid}}
{{#if refInfo.refClass}}
{{@key.original}}: typing.Union['{{> components/schemas/_helper_refclass_with_module }}', {{#with getDeepestRef}}{{> _helper_schema_python_types }}{{/with}}, schemas.Unset] = schemas.unset,
{{@key.original}}: typing.Union[
{{> components/schemas/_helper_new_ref_property_value_type optional=true }}
] = schemas.unset,
{{else}}
{{@key.original}}: typing.Union[Schema_.Properties.{{jsonPathPiece.camelCase}}, {{> _helper_schema_python_types }}, schemas.Unset] = schemas.unset,
{{@key.original}}: typing.Union[
{{> components/schemas/_helper_new_property_value_type propertyClass="Properties" optional=true }}
] = schemas.unset,
{{/if}}
{{/if}}
{{/each}}
configuration_: typing.Optional[schemas.schema_configuration.SchemaConfiguration] = None,
{{#with additionalProperties}}
{{#unless isBooleanSchemaFalse}}
{{#if refInfo.refClass}}
**kwargs: typing.Union['{{> components/schemas/_helper_refclass_with_module }}', {{#with getDeepestRef}}{{> _helper_schema_python_types }}{{/with}}],
**kwargs: typing.Union[
{{> components/schemas/_helper_new_ref_property_value_type optional=false }}
],
{{else}}
**kwargs: typing.Union[Schema_.{{jsonPathPiece.camelCase}}, {{> _helper_schema_python_types }}],
**kwargs: typing.Union[
{{> components/schemas/_helper_new_property_value_type propertyClass=null optional=false }}
],
{{/if}}
{{/unless}}
{{else}}
{{#eq types null}}
**kwargs: typing.Union[{{> components/schemas/_helper_types_all_incl_schema_oneline }}],
**kwargs: typing.Union[
{{> components/schemas/_helper_types_all_incl_schema_newline }}
],
{{else}}
{{#contains types "object"}}
**kwargs: typing.Union[{{> components/schemas/_helper_types_all_incl_schema_oneline }}],
**kwargs: typing.Union[
{{> components/schemas/_helper_types_all_incl_schema_newline }}
],
{{/contains}}
{{/eq}}
{{/with}}
Expand Down
Loading

0 comments on commit 646c57c

Please sign in to comment.