diff --git a/modules/swagger-codegen/src/main/resources/python/asyncio/rest.mustache b/modules/swagger-codegen/src/main/resources/python/asyncio/rest.mustache
index 986902f56d0..39003abfbfd 100644
--- a/modules/swagger-codegen/src/main/resources/python/asyncio/rest.mustache
+++ b/modules/swagger-codegen/src/main/resources/python/asyncio/rest.mustache
@@ -47,8 +47,7 @@ class RESTClientObject(object):
# if not set certificate file, use Mozilla's root certificates.
ca_certs = certifi.where()
- ssl_context = ssl.SSLContext()
- ssl_context.load_verify_locations(cafile=ca_certs)
+ ssl_context = ssl.create_default_context(cafile=ca_certs)
if configuration.cert_file:
ssl_context.load_cert_chain(
configuration.cert_file, keyfile=configuration.key_file
@@ -113,21 +112,34 @@ class RESTClientObject(object):
"timeout": timeout,
"headers": headers
}
+
+ if query_params:
+ args["url"] += '?' + urlencode(query_params)
+
# For `POST`, `PUT`, `PATCH`, `OPTIONS`, `DELETE`
if method in ['POST', 'PUT', 'PATCH', 'OPTIONS', 'DELETE']:
- if query_params:
- url += '?' + urlencode(query_params)
if re.search('json', headers['Content-Type'], re.IGNORECASE):
if body is not None:
body = json.dumps(body)
args["data"] = body
elif headers['Content-Type'] == 'application/x-www-form-urlencoded': # noqa: E501
- data = aiohttp.FormData()
- for k, v in post_params.items():
- data.add_field(k, v)
- args["data"] = data
+ args["data"] = aiohttp.FormData(post_params)
elif headers['Content-Type'] == 'multipart/form-data':
- args["data"] = post_params
+ # must del headers['Content-Type'], or the correct
+ # Content-Type which generated by aiohttp
+ del headers['Content-Type']
+ data = aiohttp.FormData()
+ for param in post_params:
+ k, v = param
+ if isinstance(v, tuple) and len(v) == 3:
+ data.add_field(k,
+ value=v[1],
+ filename=v[0],
+ content_type=v[2])
+ else:
+ data.add_field(k, v)
+ args["data"] = data
+
# Pass a `bytes` parameter directly in the body to support
# other content types than Json when `body` argument is provided
# in serialized form
@@ -139,8 +151,6 @@ class RESTClientObject(object):
arguments. Please check that your arguments match
declared content type."""
raise ApiException(status=0, reason=msg)
- else:
- args["data"] = query_params
async with self.pool_manager.request(**args) as r:
data = await r.text()
diff --git a/modules/swagger-codegen/src/main/resources/python/test-requirements.mustache b/modules/swagger-codegen/src/main/resources/python/test-requirements.mustache
index 2702246c0e6..31f8d94d99f 100644
--- a/modules/swagger-codegen/src/main/resources/python/test-requirements.mustache
+++ b/modules/swagger-codegen/src/main/resources/python/test-requirements.mustache
@@ -1,5 +1,11 @@
+{{^asyncio}}
coverage>=4.0.3
nose>=1.3.7
+{{/asyncio}}
+{{#asyncio}}
+pytest>=3.3.1
+pytest-cov>=2.5.1
+{{/asyncio}}
pluggy>=0.3.1
py>=1.4.31
randomize>=0.13
diff --git a/modules/swagger-codegen/src/main/resources/python/tox.mustache b/modules/swagger-codegen/src/main/resources/python/tox.mustache
index 1cf0829dc93..63d12fdeaea 100644
--- a/modules/swagger-codegen/src/main/resources/python/tox.mustache
+++ b/modules/swagger-codegen/src/main/resources/python/tox.mustache
@@ -1,10 +1,20 @@
[tox]
+{{^asyncio}}
envlist = py27, py3
+{{/asyncio}}
+{{#asyncio}}
+envlist = py3
+{{/asyncio}}
[testenv]
deps=-r{toxinidir}/requirements.txt
-r{toxinidir}/test-requirements.txt
-
+
commands=
+{{^asyncio}}
nosetests \
- []
\ No newline at end of file
+ []
+{{/asyncio}}
+{{#asyncio}}
+ pytest -v --cov petstore_api
+{{/asyncio}}
diff --git a/pom.xml b/pom.xml
index f9d861bbf9d..ee1488a3b67 100644
--- a/pom.xml
+++ b/pom.xml
@@ -846,6 +846,7 @@
samples/client/petstore/javascript
samples/client/petstore/python
samples/client/petstore/python-tornado
+ samples/client/petstore/python-asyncio
samples/client/petstore/typescript-fetch/builds/default
samples/client/petstore/typescript-fetch/builds/es6-target
samples/client/petstore/typescript-fetch/builds/with-npm-version
diff --git a/samples/client/petstore/python-asyncio/Makefile b/samples/client/petstore/python-asyncio/Makefile
new file mode 100644
index 00000000000..8d0afd4974d
--- /dev/null
+++ b/samples/client/petstore/python-asyncio/Makefile
@@ -0,0 +1,18 @@
+ #!/bin/bash
+
+REQUIREMENTS_FILE=dev-requirements.txt
+REQUIREMENTS_OUT=dev-requirements.txt.log
+SETUP_OUT=*.egg-info
+VENV=.venv
+
+clean:
+ rm -rf $(REQUIREMENTS_OUT)
+ rm -rf $(SETUP_OUT)
+ rm -rf $(VENV)
+ rm -rf .tox
+ rm -rf .coverage
+ find . -name "*.py[oc]" -delete
+ find . -name "__pycache__" -delete
+
+test-all: clean
+ bash ./test_python3.sh
diff --git a/samples/client/petstore/python-asyncio/dev-requirements.txt b/samples/client/petstore/python-asyncio/dev-requirements.txt
new file mode 100644
index 00000000000..49182426e20
--- /dev/null
+++ b/samples/client/petstore/python-asyncio/dev-requirements.txt
@@ -0,0 +1,4 @@
+tox
+coverage
+randomize
+flake8
diff --git a/samples/client/petstore/python-asyncio/docs/FakeApi.md b/samples/client/petstore/python-asyncio/docs/FakeApi.md
index 1da84500bfe..b910ba2b464 100644
--- a/samples/client/petstore/python-asyncio/docs/FakeApi.md
+++ b/samples/client/petstore/python-asyncio/docs/FakeApi.md
@@ -273,10 +273,10 @@ configuration.password = 'YOUR_PASSWORD'
# create an instance of the API class
api_instance = petstore_api.FakeApi(petstore_api.ApiClient(configuration))
-number = 8.14 # float | None
+number = 3.4 # float | None
double = 1.2 # float | None
pattern_without_delimiter = 'pattern_without_delimiter_example' # str | None
-byte = 'B' # str | None
+byte = 'byte_example' # str | None
integer = 56 # int | None (optional)
int32 = 56 # int | None (optional)
int64 = 789 # int | None (optional)
diff --git a/samples/client/petstore/python-asyncio/git_push.sh b/samples/client/petstore/python-asyncio/git_push.sh
index ed374619b13..ae01b182ae9 100644
--- a/samples/client/petstore/python-asyncio/git_push.sh
+++ b/samples/client/petstore/python-asyncio/git_push.sh
@@ -36,7 +36,7 @@ git_remote=`git remote`
if [ "$git_remote" = "" ]; then # git remote not defined
if [ "$GIT_TOKEN" = "" ]; then
- echo "[INFO] \$GIT_TOKEN (environment variable) is not set. Using the git crediential in your environment."
+ echo "[INFO] \$GIT_TOKEN (environment variable) is not set. Using the git credential in your environment."
git remote add origin https://github.com/${git_user_id}/${git_repo_id}.git
else
git remote add origin https://${git_user_id}:${GIT_TOKEN}@github.com/${git_user_id}/${git_repo_id}.git
diff --git a/samples/client/petstore/python-asyncio/petstore_api/rest.py b/samples/client/petstore/python-asyncio/petstore_api/rest.py
index 497882aaa9f..69d87b282c6 100644
--- a/samples/client/petstore/python-asyncio/petstore_api/rest.py
+++ b/samples/client/petstore/python-asyncio/petstore_api/rest.py
@@ -56,8 +56,7 @@ class RESTClientObject(object):
# if not set certificate file, use Mozilla's root certificates.
ca_certs = certifi.where()
- ssl_context = ssl.SSLContext()
- ssl_context.load_verify_locations(cafile=ca_certs)
+ ssl_context = ssl.create_default_context(cafile=ca_certs)
if configuration.cert_file:
ssl_context.load_cert_chain(
configuration.cert_file, keyfile=configuration.key_file
@@ -122,21 +121,34 @@ class RESTClientObject(object):
"timeout": timeout,
"headers": headers
}
+
+ if query_params:
+ args["url"] += '?' + urlencode(query_params)
+
# For `POST`, `PUT`, `PATCH`, `OPTIONS`, `DELETE`
if method in ['POST', 'PUT', 'PATCH', 'OPTIONS', 'DELETE']:
- if query_params:
- url += '?' + urlencode(query_params)
if re.search('json', headers['Content-Type'], re.IGNORECASE):
if body is not None:
body = json.dumps(body)
args["data"] = body
elif headers['Content-Type'] == 'application/x-www-form-urlencoded': # noqa: E501
- data = aiohttp.FormData()
- for k, v in post_params.items():
- data.add_field(k, v)
- args["data"] = data
+ args["data"] = aiohttp.FormData(post_params)
elif headers['Content-Type'] == 'multipart/form-data':
- args["data"] = post_params
+ # must del headers['Content-Type'], or the correct
+ # Content-Type which generated by aiohttp
+ del headers['Content-Type']
+ data = aiohttp.FormData()
+ for param in post_params:
+ k, v = param
+ if isinstance(v, tuple) and len(v) == 3:
+ data.add_field(k,
+ value=v[1],
+ filename=v[0],
+ content_type=v[2])
+ else:
+ data.add_field(k, v)
+ args["data"] = data
+
# Pass a `bytes` parameter directly in the body to support
# other content types than Json when `body` argument is provided
# in serialized form
@@ -148,8 +160,6 @@ class RESTClientObject(object):
arguments. Please check that your arguments match
declared content type."""
raise ApiException(status=0, reason=msg)
- else:
- args["data"] = query_params
async with self.pool_manager.request(**args) as r:
data = await r.text()
diff --git a/samples/client/petstore/python-asyncio/pom.xml b/samples/client/petstore/python-asyncio/pom.xml
new file mode 100644
index 00000000000..b370bd02469
--- /dev/null
+++ b/samples/client/petstore/python-asyncio/pom.xml
@@ -0,0 +1,46 @@
+
+ 4.0.0
+ io.swagger
+ PythonAsyncioClientTests
+ pom
+ 1.0-SNAPSHOT
+ Python Asyncio Petstore Client
+
+
+
+ maven-dependency-plugin
+
+
+ package
+
+ copy-dependencies
+
+
+ ${project.build.directory}
+
+
+
+
+
+ org.codehaus.mojo
+ exec-maven-plugin
+ 1.2.1
+
+
+ pytest-test
+ integration-test
+
+ exec
+
+
+ make
+
+ test-all
+
+
+
+
+
+
+
+
diff --git a/samples/client/petstore/python-asyncio/test-requirements.txt b/samples/client/petstore/python-asyncio/test-requirements.txt
index 2702246c0e6..1c20b09b865 100644
--- a/samples/client/petstore/python-asyncio/test-requirements.txt
+++ b/samples/client/petstore/python-asyncio/test-requirements.txt
@@ -1,5 +1,5 @@
-coverage>=4.0.3
-nose>=1.3.7
+pytest>=3.3.1
+pytest-cov>=2.5.1
pluggy>=0.3.1
py>=1.4.31
randomize>=0.13
diff --git a/samples/client/petstore/python-asyncio/test_python3.sh b/samples/client/petstore/python-asyncio/test_python3.sh
new file mode 100755
index 00000000000..01abf0b35b1
--- /dev/null
+++ b/samples/client/petstore/python-asyncio/test_python3.sh
@@ -0,0 +1,32 @@
+#!/bin/bash
+
+REQUIREMENTS_FILE=dev-requirements.txt
+REQUIREMENTS_OUT=dev-requirements.txt.log
+SETUP_OUT=*.egg-info
+VENV=.venv
+DEACTIVE=false
+
+export LC_ALL=en_US.UTF-8
+export LANG=en_US.UTF-8
+
+### set virtualenv
+if [ -z "$VIRTUAL_ENV" ]; then
+ virtualenv $VENV --no-site-packages --always-copy --python python3
+ source $VENV/bin/activate
+ DEACTIVE=true
+fi
+
+### install dependencies
+pip install -r $REQUIREMENTS_FILE | tee -a $REQUIREMENTS_OUT
+python setup.py develop
+
+### run tests
+tox || exit 1
+
+### static analysis of code
+flake8 --show-source petstore_api/
+
+### deactivate virtualenv
+#if [ $DEACTIVE == true ]; then
+# deactivate
+#fi
diff --git a/samples/client/petstore/python-asyncio/testfiles/foo.png b/samples/client/petstore/python-asyncio/testfiles/foo.png
new file mode 100644
index 00000000000..a9b12cf5927
Binary files /dev/null and b/samples/client/petstore/python-asyncio/testfiles/foo.png differ
diff --git a/samples/client/petstore/python-asyncio/tests/__init__.py b/samples/client/petstore/python-asyncio/tests/__init__.py
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/samples/client/petstore/python-asyncio/tests/test_pet_api.py b/samples/client/petstore/python-asyncio/tests/test_pet_api.py
new file mode 100644
index 00000000000..ad143e246fa
--- /dev/null
+++ b/samples/client/petstore/python-asyncio/tests/test_pet_api.py
@@ -0,0 +1,208 @@
+# coding: utf-8
+
+# flake8: noqa
+
+"""
+Run the tests.
+$ docker pull swaggerapi/petstore
+$ docker run -d -e SWAGGER_HOST=http://petstore.swagger.io -e SWAGGER_BASE_PATH=/v2 -p 80:8080 swaggerapi/petstore
+$ pytest -vv
+"""
+
+import os
+import unittest
+import asyncio
+import pytest
+
+import petstore_api
+from petstore_api import Configuration
+from petstore_api.rest import ApiException
+
+from .util import id_gen
+
+import json
+
+import urllib3
+
+HOST = 'http://localhost:80/v2'
+
+
+def async_test(f):
+ def wrapper(*args, **kwargs):
+ coro = asyncio.coroutine(f)
+ future = coro(*args, **kwargs)
+ loop = asyncio.get_event_loop()
+ loop.run_until_complete(future)
+ return wrapper
+
+
+class TestPetApiTests(unittest.TestCase):
+
+ def setUp(self):
+ config = Configuration()
+ config.host = HOST
+
+ self.api_client = petstore_api.ApiClient(config)
+ self.pet_api = petstore_api.PetApi(self.api_client)
+ self.setUpModels()
+ self.setUpFiles()
+
+ def setUpModels(self):
+ self.category = petstore_api.Category()
+ self.category.id = id_gen()
+ self.category.name = "dog"
+ self.tag = petstore_api.Tag()
+ self.tag.id = id_gen()
+ self.tag.name = "swagger-codegen-python-pet-tag"
+ self.pet = petstore_api.Pet(name="hello kity", photo_urls=["http://foo.bar.com/1", "http://foo.bar.com/2"])
+ self.pet.id = id_gen()
+ self.pet.status = "sold"
+ self.pet.category = self.category
+ self.pet.tags = [self.tag]
+
+ def setUpFiles(self):
+ self.test_file_dir = os.path.join(os.path.dirname(__file__), "..", "testfiles")
+ self.test_file_dir = os.path.realpath(self.test_file_dir)
+ self.foo = os.path.join(self.test_file_dir, "foo.png")
+
+ def test_separate_default_client_instances(self):
+ pet_api = petstore_api.PetApi()
+ pet_api2 = petstore_api.PetApi()
+ self.assertNotEqual(pet_api.api_client, pet_api2.api_client)
+
+ pet_api.api_client.user_agent = 'api client 3'
+ pet_api2.api_client.user_agent = 'api client 4'
+
+ self.assertNotEqual(pet_api.api_client.user_agent, pet_api2.api_client.user_agent)
+
+ def test_separate_default_config_instances(self):
+ pet_api = petstore_api.PetApi()
+ pet_api2 = petstore_api.PetApi()
+ self.assertNotEqual(pet_api.api_client.configuration, pet_api2.api_client.configuration)
+
+ pet_api.api_client.configuration.host = 'somehost'
+ pet_api2.api_client.configuration.host = 'someotherhost'
+ self.assertNotEqual(pet_api.api_client.configuration.host, pet_api2.api_client.configuration.host)
+
+ @async_test
+ async def test_async_with_result(self):
+ await self.pet_api.add_pet(body=self.pet)
+
+ calls = [self.pet_api.get_pet_by_id(self.pet.id),
+ self.pet_api.get_pet_by_id(self.pet.id)]
+
+ responses, _ = await asyncio.wait(calls)
+ for response in responses:
+ self.assertEqual(response.result().id, self.pet.id)
+ self.assertEqual(len(responses), 2)
+
+ @async_test
+ async def test_exception(self):
+ await self.pet_api.add_pet(body=self.pet)
+
+ try:
+ await self.pet_api.get_pet_by_id("-9999999999999")
+ except ApiException as e:
+ exception = e
+
+ self.assertIsInstance(exception, ApiException)
+ self.assertEqual(exception.status, 404)
+
+ @async_test
+ async def test_add_pet_and_get_pet_by_id(self):
+ await self.pet_api.add_pet(body=self.pet)
+
+ fetched = await self.pet_api.get_pet_by_id(pet_id=self.pet.id)
+ self.assertIsNotNone(fetched)
+ self.assertEqual(self.pet.id, fetched.id)
+ self.assertIsNotNone(fetched.category)
+ self.assertEqual(self.pet.category.name, fetched.category.name)
+
+ @async_test
+ async def test_add_pet_and_get_pet_by_id_with_http_info(self):
+ await self.pet_api.add_pet(body=self.pet)
+
+ fetched = await self.pet_api.get_pet_by_id_with_http_info(pet_id=self.pet.id)
+ self.assertIsNotNone(fetched)
+ self.assertEqual(self.pet.id, fetched[0].id)
+ self.assertIsNotNone(fetched[0].category)
+ self.assertEqual(self.pet.category.name, fetched[0].category.name)
+
+ @async_test
+ async def test_update_pet(self):
+ self.pet.name = "hello kity with updated"
+ await self.pet_api.update_pet(body=self.pet)
+
+ fetched = await self.pet_api.get_pet_by_id(pet_id=self.pet.id)
+ self.assertIsNotNone(fetched)
+ self.assertEqual(self.pet.id, fetched.id)
+ self.assertEqual(self.pet.name, fetched.name)
+ self.assertIsNotNone(fetched.category)
+ self.assertEqual(fetched.category.name, self.pet.category.name)
+
+ @async_test
+ async def test_find_pets_by_status(self):
+ await self.pet_api.add_pet(body=self.pet)
+ pets = await self.pet_api.find_pets_by_status(status=[self.pet.status])
+ self.assertIn(
+ self.pet.id,
+ list(map(lambda x: getattr(x, 'id'), pets))
+ )
+
+ @async_test
+ async def test_find_pets_by_tags(self):
+ await self.pet_api.add_pet(body=self.pet)
+ pets = await self.pet_api.find_pets_by_tags(tags=[self.tag.name])
+ self.assertIn(
+ self.pet.id,
+ list(map(lambda x: getattr(x, 'id'), pets))
+ )
+
+ @async_test
+ async def test_update_pet_with_form(self):
+ await self.pet_api.add_pet(body=self.pet)
+
+ name = "hello kity with form updated"
+ status = "pending"
+ await self.pet_api.update_pet_with_form(pet_id=self.pet.id, name=name, status=status)
+
+ fetched = await self.pet_api.get_pet_by_id(pet_id=self.pet.id)
+ self.assertEqual(self.pet.id, fetched.id)
+ self.assertEqual(name, fetched.name)
+ self.assertEqual(status, fetched.status)
+
+ @async_test
+ async def test_upload_file(self):
+ # upload file with form parameter
+ try:
+ additional_metadata = "special"
+ await self.pet_api.upload_file(
+ pet_id=self.pet.id,
+ additional_metadata=additional_metadata,
+ file=self.foo
+ )
+ except ApiException as e:
+ self.fail("upload_file() raised {0} unexpectedly".format(type(e)))
+
+ # upload only file
+ try:
+ await self.pet_api.upload_file(pet_id=self.pet.id, file=self.foo)
+ except ApiException as e:
+ self.fail("upload_file() raised {0} unexpectedly".format(type(e)))
+
+ @async_test
+ async def test_delete_pet(self):
+ await self.pet_api.add_pet(body=self.pet)
+ await self.pet_api.delete_pet(pet_id=self.pet.id, api_key="special-key")
+
+ try:
+ await self.pet_api.get_pet_by_id(pet_id=self.pet.id)
+ raise Exception("expected an error")
+ except ApiException as e:
+ self.assertEqual(404, e.status)
+
+
+if __name__ == '__main__':
+ import logging
+ logging.basicConfig(level=logging.DEBUG)
+ unittest.main()
diff --git a/samples/client/petstore/python-asyncio/tests/util.py b/samples/client/petstore/python-asyncio/tests/util.py
new file mode 100644
index 00000000000..39fba1514b3
--- /dev/null
+++ b/samples/client/petstore/python-asyncio/tests/util.py
@@ -0,0 +1,11 @@
+# flake8: noqa
+
+import random
+
+
+def id_gen(bits=32):
+ """ Returns a n-bit randomly generated int """
+ return int(random.getrandbits(bits))
+
+
+
diff --git a/samples/client/petstore/python-asyncio/tox.ini b/samples/client/petstore/python-asyncio/tox.ini
index 1cf0829dc93..65f5351ddcc 100644
--- a/samples/client/petstore/python-asyncio/tox.ini
+++ b/samples/client/petstore/python-asyncio/tox.ini
@@ -1,10 +1,9 @@
[tox]
-envlist = py27, py3
+envlist = py3
[testenv]
deps=-r{toxinidir}/requirements.txt
-r{toxinidir}/test-requirements.txt
-
+
commands=
- nosetests \
- []
\ No newline at end of file
+ pytest -v --cov petstore_api
diff --git a/samples/client/petstore/python-tornado/tox.ini b/samples/client/petstore/python-tornado/tox.ini
index 1cf0829dc93..3d0be613cfc 100644
--- a/samples/client/petstore/python-tornado/tox.ini
+++ b/samples/client/petstore/python-tornado/tox.ini
@@ -4,7 +4,7 @@ envlist = py27, py3
[testenv]
deps=-r{toxinidir}/requirements.txt
-r{toxinidir}/test-requirements.txt
-
+
commands=
nosetests \
- []
\ No newline at end of file
+ []
diff --git a/samples/client/petstore/python/docs/FakeApi.md b/samples/client/petstore/python/docs/FakeApi.md
index 1da84500bfe..b910ba2b464 100644
--- a/samples/client/petstore/python/docs/FakeApi.md
+++ b/samples/client/petstore/python/docs/FakeApi.md
@@ -273,10 +273,10 @@ configuration.password = 'YOUR_PASSWORD'
# create an instance of the API class
api_instance = petstore_api.FakeApi(petstore_api.ApiClient(configuration))
-number = 8.14 # float | None
+number = 3.4 # float | None
double = 1.2 # float | None
pattern_without_delimiter = 'pattern_without_delimiter_example' # str | None
-byte = 'B' # str | None
+byte = 'byte_example' # str | None
integer = 56 # int | None (optional)
int32 = 56 # int | None (optional)
int64 = 789 # int | None (optional)
diff --git a/samples/client/petstore/python/tox.ini b/samples/client/petstore/python/tox.ini
index 1cf0829dc93..3d0be613cfc 100644
--- a/samples/client/petstore/python/tox.ini
+++ b/samples/client/petstore/python/tox.ini
@@ -4,7 +4,7 @@ envlist = py27, py3
[testenv]
deps=-r{toxinidir}/requirements.txt
-r{toxinidir}/test-requirements.txt
-
+
commands=
nosetests \
- []
\ No newline at end of file
+ []