Skip to content

Commit

Permalink
[python-experimental] fixes json + charset use case (#12114)
Browse files Browse the repository at this point in the history
* Adds code to detect json content type when charset is also set

* Updates template to properly render content type, regenerates samples

* Adds test_json_with_charset

* Reverts version file

* Fixes typo
  • Loading branch information
spacether authored Apr 12, 2022
1 parent d17316e commit b29b5e1
Show file tree
Hide file tree
Showing 9 changed files with 327 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -719,7 +719,20 @@ class ApiResponseWithoutDeserialization(ApiResponse):
headers: typing.Union[Unset, typing.List[HeaderParameter]] = unset


class OpenApiResponse:
class JSONDetector:
@staticmethod
def content_type_is_json(content_type: str) -> bool:
"""
for when content_type strings also include charset info like:
application/json; charset=UTF-8
"""
content_type_piece = content_type.split(';')[0]
if content_type_piece == 'application/json':
return True
return False


class OpenApiResponse(JSONDetector):
def __init__(
self,
response_cls: typing.Type[ApiResponse] = ApiResponse,
Expand All @@ -734,8 +747,8 @@ class OpenApiResponse:

@staticmethod
def __deserialize_json(response: urllib3.HTTPResponse) -> typing.Any:
decoded_data = response.data.decode("utf-8")
return json.loads(decoded_data)
# python must be >= 3.9 so we can pass in bytes into json.loads
return json.loads(response.data)

@staticmethod
def __file_name_from_content_disposition(content_disposition: typing.Optional[str]) -> typing.Optional[str]:
Expand Down Expand Up @@ -796,7 +809,7 @@ class OpenApiResponse:
deserialized_body = unset
streamed = response.supports_chunked_reads()
if self.content is not None:
if content_type == 'application/json':
if self.content_type_is_json(content_type):
body_data = self.__deserialize_json(response)
elif content_type == 'application/octet-stream':
body_data = self.__deserialize_application_octet_stream(response)
Expand Down Expand Up @@ -1245,7 +1258,7 @@ class SerializedRequestBody(typing.TypedDict, total=False):
fields: typing.Tuple[typing.Union[RequestField, tuple[str, str]], ...]


class RequestBody(StyleFormSerializer):
class RequestBody(StyleFormSerializer, JSONDetector):
"""
A request body parameter
content: content_type to MediaType Schema info
Expand Down Expand Up @@ -1382,7 +1395,7 @@ class RequestBody(StyleFormSerializer):
cast_in_data = media_type.schema(in_data)
# TODO check for and use encoding if it exists
# and content_type is multipart or application/x-www-form-urlencoded
if content_type == 'application/json':
if self.content_type_is_json(content_type):
return self.__serialize_json(cast_in_data)
elif content_type == 'text/plain':
return self.__serialize_text_plain(cast_in_data)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ class RequestCookieParams(RequestRequiredCookieParams, RequestOptionalCookiePara
request_body_{{paramName}} = api_client.RequestBody(
content={
{{#each content}}
'{{@key}}': api_client.MediaType(
'{{{@key}}}': api_client.MediaType(
schema={{this.schema.baseName}}),
{{/each}}
},
Expand Down Expand Up @@ -323,7 +323,7 @@ _response_for_{{code}} = api_client.OpenApiResponse(
{{#if @first}}
content={
{{/if}}
'{{@key}}': api_client.MediaType(
'{{{@key}}}': api_client.MediaType(
schema={{this.schema.baseName}}),
{{#if @last}}
},
Expand Down Expand Up @@ -351,7 +351,7 @@ _status_code_to_response = {
{{#if @first}}
_all_accept_content_types = (
{{/if}}
'{{this.mediaType}}',
'{{{this.mediaType}}}',
{{#if @last}}
)
{{/if}}
Expand Down Expand Up @@ -382,7 +382,7 @@ class {{operationIdCamelCase}}(api_client.Api):
{{#with bodyParam}}
{{#each content}}
{{#if @first}}
content_type: str = '{{@key}}',
content_type: str = '{{{@key}}}',
{{/if}}
{{/each}}
{{/with}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1530,6 +1530,22 @@ paths:
responses:
'200':
description: ok
'/fake/jsonWithCharset':
post:
tags:
- fake
summary: json with charset tx and rx
operationId: jsonWithCharset
requestBody:
content:
application/json; charset=utf-8:
schema: {}
responses:
200:
description: success
content:
application/json; charset=utf-8:
schema: {}
servers:
- url: 'http://{server}.swagger.io:{port}/v2'
description: petstore server
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ Class | Method | HTTP request | Description
*FakeApi* | [**inline_additional_properties**](docs/FakeApi.md#inline_additional_properties) | **POST** /fake/inline-additionalProperties | test inline additionalProperties
*FakeApi* | [**inline_composition**](docs/FakeApi.md#inline_composition) | **POST** /fake/inlineComposition/ | testing composed schemas at inline locations
*FakeApi* | [**json_form_data**](docs/FakeApi.md#json_form_data) | **GET** /fake/jsonFormData | test json serialization of form data
*FakeApi* | [**json_with_charset**](docs/FakeApi.md#json_with_charset) | **POST** /fake/jsonWithCharset | json with charset tx and rx
*FakeApi* | [**mammal**](docs/FakeApi.md#mammal) | **POST** /fake/refs/mammal |
*FakeApi* | [**number_with_validations**](docs/FakeApi.md#number_with_validations) | **POST** /fake/refs/number |
*FakeApi* | [**object_in_query**](docs/FakeApi.md#object_in_query) | **GET** /fake/objInQuery | user list
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ Method | HTTP request | Description
[**inline_additional_properties**](FakeApi.md#inline_additional_properties) | **POST** /fake/inline-additionalProperties | test inline additionalProperties
[**inline_composition**](FakeApi.md#inline_composition) | **POST** /fake/inlineComposition/ | testing composed schemas at inline locations
[**json_form_data**](FakeApi.md#json_form_data) | **GET** /fake/jsonFormData | test json serialization of form data
[**json_with_charset**](FakeApi.md#json_with_charset) | **POST** /fake/jsonWithCharset | json with charset tx and rx
[**mammal**](FakeApi.md#mammal) | **POST** /fake/refs/mammal |
[**number_with_validations**](FakeApi.md#number_with_validations) | **POST** /fake/refs/number |
[**object_in_query**](FakeApi.md#object_in_query) | **GET** /fake/objInQuery | user list
Expand Down Expand Up @@ -1618,6 +1619,87 @@ No authorization required

[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)

# **json_with_charset**
> bool, date, datetime, dict, float, int, list, str, none_type json_with_charset()
json with charset tx and rx

### Example

```python
import petstore_api
from petstore_api.api import fake_api
from pprint import pprint
# Defining the host is optional and defaults to http://petstore.swagger.io:80/v2
# See configuration.py for a list of all supported configuration parameters.
configuration = petstore_api.Configuration(
host = "http://petstore.swagger.io:80/v2"
)

# Enter a context with an instance of the API client
with petstore_api.ApiClient(configuration) as api_client:
# Create an instance of the API class
api_instance = fake_api.FakeApi(api_client)

# example passing only optional values
body = None
try:
# json with charset tx and rx
api_response = api_instance.json_with_charset(
body=body,
)
pprint(api_response)
except petstore_api.ApiException as e:
print("Exception when calling FakeApi->json_with_charset: %s\n" % e)
```
### Parameters

Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------
body | typing.Union[SchemaForRequestBodyApplicationJsonCharsetutf8, Unset] | optional, default is unset |
content_type | str | optional, default is 'application/json; charset=utf-8' | Selects the schema and serialization of the request body
accept_content_types | typing.Tuple[str] | default is ('application/json; charset=utf-8', ) | Tells the server the content type(s) that are accepted by the client
stream | bool | default is False | if True then the response.content will be streamed and loaded from a file like object. When downloading a file, set this to True to force the code to deserialize the content to a FileSchema file
timeout | typing.Optional[typing.Union[int, typing.Tuple]] | default is None | the timeout used by the rest client
skip_deserialization | bool | default is False | when True, headers and body will be unset and an instance of api_client.ApiResponseWithoutDeserialization will be returned

### body

#### SchemaForRequestBodyApplicationJsonCharsetutf8

Type | Description | Notes
------------- | ------------- | -------------
typing.Union[dict, frozendict, str, date, datetime, int, float, bool, Decimal, None, list, tuple, bytes] | |

### Return Types, Responses

Code | Class | Description
------------- | ------------- | -------------
n/a | api_client.ApiResponseWithoutDeserialization | When skip_deserialization is True this response is returned
200 | ApiResponseFor200 | success

#### ApiResponseFor200
Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------
response | urllib3.HTTPResponse | Raw response |
body | typing.Union[SchemaFor200ResponseBodyApplicationJsonCharsetutf8, ] | |
headers | Unset | headers were not defined |

#### SchemaFor200ResponseBodyApplicationJsonCharsetutf8

Type | Description | Notes
------------- | ------------- | -------------
typing.Union[dict, frozendict, str, date, datetime, int, float, bool, Decimal, None, list, tuple, bytes] | |


**bool, date, datetime, dict, float, int, list, str, none_type**

### Authorization

No authorization required

[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)

# **mammal**
> Mammal mammal(mammal)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
from petstore_api.api.fake_api_endpoints.inline_additional_properties import InlineAdditionalProperties
from petstore_api.api.fake_api_endpoints.inline_composition import InlineComposition
from petstore_api.api.fake_api_endpoints.json_form_data import JsonFormData
from petstore_api.api.fake_api_endpoints.json_with_charset import JsonWithCharset
from petstore_api.api.fake_api_endpoints.mammal import Mammal
from petstore_api.api.fake_api_endpoints.number_with_validations import NumberWithValidations
from petstore_api.api.fake_api_endpoints.object_in_query import ObjectInQuery
Expand Down Expand Up @@ -57,6 +58,7 @@ class FakeApi(
InlineAdditionalProperties,
InlineComposition,
JsonFormData,
JsonWithCharset,
Mammal,
NumberWithValidations,
ObjectInQuery,
Expand Down
Loading

0 comments on commit b29b5e1

Please sign in to comment.