forked from loafle/openapi-generator-original
[Python] Fix Python UTF-8 Encoding Issue (#5679)
* Try decoding but don't bail on error * Switch binary and ByteArray to bytes * Read content type and parse appropriately * Remove response parsing * Remove response parsing and just return the data * Update petshop examples w/ new generator code * Fix copy/paste error with naming * Update petstore examples * Move response decoding to inside _preload_content block * Update the clients again * Use a raw string for the regex pattern * Regenerate petstore clients * Add bytes to python primitives as it's supported in 2.7 and 3 * Add bytes to the exports from model_utils * Import bytes from model_utils * Add conditional typing for regex pattern to match variable type * Regenerate petstore clients * Use read() instead of text() for asyncio * Regenerate petstore clients * Remove unused six import * Regenerate petstore clients * Add newline to kick Circle to re-run * Remove whitespace from tox.ini * Update more examples after ensure_updated * Add sample updates that didn't run with the --batch flag * Remove extra bracket in regex to remove warning * Stop printing debug messages * Add bytes examples to python doc generators * Update generated FakeApi docs * Regenerate api_client.py * Remove print statements from generated clients * Update bytes example in FakeApi.md. Again. I swear. * Add yet another seemingly missing doc update * Catch the error, decode the body, and re-throw * Remove the updates now that the change is non-breaking * Regenerate client * Add bytes deserialization test * Update exception parsing * Add exception parsing for python-experimental * Regenerate client with minor changes * Revert test changes * Regenerate model_utils.py * Update confusing test name * Remove bytes from mapping and examples * Add back in the old binary/ByteArray to str mapping * Update docs and api_client template * Add experimental api_client changes * Regenerate samples again * Add Tornado handling to early return * Try fixing Tornado python returns * More documentation changes * Re-generate the client code * Remove bytes from test_format_test * Remove more leftover bytes usages * Switch bytes validation back to string * Fix format_test template and regenerate * Remove unused bytes var * Remove bytes import from models and regenerate * Remove bytes import from test_deserialization * Reduce nested ifs * Remove byte logic for now * Regenerate client after latest changes * Remove another bytes usage * Regenerate after removing dangling byte string usage * Reduce the scope of the try/catch in api_client * Regenerate after try/catch cleanup * Swap catch for except * Regenerate Python client after api_client change * Fix lint error on the generated api_client * Add binary format test back in w/ string * Add decoding to python-experimental and regenerate * Import re into python-experimental api_client * Ensure file upload json response is utf-8 encoded bytes
This commit is contained in:
parent
cef5470ea8
commit
db5941379f
@ -31,6 +31,7 @@ sidebar_label: python-experimental
|
|||||||
|
|
||||||
<ul class="column-ul">
|
<ul class="column-ul">
|
||||||
<li>bool</li>
|
<li>bool</li>
|
||||||
|
<li>bytes</li>
|
||||||
<li>date</li>
|
<li>date</li>
|
||||||
<li>datetime</li>
|
<li>datetime</li>
|
||||||
<li>dict</li>
|
<li>dict</li>
|
||||||
|
@ -31,6 +31,7 @@ sidebar_label: python
|
|||||||
|
|
||||||
<ul class="column-ul">
|
<ul class="column-ul">
|
||||||
<li>bool</li>
|
<li>bool</li>
|
||||||
|
<li>bytes</li>
|
||||||
<li>date</li>
|
<li>date</li>
|
||||||
<li>datetime</li>
|
<li>datetime</li>
|
||||||
<li>dict</li>
|
<li>dict</li>
|
||||||
|
@ -119,6 +119,7 @@ public class PythonClientCodegen extends DefaultCodegen implements CodegenConfig
|
|||||||
languageSpecificPrimitives.add("object");
|
languageSpecificPrimitives.add("object");
|
||||||
// TODO file and binary is mapped as `file`
|
// TODO file and binary is mapped as `file`
|
||||||
languageSpecificPrimitives.add("file");
|
languageSpecificPrimitives.add("file");
|
||||||
|
languageSpecificPrimitives.add("bytes");
|
||||||
|
|
||||||
typeMapping.clear();
|
typeMapping.clear();
|
||||||
typeMapping.put("integer", "int");
|
typeMapping.put("integer", "int");
|
||||||
|
@ -22,7 +22,7 @@ import tornado.gen
|
|||||||
from {{packageName}}.configuration import Configuration
|
from {{packageName}}.configuration import Configuration
|
||||||
import {{modelPackage}}
|
import {{modelPackage}}
|
||||||
from {{packageName}} import rest
|
from {{packageName}} import rest
|
||||||
from {{packageName}}.exceptions import ApiValueError
|
from {{packageName}}.exceptions import ApiValueError, ApiException
|
||||||
|
|
||||||
|
|
||||||
class ApiClient(object):
|
class ApiClient(object):
|
||||||
@ -186,17 +186,38 @@ class ApiClient(object):
|
|||||||
# use server/host defined in path or operation instead
|
# use server/host defined in path or operation instead
|
||||||
url = _host + resource_path
|
url = _host + resource_path
|
||||||
|
|
||||||
|
try:
|
||||||
# perform request and return response
|
# perform request and return response
|
||||||
response_data = {{#asyncio}}await {{/asyncio}}{{#tornado}}yield {{/tornado}}self.request(
|
response_data = {{#asyncio}}await {{/asyncio}}{{#tornado}}yield {{/tornado}}self.request(
|
||||||
method, url, query_params=query_params, headers=header_params,
|
method, url, query_params=query_params, headers=header_params,
|
||||||
post_params=post_params, body=body,
|
post_params=post_params, body=body,
|
||||||
_preload_content=_preload_content,
|
_preload_content=_preload_content,
|
||||||
_request_timeout=_request_timeout)
|
_request_timeout=_request_timeout)
|
||||||
|
except ApiException as e:
|
||||||
|
e.body = e.body.decode('utf-8') if six.PY3 else e.body
|
||||||
|
raise e
|
||||||
|
|
||||||
|
content_type = response_data.getheader('content-type')
|
||||||
|
|
||||||
self.last_response = response_data
|
self.last_response = response_data
|
||||||
|
|
||||||
return_data = response_data
|
return_data = response_data
|
||||||
if _preload_content:
|
|
||||||
|
if not _preload_content:
|
||||||
|
{{^tornado}}
|
||||||
|
return return_data
|
||||||
|
{{/tornado}}
|
||||||
|
{{#tornado}}
|
||||||
|
raise tornado.gen.Return(return_data)
|
||||||
|
{{/tornado}}
|
||||||
|
|
||||||
|
if six.PY3 and response_type not in ["file", "bytes"]:
|
||||||
|
match = None
|
||||||
|
if content_type is not None:
|
||||||
|
match = re.search(r"charset=([a-zA-Z\-\d]+)[\s\;]?", content_type)
|
||||||
|
encoding = match.group(1) if match else "utf-8"
|
||||||
|
response_data.data = response_data.data.decode(encoding)
|
||||||
|
|
||||||
# deserialize response data
|
# deserialize response data
|
||||||
if response_type:
|
if response_type:
|
||||||
return_data = self.deserialize(response_data, response_type)
|
return_data = self.deserialize(response_data, response_type)
|
||||||
|
@ -166,7 +166,7 @@ class RESTClientObject(object):
|
|||||||
r = await self.pool_manager.request(**args)
|
r = await self.pool_manager.request(**args)
|
||||||
if _preload_content:
|
if _preload_content:
|
||||||
|
|
||||||
data = await r.text()
|
data = await r.read()
|
||||||
r = RESTResponse(r, data)
|
r = RESTResponse(r, data)
|
||||||
|
|
||||||
# log response body
|
# log response body
|
||||||
|
@ -7,6 +7,7 @@ import atexit
|
|||||||
import mimetypes
|
import mimetypes
|
||||||
from multiprocessing.pool import ThreadPool
|
from multiprocessing.pool import ThreadPool
|
||||||
import os
|
import os
|
||||||
|
import re
|
||||||
|
|
||||||
# python 2 and python 3 compatibility library
|
# python 2 and python 3 compatibility library
|
||||||
import six
|
import six
|
||||||
@ -17,7 +18,7 @@ import tornado.gen
|
|||||||
|
|
||||||
from {{packageName}} import rest
|
from {{packageName}} import rest
|
||||||
from {{packageName}}.configuration import Configuration
|
from {{packageName}}.configuration import Configuration
|
||||||
from {{packageName}}.exceptions import ApiValueError
|
from {{packageName}}.exceptions import ApiValueError, ApiException
|
||||||
from {{packageName}}.model_utils import (
|
from {{packageName}}.model_utils import (
|
||||||
ModelNormal,
|
ModelNormal,
|
||||||
ModelSimple,
|
ModelSimple,
|
||||||
@ -176,17 +177,39 @@ class ApiClient(object):
|
|||||||
# use server/host defined in path or operation instead
|
# use server/host defined in path or operation instead
|
||||||
url = _host + resource_path
|
url = _host + resource_path
|
||||||
|
|
||||||
|
try:
|
||||||
# perform request and return response
|
# perform request and return response
|
||||||
response_data = {{#asyncio}}await {{/asyncio}}{{#tornado}}yield {{/tornado}}self.request(
|
response_data = {{#asyncio}}await {{/asyncio}}{{#tornado}}yield {{/tornado}}self.request(
|
||||||
method, url, query_params=query_params, headers=header_params,
|
method, url, query_params=query_params, headers=header_params,
|
||||||
post_params=post_params, body=body,
|
post_params=post_params, body=body,
|
||||||
_preload_content=_preload_content,
|
_preload_content=_preload_content,
|
||||||
_request_timeout=_request_timeout)
|
_request_timeout=_request_timeout)
|
||||||
|
except ApiException as e:
|
||||||
|
e.body = e.body.decode('utf-8') if six.PY3 else e.body
|
||||||
|
raise e
|
||||||
|
|
||||||
|
content_type = response_data.getheader('content-type')
|
||||||
|
|
||||||
self.last_response = response_data
|
self.last_response = response_data
|
||||||
|
|
||||||
return_data = response_data
|
return_data = response_data
|
||||||
if _preload_content:
|
|
||||||
|
if not _preload_content:
|
||||||
|
{{^tornado}}
|
||||||
|
return (return_data)
|
||||||
|
{{/tornado}}
|
||||||
|
{{#tornado}}
|
||||||
|
raise tornado.gen.Return(return_data)
|
||||||
|
{{/tornado}}
|
||||||
|
return return_data
|
||||||
|
|
||||||
|
if six.PY3 and response_type not in ["file", "bytes"]:
|
||||||
|
match = None
|
||||||
|
if content_type is not None:
|
||||||
|
match = re.search(r"charset=([a-zA-Z\-\d]+)[\s\;]?", content_type)
|
||||||
|
encoding = match.group(1) if match else "utf-8"
|
||||||
|
response_data.data = response_data.data.decode(encoding)
|
||||||
|
|
||||||
# deserialize response data
|
# deserialize response data
|
||||||
if response_type:
|
if response_type:
|
||||||
return_data = self.deserialize(
|
return_data = self.deserialize(
|
||||||
|
@ -209,11 +209,6 @@ class RESTClientObject(object):
|
|||||||
if _preload_content:
|
if _preload_content:
|
||||||
r = RESTResponse(r)
|
r = RESTResponse(r)
|
||||||
|
|
||||||
# In the python 3, the response.data is bytes.
|
|
||||||
# we need to decode it to string.
|
|
||||||
if six.PY3:
|
|
||||||
r.data = r.data.decode('utf8')
|
|
||||||
|
|
||||||
# log response body
|
# log response body
|
||||||
logger.debug("response body: %s", r.data)
|
logger.debug("response body: %s", r.data)
|
||||||
|
|
||||||
|
@ -8,7 +8,6 @@ import logging
|
|||||||
import re
|
import re
|
||||||
|
|
||||||
# python 2 and python 3 compatibility library
|
# python 2 and python 3 compatibility library
|
||||||
import six
|
|
||||||
from six.moves.urllib.parse import urlencode
|
from six.moves.urllib.parse import urlencode
|
||||||
import tornado
|
import tornado
|
||||||
import tornado.gen
|
import tornado.gen
|
||||||
@ -28,10 +27,6 @@ class RESTResponse(io.IOBase):
|
|||||||
self.reason = resp.reason
|
self.reason = resp.reason
|
||||||
|
|
||||||
if resp.body:
|
if resp.body:
|
||||||
# In Python 3, the response body is utf-8 encoded bytes.
|
|
||||||
if six.PY3:
|
|
||||||
self.data = resp.body.decode('utf-8')
|
|
||||||
else:
|
|
||||||
self.data = resp.body
|
self.data = resp.body
|
||||||
else:
|
else:
|
||||||
self.data = None
|
self.data = None
|
||||||
|
@ -27,7 +27,7 @@ from six.moves.urllib.parse import quote
|
|||||||
from petstore_api.configuration import Configuration
|
from petstore_api.configuration import Configuration
|
||||||
import petstore_api.models
|
import petstore_api.models
|
||||||
from petstore_api import rest
|
from petstore_api import rest
|
||||||
from petstore_api.exceptions import ApiValueError
|
from petstore_api.exceptions import ApiValueError, ApiException
|
||||||
|
|
||||||
|
|
||||||
class ApiClient(object):
|
class ApiClient(object):
|
||||||
@ -177,17 +177,33 @@ class ApiClient(object):
|
|||||||
# use server/host defined in path or operation instead
|
# use server/host defined in path or operation instead
|
||||||
url = _host + resource_path
|
url = _host + resource_path
|
||||||
|
|
||||||
|
try:
|
||||||
# perform request and return response
|
# perform request and return response
|
||||||
response_data = await self.request(
|
response_data = await self.request(
|
||||||
method, url, query_params=query_params, headers=header_params,
|
method, url, query_params=query_params, headers=header_params,
|
||||||
post_params=post_params, body=body,
|
post_params=post_params, body=body,
|
||||||
_preload_content=_preload_content,
|
_preload_content=_preload_content,
|
||||||
_request_timeout=_request_timeout)
|
_request_timeout=_request_timeout)
|
||||||
|
except ApiException as e:
|
||||||
|
e.body = e.body.decode('utf-8') if six.PY3 else e.body
|
||||||
|
raise e
|
||||||
|
|
||||||
|
content_type = response_data.getheader('content-type')
|
||||||
|
|
||||||
self.last_response = response_data
|
self.last_response = response_data
|
||||||
|
|
||||||
return_data = response_data
|
return_data = response_data
|
||||||
if _preload_content:
|
|
||||||
|
if not _preload_content:
|
||||||
|
return return_data
|
||||||
|
|
||||||
|
if six.PY3 and response_type not in ["file", "bytes"]:
|
||||||
|
match = None
|
||||||
|
if content_type is not None:
|
||||||
|
match = re.search(r"charset=([a-zA-Z\-\d]+)[\s\;]?", content_type)
|
||||||
|
encoding = match.group(1) if match else "utf-8"
|
||||||
|
response_data.data = response_data.data.decode(encoding)
|
||||||
|
|
||||||
# deserialize response data
|
# deserialize response data
|
||||||
if response_type:
|
if response_type:
|
||||||
return_data = self.deserialize(response_data, response_type)
|
return_data = self.deserialize(response_data, response_type)
|
||||||
|
@ -174,7 +174,7 @@ class RESTClientObject(object):
|
|||||||
r = await self.pool_manager.request(**args)
|
r = await self.pool_manager.request(**args)
|
||||||
if _preload_content:
|
if _preload_content:
|
||||||
|
|
||||||
data = await r.text()
|
data = await r.read()
|
||||||
r = RESTResponse(r, data)
|
r = RESTResponse(r, data)
|
||||||
|
|
||||||
# log response body
|
# log response body
|
||||||
|
@ -15,6 +15,7 @@ import atexit
|
|||||||
import mimetypes
|
import mimetypes
|
||||||
from multiprocessing.pool import ThreadPool
|
from multiprocessing.pool import ThreadPool
|
||||||
import os
|
import os
|
||||||
|
import re
|
||||||
|
|
||||||
# python 2 and python 3 compatibility library
|
# python 2 and python 3 compatibility library
|
||||||
import six
|
import six
|
||||||
@ -22,7 +23,7 @@ from six.moves.urllib.parse import quote
|
|||||||
|
|
||||||
from petstore_api import rest
|
from petstore_api import rest
|
||||||
from petstore_api.configuration import Configuration
|
from petstore_api.configuration import Configuration
|
||||||
from petstore_api.exceptions import ApiValueError
|
from petstore_api.exceptions import ApiValueError, ApiException
|
||||||
from petstore_api.model_utils import (
|
from petstore_api.model_utils import (
|
||||||
ModelNormal,
|
ModelNormal,
|
||||||
ModelSimple,
|
ModelSimple,
|
||||||
@ -178,17 +179,34 @@ class ApiClient(object):
|
|||||||
# use server/host defined in path or operation instead
|
# use server/host defined in path or operation instead
|
||||||
url = _host + resource_path
|
url = _host + resource_path
|
||||||
|
|
||||||
|
try:
|
||||||
# perform request and return response
|
# perform request and return response
|
||||||
response_data = self.request(
|
response_data = self.request(
|
||||||
method, url, query_params=query_params, headers=header_params,
|
method, url, query_params=query_params, headers=header_params,
|
||||||
post_params=post_params, body=body,
|
post_params=post_params, body=body,
|
||||||
_preload_content=_preload_content,
|
_preload_content=_preload_content,
|
||||||
_request_timeout=_request_timeout)
|
_request_timeout=_request_timeout)
|
||||||
|
except ApiException as e:
|
||||||
|
e.body = e.body.decode('utf-8') if six.PY3 else e.body
|
||||||
|
raise e
|
||||||
|
|
||||||
|
content_type = response_data.getheader('content-type')
|
||||||
|
|
||||||
self.last_response = response_data
|
self.last_response = response_data
|
||||||
|
|
||||||
return_data = response_data
|
return_data = response_data
|
||||||
if _preload_content:
|
|
||||||
|
if not _preload_content:
|
||||||
|
return (return_data)
|
||||||
|
return return_data
|
||||||
|
|
||||||
|
if six.PY3 and response_type not in ["file", "bytes"]:
|
||||||
|
match = None
|
||||||
|
if content_type is not None:
|
||||||
|
match = re.search(r"charset=([a-zA-Z\-\d]+)[\s\;]?", content_type)
|
||||||
|
encoding = match.group(1) if match else "utf-8"
|
||||||
|
response_data.data = response_data.data.decode(encoding)
|
||||||
|
|
||||||
# deserialize response data
|
# deserialize response data
|
||||||
if response_type:
|
if response_type:
|
||||||
return_data = self.deserialize(
|
return_data = self.deserialize(
|
||||||
|
@ -217,11 +217,6 @@ class RESTClientObject(object):
|
|||||||
if _preload_content:
|
if _preload_content:
|
||||||
r = RESTResponse(r)
|
r = RESTResponse(r)
|
||||||
|
|
||||||
# In the python 3, the response.data is bytes.
|
|
||||||
# we need to decode it to string.
|
|
||||||
if six.PY3:
|
|
||||||
r.data = r.data.decode('utf8')
|
|
||||||
|
|
||||||
# log response body
|
# log response body
|
||||||
logger.debug("response body: %s", r.data)
|
logger.debug("response body: %s", r.data)
|
||||||
|
|
||||||
|
@ -10,6 +10,7 @@ $ nosetests -v
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
import six
|
||||||
import sys
|
import sys
|
||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
|
@ -377,6 +377,36 @@ class DeserializationTests(unittest.TestCase):
|
|||||||
finally:
|
finally:
|
||||||
os.unlink(file_path)
|
os.unlink(file_path)
|
||||||
|
|
||||||
|
def test_deserialize_binary_to_str(self):
|
||||||
|
"""Ensures that bytes deserialization works"""
|
||||||
|
response_types_mixed = (str,)
|
||||||
|
|
||||||
|
# sample from http://www.jtricks.com/download-text
|
||||||
|
HTTPResponse = namedtuple(
|
||||||
|
'urllib3_response_HTTPResponse',
|
||||||
|
['status', 'reason', 'data', 'getheaders', 'getheader']
|
||||||
|
)
|
||||||
|
headers = {}
|
||||||
|
def get_headers():
|
||||||
|
return headers
|
||||||
|
def get_header(name, default=None):
|
||||||
|
return headers.get(name, default)
|
||||||
|
data = "str"
|
||||||
|
|
||||||
|
http_response = HTTPResponse(
|
||||||
|
status=200,
|
||||||
|
reason='OK',
|
||||||
|
data=json.dumps(data).encode("utf-8") if six.PY3 else json.dumps(data),
|
||||||
|
getheaders=get_headers,
|
||||||
|
getheader=get_header
|
||||||
|
)
|
||||||
|
|
||||||
|
mock_response = RESTResponse(http_response)
|
||||||
|
|
||||||
|
result = self.deserialize(mock_response, response_types_mixed, True)
|
||||||
|
self.assertEqual(isinstance(result, str), True)
|
||||||
|
self.assertEqual(result, data)
|
||||||
|
|
||||||
def test_deserialize_string_boolean_map(self):
|
def test_deserialize_string_boolean_map(self):
|
||||||
"""
|
"""
|
||||||
Ensures that string boolean (additional properties)
|
Ensures that string boolean (additional properties)
|
||||||
|
@ -329,7 +329,7 @@ class PetApiTests(unittest.TestCase):
|
|||||||
http_response = HTTPResponse(
|
http_response = HTTPResponse(
|
||||||
status=200,
|
status=200,
|
||||||
reason='OK',
|
reason='OK',
|
||||||
data=json.dumps(api_respponse),
|
data=json.dumps(api_respponse).encode('utf-8'),
|
||||||
getheaders=get_headers,
|
getheaders=get_headers,
|
||||||
getheader=get_header
|
getheader=get_header
|
||||||
)
|
)
|
||||||
|
@ -28,7 +28,7 @@ import tornado.gen
|
|||||||
from petstore_api.configuration import Configuration
|
from petstore_api.configuration import Configuration
|
||||||
import petstore_api.models
|
import petstore_api.models
|
||||||
from petstore_api import rest
|
from petstore_api import rest
|
||||||
from petstore_api.exceptions import ApiValueError
|
from petstore_api.exceptions import ApiValueError, ApiException
|
||||||
|
|
||||||
|
|
||||||
class ApiClient(object):
|
class ApiClient(object):
|
||||||
@ -178,17 +178,33 @@ class ApiClient(object):
|
|||||||
# use server/host defined in path or operation instead
|
# use server/host defined in path or operation instead
|
||||||
url = _host + resource_path
|
url = _host + resource_path
|
||||||
|
|
||||||
|
try:
|
||||||
# perform request and return response
|
# perform request and return response
|
||||||
response_data = yield self.request(
|
response_data = yield self.request(
|
||||||
method, url, query_params=query_params, headers=header_params,
|
method, url, query_params=query_params, headers=header_params,
|
||||||
post_params=post_params, body=body,
|
post_params=post_params, body=body,
|
||||||
_preload_content=_preload_content,
|
_preload_content=_preload_content,
|
||||||
_request_timeout=_request_timeout)
|
_request_timeout=_request_timeout)
|
||||||
|
except ApiException as e:
|
||||||
|
e.body = e.body.decode('utf-8') if six.PY3 else e.body
|
||||||
|
raise e
|
||||||
|
|
||||||
|
content_type = response_data.getheader('content-type')
|
||||||
|
|
||||||
self.last_response = response_data
|
self.last_response = response_data
|
||||||
|
|
||||||
return_data = response_data
|
return_data = response_data
|
||||||
if _preload_content:
|
|
||||||
|
if not _preload_content:
|
||||||
|
raise tornado.gen.Return(return_data)
|
||||||
|
|
||||||
|
if six.PY3 and response_type not in ["file", "bytes"]:
|
||||||
|
match = None
|
||||||
|
if content_type is not None:
|
||||||
|
match = re.search(r"charset=([a-zA-Z\-\d]+)[\s\;]?", content_type)
|
||||||
|
encoding = match.group(1) if match else "utf-8"
|
||||||
|
response_data.data = response_data.data.decode(encoding)
|
||||||
|
|
||||||
# deserialize response data
|
# deserialize response data
|
||||||
if response_type:
|
if response_type:
|
||||||
return_data = self.deserialize(response_data, response_type)
|
return_data = self.deserialize(response_data, response_type)
|
||||||
|
@ -16,7 +16,6 @@ import logging
|
|||||||
import re
|
import re
|
||||||
|
|
||||||
# python 2 and python 3 compatibility library
|
# python 2 and python 3 compatibility library
|
||||||
import six
|
|
||||||
from six.moves.urllib.parse import urlencode
|
from six.moves.urllib.parse import urlencode
|
||||||
import tornado
|
import tornado
|
||||||
import tornado.gen
|
import tornado.gen
|
||||||
@ -36,10 +35,6 @@ class RESTResponse(io.IOBase):
|
|||||||
self.reason = resp.reason
|
self.reason = resp.reason
|
||||||
|
|
||||||
if resp.body:
|
if resp.body:
|
||||||
# In Python 3, the response body is utf-8 encoded bytes.
|
|
||||||
if six.PY3:
|
|
||||||
self.data = resp.body.decode('utf-8')
|
|
||||||
else:
|
|
||||||
self.data = resp.body
|
self.data = resp.body
|
||||||
else:
|
else:
|
||||||
self.data = None
|
self.data = None
|
||||||
|
@ -27,7 +27,7 @@ from six.moves.urllib.parse import quote
|
|||||||
from petstore_api.configuration import Configuration
|
from petstore_api.configuration import Configuration
|
||||||
import petstore_api.models
|
import petstore_api.models
|
||||||
from petstore_api import rest
|
from petstore_api import rest
|
||||||
from petstore_api.exceptions import ApiValueError
|
from petstore_api.exceptions import ApiValueError, ApiException
|
||||||
|
|
||||||
|
|
||||||
class ApiClient(object):
|
class ApiClient(object):
|
||||||
@ -176,17 +176,33 @@ class ApiClient(object):
|
|||||||
# use server/host defined in path or operation instead
|
# use server/host defined in path or operation instead
|
||||||
url = _host + resource_path
|
url = _host + resource_path
|
||||||
|
|
||||||
|
try:
|
||||||
# perform request and return response
|
# perform request and return response
|
||||||
response_data = self.request(
|
response_data = self.request(
|
||||||
method, url, query_params=query_params, headers=header_params,
|
method, url, query_params=query_params, headers=header_params,
|
||||||
post_params=post_params, body=body,
|
post_params=post_params, body=body,
|
||||||
_preload_content=_preload_content,
|
_preload_content=_preload_content,
|
||||||
_request_timeout=_request_timeout)
|
_request_timeout=_request_timeout)
|
||||||
|
except ApiException as e:
|
||||||
|
e.body = e.body.decode('utf-8') if six.PY3 else e.body
|
||||||
|
raise e
|
||||||
|
|
||||||
|
content_type = response_data.getheader('content-type')
|
||||||
|
|
||||||
self.last_response = response_data
|
self.last_response = response_data
|
||||||
|
|
||||||
return_data = response_data
|
return_data = response_data
|
||||||
if _preload_content:
|
|
||||||
|
if not _preload_content:
|
||||||
|
return return_data
|
||||||
|
|
||||||
|
if six.PY3 and response_type not in ["file", "bytes"]:
|
||||||
|
match = None
|
||||||
|
if content_type is not None:
|
||||||
|
match = re.search(r"charset=([a-zA-Z\-\d]+)[\s\;]?", content_type)
|
||||||
|
encoding = match.group(1) if match else "utf-8"
|
||||||
|
response_data.data = response_data.data.decode(encoding)
|
||||||
|
|
||||||
# deserialize response data
|
# deserialize response data
|
||||||
if response_type:
|
if response_type:
|
||||||
return_data = self.deserialize(response_data, response_type)
|
return_data = self.deserialize(response_data, response_type)
|
||||||
|
@ -217,11 +217,6 @@ class RESTClientObject(object):
|
|||||||
if _preload_content:
|
if _preload_content:
|
||||||
r = RESTResponse(r)
|
r = RESTResponse(r)
|
||||||
|
|
||||||
# In the python 3, the response.data is bytes.
|
|
||||||
# we need to decode it to string.
|
|
||||||
if six.PY3:
|
|
||||||
r.data = r.data.decode('utf8')
|
|
||||||
|
|
||||||
# log response body
|
# log response body
|
||||||
logger.debug("response body: %s", r.data)
|
logger.debug("response body: %s", r.data)
|
||||||
|
|
||||||
|
@ -44,7 +44,7 @@ class TestFormatTest(unittest.TestCase):
|
|||||||
double = 67.8,
|
double = 67.8,
|
||||||
string = 'a',
|
string = 'a',
|
||||||
byte = 'YQ==',
|
byte = 'YQ==',
|
||||||
binary = bytes(b'blah'),
|
binary = 'bytes',
|
||||||
date = datetime.datetime.strptime('1975-12-30', '%Y-%m-%d').date(),
|
date = datetime.datetime.strptime('1975-12-30', '%Y-%m-%d').date(),
|
||||||
date_time = datetime.datetime.strptime('2013-10-20 19:20:30.00', '%Y-%m-%d %H:%M:%S.%f'),
|
date_time = datetime.datetime.strptime('2013-10-20 19:20:30.00', '%Y-%m-%d %H:%M:%S.%f'),
|
||||||
uuid = '72f98069-206d-4f12-9f12-3d1e525a8e84',
|
uuid = '72f98069-206d-4f12-9f12-3d1e525a8e84',
|
||||||
|
@ -10,6 +10,7 @@ $ nosetests -v
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
import six
|
||||||
import sys
|
import sys
|
||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
|
@ -15,6 +15,7 @@ import atexit
|
|||||||
import mimetypes
|
import mimetypes
|
||||||
from multiprocessing.pool import ThreadPool
|
from multiprocessing.pool import ThreadPool
|
||||||
import os
|
import os
|
||||||
|
import re
|
||||||
|
|
||||||
# python 2 and python 3 compatibility library
|
# python 2 and python 3 compatibility library
|
||||||
import six
|
import six
|
||||||
@ -22,7 +23,7 @@ from six.moves.urllib.parse import quote
|
|||||||
|
|
||||||
from petstore_api import rest
|
from petstore_api import rest
|
||||||
from petstore_api.configuration import Configuration
|
from petstore_api.configuration import Configuration
|
||||||
from petstore_api.exceptions import ApiValueError
|
from petstore_api.exceptions import ApiValueError, ApiException
|
||||||
from petstore_api.model_utils import (
|
from petstore_api.model_utils import (
|
||||||
ModelNormal,
|
ModelNormal,
|
||||||
ModelSimple,
|
ModelSimple,
|
||||||
@ -178,17 +179,34 @@ class ApiClient(object):
|
|||||||
# use server/host defined in path or operation instead
|
# use server/host defined in path or operation instead
|
||||||
url = _host + resource_path
|
url = _host + resource_path
|
||||||
|
|
||||||
|
try:
|
||||||
# perform request and return response
|
# perform request and return response
|
||||||
response_data = self.request(
|
response_data = self.request(
|
||||||
method, url, query_params=query_params, headers=header_params,
|
method, url, query_params=query_params, headers=header_params,
|
||||||
post_params=post_params, body=body,
|
post_params=post_params, body=body,
|
||||||
_preload_content=_preload_content,
|
_preload_content=_preload_content,
|
||||||
_request_timeout=_request_timeout)
|
_request_timeout=_request_timeout)
|
||||||
|
except ApiException as e:
|
||||||
|
e.body = e.body.decode('utf-8') if six.PY3 else e.body
|
||||||
|
raise e
|
||||||
|
|
||||||
|
content_type = response_data.getheader('content-type')
|
||||||
|
|
||||||
self.last_response = response_data
|
self.last_response = response_data
|
||||||
|
|
||||||
return_data = response_data
|
return_data = response_data
|
||||||
if _preload_content:
|
|
||||||
|
if not _preload_content:
|
||||||
|
return (return_data)
|
||||||
|
return return_data
|
||||||
|
|
||||||
|
if six.PY3 and response_type not in ["file", "bytes"]:
|
||||||
|
match = None
|
||||||
|
if content_type is not None:
|
||||||
|
match = re.search(r"charset=([a-zA-Z\-\d]+)[\s\;]?", content_type)
|
||||||
|
encoding = match.group(1) if match else "utf-8"
|
||||||
|
response_data.data = response_data.data.decode(encoding)
|
||||||
|
|
||||||
# deserialize response data
|
# deserialize response data
|
||||||
if response_type:
|
if response_type:
|
||||||
return_data = self.deserialize(
|
return_data = self.deserialize(
|
||||||
|
@ -217,11 +217,6 @@ class RESTClientObject(object):
|
|||||||
if _preload_content:
|
if _preload_content:
|
||||||
r = RESTResponse(r)
|
r = RESTResponse(r)
|
||||||
|
|
||||||
# In the python 3, the response.data is bytes.
|
|
||||||
# we need to decode it to string.
|
|
||||||
if six.PY3:
|
|
||||||
r.data = r.data.decode('utf8')
|
|
||||||
|
|
||||||
# log response body
|
# log response body
|
||||||
logger.debug("response body: %s", r.data)
|
logger.debug("response body: %s", r.data)
|
||||||
|
|
||||||
|
@ -27,7 +27,7 @@ from six.moves.urllib.parse import quote
|
|||||||
from petstore_api.configuration import Configuration
|
from petstore_api.configuration import Configuration
|
||||||
import petstore_api.models
|
import petstore_api.models
|
||||||
from petstore_api import rest
|
from petstore_api import rest
|
||||||
from petstore_api.exceptions import ApiValueError
|
from petstore_api.exceptions import ApiValueError, ApiException
|
||||||
|
|
||||||
|
|
||||||
class ApiClient(object):
|
class ApiClient(object):
|
||||||
@ -176,17 +176,33 @@ class ApiClient(object):
|
|||||||
# use server/host defined in path or operation instead
|
# use server/host defined in path or operation instead
|
||||||
url = _host + resource_path
|
url = _host + resource_path
|
||||||
|
|
||||||
|
try:
|
||||||
# perform request and return response
|
# perform request and return response
|
||||||
response_data = self.request(
|
response_data = self.request(
|
||||||
method, url, query_params=query_params, headers=header_params,
|
method, url, query_params=query_params, headers=header_params,
|
||||||
post_params=post_params, body=body,
|
post_params=post_params, body=body,
|
||||||
_preload_content=_preload_content,
|
_preload_content=_preload_content,
|
||||||
_request_timeout=_request_timeout)
|
_request_timeout=_request_timeout)
|
||||||
|
except ApiException as e:
|
||||||
|
e.body = e.body.decode('utf-8') if six.PY3 else e.body
|
||||||
|
raise e
|
||||||
|
|
||||||
|
content_type = response_data.getheader('content-type')
|
||||||
|
|
||||||
self.last_response = response_data
|
self.last_response = response_data
|
||||||
|
|
||||||
return_data = response_data
|
return_data = response_data
|
||||||
if _preload_content:
|
|
||||||
|
if not _preload_content:
|
||||||
|
return return_data
|
||||||
|
|
||||||
|
if six.PY3 and response_type not in ["file", "bytes"]:
|
||||||
|
match = None
|
||||||
|
if content_type is not None:
|
||||||
|
match = re.search(r"charset=([a-zA-Z\-\d]+)[\s\;]?", content_type)
|
||||||
|
encoding = match.group(1) if match else "utf-8"
|
||||||
|
response_data.data = response_data.data.decode(encoding)
|
||||||
|
|
||||||
# deserialize response data
|
# deserialize response data
|
||||||
if response_type:
|
if response_type:
|
||||||
return_data = self.deserialize(response_data, response_type)
|
return_data = self.deserialize(response_data, response_type)
|
||||||
|
@ -217,11 +217,6 @@ class RESTClientObject(object):
|
|||||||
if _preload_content:
|
if _preload_content:
|
||||||
r = RESTResponse(r)
|
r = RESTResponse(r)
|
||||||
|
|
||||||
# In the python 3, the response.data is bytes.
|
|
||||||
# we need to decode it to string.
|
|
||||||
if six.PY3:
|
|
||||||
r.data = r.data.decode('utf8')
|
|
||||||
|
|
||||||
# log response body
|
# log response body
|
||||||
logger.debug("response body: %s", r.data)
|
logger.debug("response body: %s", r.data)
|
||||||
|
|
||||||
|
@ -30,8 +30,8 @@ class EnumClass implements ModelInterface
|
|||||||
private const MODEL_SCHEMA = <<<'SCHEMA'
|
private const MODEL_SCHEMA = <<<'SCHEMA'
|
||||||
{
|
{
|
||||||
"type" : "string",
|
"type" : "string",
|
||||||
"default" : "-efg",
|
"enum" : [ "_abc", "-efg", "(xyz)" ],
|
||||||
"enum" : [ "_abc", "-efg", "(xyz)" ]
|
"default" : "-efg"
|
||||||
}
|
}
|
||||||
SCHEMA;
|
SCHEMA;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user