[python-client] Modify python templates to resolve linting errors (#6839)

The linting results for the generated samples are as follows
where the first number is the BEFORE and the second is AFTER.

pyclient            7714 vs. 120
pyclient3           7717 vs. 120
pyclient3-asyncio   7584 vs. 120
pyclient-tornado    7633 vs. 120
pyclient3-tornado   7633 vs. 120

For the complete details please see the following gist.
https://gist.github.com/kenjones-cisco/2eb69a7e8db75e9fd53789f01570d9f2

Enforces linting for python clients by running flake8 for the generated
python client.
This commit is contained in:
Kenny Jones
2017-11-01 12:47:14 -04:00
committed by wing328
parent eba4affbb4
commit 74f70a1924
339 changed files with 9992 additions and 11581 deletions

View File

@@ -67,6 +67,7 @@ public class PythonClientCodegen extends DefaultCodegen implements CodegenConfig
languageSpecificPrimitives.add("int");
languageSpecificPrimitives.add("float");
languageSpecificPrimitives.add("list");
languageSpecificPrimitives.add("dict");
languageSpecificPrimitives.add("bool");
languageSpecificPrimitives.add("str");
languageSpecificPrimitives.add("datetime");
@@ -189,21 +190,16 @@ public class PythonClientCodegen extends DefaultCodegen implements CodegenConfig
setPackageUrl((String) additionalProperties.get(PACKAGE_URL));
}
String swaggerFolder = packageName;
modelPackage = swaggerFolder + File.separatorChar + "models";
apiPackage = swaggerFolder + File.separatorChar + "apis";
supportingFiles.add(new SupportingFile("README.mustache", "", "README.md"));
supportingFiles.add(new SupportingFile("tox.mustache", "", "tox.ini"));
supportingFiles.add(new SupportingFile("test-requirements.mustache", "", "test-requirements.txt"));
supportingFiles.add(new SupportingFile("requirements.mustache", "", "requirements.txt"));
supportingFiles.add(new SupportingFile("configuration.mustache", swaggerFolder, "configuration.py"));
supportingFiles.add(new SupportingFile("__init__package.mustache", swaggerFolder, "__init__.py"));
supportingFiles.add(new SupportingFile("__init__model.mustache", modelPackage, "__init__.py"));
supportingFiles.add(new SupportingFile("__init__api.mustache", apiPackage, "__init__.py"));
supportingFiles.add(new SupportingFile("configuration.mustache", packageName, "configuration.py"));
supportingFiles.add(new SupportingFile("__init__package.mustache", packageName, "__init__.py"));
supportingFiles.add(new SupportingFile("__init__model.mustache", packageName + File.separatorChar + modelPackage, "__init__.py"));
supportingFiles.add(new SupportingFile("__init__api.mustache", packageName + File.separatorChar + apiPackage, "__init__.py"));
if(Boolean.FALSE.equals(excludeTests)) {
supportingFiles.add(new SupportingFile("__init__test.mustache", testFolder, "__init__.py"));
@@ -212,23 +208,42 @@ public class PythonClientCodegen extends DefaultCodegen implements CodegenConfig
supportingFiles.add(new SupportingFile("gitignore.mustache", "", ".gitignore"));
supportingFiles.add(new SupportingFile("travis.mustache", "", ".travis.yml"));
supportingFiles.add(new SupportingFile("setup.mustache", "", "setup.py"));
supportingFiles.add(new SupportingFile("api_client.mustache", swaggerFolder, "api_client.py"));
supportingFiles.add(new SupportingFile("api_client.mustache", packageName, "api_client.py"));
if ("asyncio".equals(getLibrary())) {
supportingFiles.add(new SupportingFile("asyncio/rest.mustache", swaggerFolder, "rest.py"));
supportingFiles.add(new SupportingFile("asyncio/rest.mustache", packageName, "rest.py"));
additionalProperties.put("asyncio", "true");
} else if ("tornado".equals(getLibrary())) {
supportingFiles.add(new SupportingFile("tornado/rest.mustache", swaggerFolder, "rest.py"));
supportingFiles.add(new SupportingFile("tornado/rest.mustache", packageName, "rest.py"));
additionalProperties.put("tornado", "true");
} else {
supportingFiles.add(new SupportingFile("rest.mustache", swaggerFolder, "rest.py"));
supportingFiles.add(new SupportingFile("rest.mustache", packageName, "rest.py"));
}
modelPackage = packageName + "." + modelPackage;
apiPackage = packageName + "." + apiPackage;
}
private static String dropDots(String str) {
return str.replaceAll("\\.", "_");
}
@Override
public String toModelImport(String name) {
String modelImport;
if (StringUtils.startsWithAny(name,"import", "from")) {
modelImport = name;
} else {
modelImport = "from ";
if (!"".equals(modelPackage())) {
modelImport += modelPackage() + ".";
}
modelImport += toModelFilename(name)+ " import " + name;
}
return modelImport;
}
@Override
public Map<String, Object> postProcessModels(Map<String, Object> objs) {
// process enum in models

View File

@@ -6,7 +6,7 @@ from datetime import date, datetime # noqa: F401
from typing import List, Dict # noqa: F401
from {{modelPackage}}.base_model_ import Model
{{#imports}}{{import}} # noqa: E501
{{#imports}}{{import}} # noqa: F401,E501
{{/imports}}
from {{packageName}} import util
@@ -94,7 +94,7 @@ class {{classname}}(Model):
if not set({{{name}}}).issubset(set(allowed_values)):
raise ValueError(
"Invalid values for `{{{name}}}` [{0}], must be a subset of [{1}]" # noqa: E501
.format(", ".join(map(str, set({{{name}}})-set(allowed_values))), # noqa: E501
.format(", ".join(map(str, set({{{name}}}) - set(allowed_values))), # noqa: E501
", ".join(map(str, allowed_values)))
)
{{/isListContainer}}
@@ -102,7 +102,7 @@ class {{classname}}(Model):
if not set({{{name}}}.keys()).issubset(set(allowed_values)):
raise ValueError(
"Invalid keys in `{{{name}}}` [{0}], must be a subset of [{1}]" # noqa: E501
.format(", ".join(map(str, set({{{name}}}.keys())-set(allowed_values))), # noqa: E501
.format(", ".join(map(str, set({{{name}}}.keys()) - set(allowed_values))), # noqa: E501
", ".join(map(str, allowed_values)))
)
{{/isMapContainer}}

View File

@@ -1,8 +1,7 @@
from __future__ import absolute_import
# flake8: noqa
# import apis into api package
{{#apiInfo}}
{{#apis}}
from .{{classVarName}} import {{classname}}
{{/apis}}
{{/apiInfo}}
{{#apiInfo}}{{#apis}}from {{apiPackage}}.{{classVarName}} import {{classname}}
{{/apis}}{{/apiInfo}}

View File

@@ -1,9 +1,10 @@
# coding: utf-8
# flake8: noqa
{{>partial_header}}
from __future__ import absolute_import
# import models into model package
{{#models}}{{#model}}from .{{classFilename}} import {{classname}}{{/model}}
{{#models}}{{#model}}from {{modelPackage}}.{{classFilename}} import {{classname}}{{/model}}
{{/models}}

View File

@@ -1,16 +1,17 @@
# coding: utf-8
# flake8: noqa
{{>partial_header}}
from __future__ import absolute_import
# import models into sdk package
{{#models}}{{#model}}from .models.{{classFilename}} import {{classname}}
{{/model}}{{/models}}
# import apis into sdk package
{{#apiInfo}}{{#apis}}from .apis.{{classVarName}} import {{classname}}
{{#apiInfo}}{{#apis}}from {{apiPackage}}.{{classVarName}} import {{classname}}
{{/apis}}{{/apiInfo}}
# import ApiClient
from .api_client import ApiClient
from .configuration import Configuration
from {{packageName}}.api_client import ApiClient
from {{packageName}}.configuration import Configuration
# import models into sdk package
{{#models}}{{#model}}from {{modelPackage}}.{{classFilename}} import {{classname}}
{{/model}}{{/models}}

View File

@@ -4,20 +4,18 @@
from __future__ import absolute_import
import sys
import os
import re
import re # noqa: F401
# python 2 and python 3 compatibility library
from six import iteritems
import six
from ..api_client import ApiClient
from {{packageName}}.api_client import ApiClient
{{#operations}}
class {{classname}}(object):
"""
NOTE: This class is auto generated by the swagger code generator program.
"""NOTE: This class is auto generated by the swagger code generator program.
Do not edit the class manually.
Ref: https://github.com/swagger-api/swagger-codegen
"""
@@ -28,13 +26,11 @@ class {{classname}}(object):
self.api_client = api_client
{{#operation}}
def {{operationId}}(self, {{#sortParamsByRequiredFlag}}{{#allParams}}{{#required}}{{paramName}}, {{/required}}{{/allParams}}{{/sortParamsByRequiredFlag}}**kwargs):
"""
{{#summary}}
{{{summary}}}
{{/summary}}
def {{operationId}}(self, {{#sortParamsByRequiredFlag}}{{#allParams}}{{#required}}{{paramName}}, {{/required}}{{/allParams}}{{/sortParamsByRequiredFlag}}**kwargs): # noqa: E501
"""{{#summary}}{{.}}{{/summary}}{{^summary}}{{operationId}}{{/summary}} # noqa: E501
{{#notes}}
{{{notes}}}
{{{notes}}} # noqa: E501
{{/notes}}
This method makes a synchronous HTTP request by default. To make an
asynchronous HTTP request, please pass async=True
@@ -56,18 +52,16 @@ class {{classname}}(object):
"""
kwargs['_return_http_data_only'] = True
if kwargs.get('async'):
return self.{{operationId}}_with_http_info({{#sortParamsByRequiredFlag}}{{#allParams}}{{#required}}{{paramName}}, {{/required}}{{/allParams}}{{/sortParamsByRequiredFlag}}**kwargs)
return self.{{operationId}}_with_http_info({{#sortParamsByRequiredFlag}}{{#allParams}}{{#required}}{{paramName}}, {{/required}}{{/allParams}}{{/sortParamsByRequiredFlag}}**kwargs) # noqa: E501
else:
(data) = self.{{operationId}}_with_http_info({{#sortParamsByRequiredFlag}}{{#allParams}}{{#required}}{{paramName}}, {{/required}}{{/allParams}}{{/sortParamsByRequiredFlag}}**kwargs)
(data) = self.{{operationId}}_with_http_info({{#sortParamsByRequiredFlag}}{{#allParams}}{{#required}}{{paramName}}, {{/required}}{{/allParams}}{{/sortParamsByRequiredFlag}}**kwargs) # noqa: E501
return data
def {{operationId}}_with_http_info(self, {{#sortParamsByRequiredFlag}}{{#allParams}}{{#required}}{{paramName}}, {{/required}}{{/allParams}}{{/sortParamsByRequiredFlag}}**kwargs):
"""
{{#summary}}
{{{summary}}}
{{/summary}}
def {{operationId}}_with_http_info(self, {{#sortParamsByRequiredFlag}}{{#allParams}}{{#required}}{{paramName}}, {{/required}}{{/allParams}}{{/sortParamsByRequiredFlag}}**kwargs): # noqa: E501
"""{{#summary}}{{.}}{{/summary}}{{^summary}}{{operationId}}{{/summary}} # noqa: E501
{{#notes}}
{{{notes}}}
{{{notes}}} # noqa: E501
{{/notes}}
This method makes a synchronous HTTP request by default. To make an
asynchronous HTTP request, please pass async=True
@@ -88,14 +82,14 @@ class {{classname}}(object):
returns the request thread.
"""
all_params = [{{#allParams}}'{{paramName}}'{{#hasMore}}, {{/hasMore}}{{/allParams}}]
all_params = [{{#allParams}}'{{paramName}}'{{#hasMore}}, {{/hasMore}}{{/allParams}}] # noqa: E501
all_params.append('async')
all_params.append('_return_http_data_only')
all_params.append('_preload_content')
all_params.append('_request_timeout')
params = locals()
for key, val in iteritems(params['kwargs']):
for key, val in six.iteritems(params['kwargs']):
if key not in all_params:
raise TypeError(
"Got an unexpected keyword argument '%s'"
@@ -106,44 +100,48 @@ class {{classname}}(object):
{{#allParams}}
{{#required}}
# verify the required parameter '{{paramName}}' is set
if ('{{paramName}}' not in params) or (params['{{paramName}}'] is None):
raise ValueError("Missing the required parameter `{{paramName}}` when calling `{{operationId}}`")
if ('{{paramName}}' not in params or
params['{{paramName}}'] is None):
raise ValueError("Missing the required parameter `{{paramName}}` when calling `{{operationId}}`") # noqa: E501
{{/required}}
{{/allParams}}
{{#allParams}}
{{#hasValidation}}
{{#maxLength}}
if '{{paramName}}' in params and len(params['{{paramName}}']) > {{maxLength}}:
raise ValueError("Invalid value for parameter `{{paramName}}` when calling `{{operationId}}`, length must be less than or equal to `{{maxLength}}`")
if ('{{paramName}}' in params and
len(params['{{paramName}}']) > {{maxLength}}):
raise ValueError("Invalid value for parameter `{{paramName}}` when calling `{{operationId}}`, length must be less than or equal to `{{maxLength}}`") # noqa: E501
{{/maxLength}}
{{#minLength}}
if '{{paramName}}' in params and len(params['{{paramName}}']) < {{minLength}}:
raise ValueError("Invalid value for parameter `{{paramName}}` when calling `{{operationId}}`, length must be greater than or equal to `{{minLength}}`")
if ('{{paramName}}' in params and
len(params['{{paramName}}']) < {{minLength}}):
raise ValueError("Invalid value for parameter `{{paramName}}` when calling `{{operationId}}`, length must be greater than or equal to `{{minLength}}`") # noqa: E501
{{/minLength}}
{{#maximum}}
if '{{paramName}}' in params and params['{{paramName}}'] >{{#exclusiveMaximum}}={{/exclusiveMaximum}} {{maximum}}:
raise ValueError("Invalid value for parameter `{{paramName}}` when calling `{{operationId}}`, must be a value less than {{^exclusiveMaximum}}or equal to {{/exclusiveMaximum}}`{{maximum}}`")
if '{{paramName}}' in params and params['{{paramName}}'] >{{#exclusiveMaximum}}={{/exclusiveMaximum}} {{maximum}}: # noqa: E501
raise ValueError("Invalid value for parameter `{{paramName}}` when calling `{{operationId}}`, must be a value less than {{^exclusiveMaximum}}or equal to {{/exclusiveMaximum}}`{{maximum}}`") # noqa: E501
{{/maximum}}
{{#minimum}}
if '{{paramName}}' in params and params['{{paramName}}'] <{{#exclusiveMinimum}}={{/exclusiveMinimum}} {{minimum}}:
raise ValueError("Invalid value for parameter `{{paramName}}` when calling `{{operationId}}`, must be a value greater than {{^exclusiveMinimum}}or equal to {{/exclusiveMinimum}}`{{minimum}}`")
if '{{paramName}}' in params and params['{{paramName}}'] <{{#exclusiveMinimum}}={{/exclusiveMinimum}} {{minimum}}: # noqa: E501
raise ValueError("Invalid value for parameter `{{paramName}}` when calling `{{operationId}}`, must be a value greater than {{^exclusiveMinimum}}or equal to {{/exclusiveMinimum}}`{{minimum}}`") # noqa: E501
{{/minimum}}
{{#pattern}}
if '{{paramName}}' in params and not re.search('{{{vendorExtensions.x-regex}}}', params['{{paramName}}']{{#vendorExtensions.x-modifiers}}{{#-first}}, flags={{/-first}}re.{{.}}{{^-last}} | {{/-last}}{{/vendorExtensions.x-modifiers}}):
raise ValueError("Invalid value for parameter `{{paramName}}` when calling `{{operationId}}`, must conform to the pattern `{{{pattern}}}`")
if '{{paramName}}' in params and not re.search('{{{vendorExtensions.x-regex}}}', params['{{paramName}}']{{#vendorExtensions.x-modifiers}}{{#-first}}, flags={{/-first}}re.{{.}}{{^-last}} | {{/-last}}{{/vendorExtensions.x-modifiers}}): # noqa: E501
raise ValueError("Invalid value for parameter `{{paramName}}` when calling `{{operationId}}`, must conform to the pattern `{{{pattern}}}`") # noqa: E501
{{/pattern}}
{{#maxItems}}
if '{{paramName}}' in params and len(params['{{paramName}}']) > {{maxItems}}:
raise ValueError("Invalid value for parameter `{{paramName}}` when calling `{{operationId}}`, number of items must be less than or equal to `{{maxItems}}`")
if ('{{paramName}}' in params and
len(params['{{paramName}}']) > {{maxItems}}):
raise ValueError("Invalid value for parameter `{{paramName}}` when calling `{{operationId}}`, number of items must be less than or equal to `{{maxItems}}`") # noqa: E501
{{/maxItems}}
{{#minItems}}
if '{{paramName}}' in params and len(params['{{paramName}}']) < {{minItems}}:
raise ValueError("Invalid value for parameter `{{paramName}}` when calling `{{operationId}}`, number of items must be greater than or equal to `{{minItems}}`")
if ('{{paramName}}' in params and
len(params['{{paramName}}']) < {{minItems}}):
raise ValueError("Invalid value for parameter `{{paramName}}` when calling `{{operationId}}`, number of items must be greater than or equal to `{{minItems}}`") # noqa: E501
{{/minItems}}
{{/hasValidation}}
{{#-last}}
{{/-last}}
{{/allParams}}
collection_formats = {}
@@ -151,30 +149,30 @@ class {{classname}}(object):
path_params = {}
{{#pathParams}}
if '{{paramName}}' in params:
path_params['{{baseName}}'] = params['{{paramName}}']{{#isListContainer}}
collection_formats['{{baseName}}'] = '{{collectionFormat}}'{{/isListContainer}}
path_params['{{baseName}}'] = params['{{paramName}}']{{#isListContainer}} # noqa: E501
collection_formats['{{baseName}}'] = '{{collectionFormat}}'{{/isListContainer}} # noqa: E501
{{/pathParams}}
query_params = []
{{#queryParams}}
if '{{paramName}}' in params:
query_params.append(('{{baseName}}', params['{{paramName}}'])){{#isListContainer}}
collection_formats['{{baseName}}'] = '{{collectionFormat}}'{{/isListContainer}}
query_params.append(('{{baseName}}', params['{{paramName}}'])){{#isListContainer}} # noqa: E501
collection_formats['{{baseName}}'] = '{{collectionFormat}}'{{/isListContainer}} # noqa: E501
{{/queryParams}}
header_params = {}
{{#headerParams}}
if '{{paramName}}' in params:
header_params['{{baseName}}'] = params['{{paramName}}']{{#isListContainer}}
collection_formats['{{baseName}}'] = '{{collectionFormat}}'{{/isListContainer}}
header_params['{{baseName}}'] = params['{{paramName}}']{{#isListContainer}} # noqa: E501
collection_formats['{{baseName}}'] = '{{collectionFormat}}'{{/isListContainer}} # noqa: E501
{{/headerParams}}
form_params = []
local_var_files = {}
{{#formParams}}
if '{{paramName}}' in params:
{{#notFile}}form_params.append(('{{baseName}}', params['{{paramName}}'])){{/notFile}}{{#isFile}}local_var_files['{{baseName}}'] = params['{{paramName}}']{{/isFile}}{{#isListContainer}}
collection_formats['{{baseName}}'] = '{{collectionFormat}}'{{/isListContainer}}
{{#notFile}}form_params.append(('{{baseName}}', params['{{paramName}}'])){{/notFile}}{{#isFile}}local_var_files['{{baseName}}'] = params['{{paramName}}']{{/isFile}}{{#isListContainer}} # noqa: E501
collection_formats['{{baseName}}'] = '{{collectionFormat}}'{{/isListContainer}} # noqa: E501
{{/formParams}}
body_params = None
@@ -184,32 +182,33 @@ class {{classname}}(object):
{{/bodyParam}}
{{#hasProduces}}
# HTTP header `Accept`
header_params['Accept'] = self.api_client.\
select_header_accept([{{#produces}}'{{{mediaType}}}'{{#hasMore}}, {{/hasMore}}{{/produces}}])
header_params['Accept'] = self.api_client.select_header_accept(
[{{#produces}}'{{{mediaType}}}'{{#hasMore}}, {{/hasMore}}{{/produces}}]) # noqa: E501
{{/hasProduces}}
{{#hasConsumes}}
# HTTP header `Content-Type`
header_params['Content-Type'] = self.api_client.\
select_header_content_type([{{#consumes}}'{{{mediaType}}}'{{#hasMore}}, {{/hasMore}}{{/consumes}}])
header_params['Content-Type'] = self.api_client.select_header_content_type( # noqa: E501
[{{#consumes}}'{{{mediaType}}}'{{#hasMore}}, {{/hasMore}}{{/consumes}}]) # noqa: E501
{{/hasConsumes}}
# Authentication setting
auth_settings = [{{#authMethods}}'{{name}}'{{#hasMore}}, {{/hasMore}}{{/authMethods}}]
auth_settings = [{{#authMethods}}'{{name}}'{{#hasMore}}, {{/hasMore}}{{/authMethods}}] # noqa: E501
return self.api_client.call_api('{{{path}}}', '{{httpMethod}}',
path_params,
query_params,
header_params,
body=body_params,
post_params=form_params,
files=local_var_files,
response_type={{#returnType}}'{{returnType}}'{{/returnType}}{{^returnType}}None{{/returnType}},
auth_settings=auth_settings,
async=params.get('async'),
_return_http_data_only=params.get('_return_http_data_only'),
_preload_content=params.get('_preload_content', True),
_request_timeout=params.get('_request_timeout'),
collection_formats=collection_formats)
return self.api_client.call_api(
'{{{path}}}', '{{httpMethod}}',
path_params,
query_params,
header_params,
body=body_params,
post_params=form_params,
files=local_var_files,
response_type={{#returnType}}'{{returnType}}'{{/returnType}}{{^returnType}}None{{/returnType}}, # noqa: E501
auth_settings=auth_settings,
async=params.get('async'),
_return_http_data_only=params.get('_return_http_data_only'),
_preload_content=params.get('_preload_content', True),
_request_timeout=params.get('_request_timeout'),
collection_formats=collection_formats)
{{/operation}}
{{/operations}}

View File

@@ -2,30 +2,28 @@
{{>partial_header}}
from __future__ import absolute_import
import os
import re
import datetime
import json
import mimetypes
from multiprocessing.pool import ThreadPool
import os
import re
import tempfile
# python 2 and python 3 compatibility library
import six
from six.moves.urllib.parse import quote
{{#tornado}}
import tornado.gen
{{/tornado}}
from multiprocessing.pool import ThreadPool
from datetime import date, datetime
# python 2 and python 3 compatibility library
from six import PY3, integer_types, iteritems, text_type
from six.moves.urllib.parse import quote
from . import models
from .configuration import Configuration
from .rest import ApiException, RESTClientObject
from {{packageName}}.configuration import Configuration
import {{modelPackage}}
from {{packageName}} import rest
class ApiClient(object):
"""
Generic API client for Swagger client library builds.
"""Generic API client for Swagger client library builds.
Swagger generic API client. This client handles the client-
server communication, and is invariant across implementations. Specifics of
@@ -38,38 +36,39 @@ class ApiClient(object):
:param configuration: .Configuration object for this client
:param header_name: a header to pass when making calls to the API.
:param header_value: a header value to pass when making calls to
:param header_value: a header value to pass when making calls to
the API.
:param cookie: a cookie to include in the header when making calls
:param cookie: a cookie to include in the header when making calls
to the API
"""
PRIMITIVE_TYPES = (float, bool, bytes, text_type) + integer_types
PRIMITIVE_TYPES = (float, bool, bytes, six.text_type) + six.integer_types
NATIVE_TYPES_MAPPING = {
'int': int,
'long': int if PY3 else long,
'long': int if six.PY3 else long, # noqa: F821
'float': float,
'str': str,
'bool': bool,
'date': date,
'datetime': datetime,
'date': datetime.date,
'datetime': datetime.datetime,
'object': object,
}
def __init__(self, configuration=None, header_name=None, header_value=None, cookie=None):
def __init__(self, configuration=None, header_name=None, header_value=None,
cookie=None):
if configuration is None:
configuration = Configuration()
self.configuration = configuration
self.pool = ThreadPool()
self.rest_client = RESTClientObject(configuration)
self.rest_client = rest.RESTClientObject(configuration)
self.default_headers = {}
if header_name is not None:
self.default_headers[header_name] = header_value
self.cookie = cookie
# Set default User-Agent.
self.user_agent = '{{#httpUserAgent}}{{{.}}}{{/httpUserAgent}}{{^httpUserAgent}}Swagger-Codegen/{{{packageVersion}}}/python{{/httpUserAgent}}'
def __del__(self):
self.pool.close()
self.pool.join()
@@ -89,12 +88,12 @@ class ApiClient(object):
{{#tornado}}
@tornado.gen.coroutine
{{/tornado}}
{{#asyncio}}async {{/asyncio}}def __call_api(self, resource_path, method,
path_params=None, query_params=None, header_params=None,
body=None, post_params=None, files=None,
response_type=None, auth_settings=None,
_return_http_data_only=None, collection_formats=None, _preload_content=True,
_request_timeout=None):
{{#asyncio}}async {{/asyncio}}def __call_api(
self, resource_path, method, path_params=None,
query_params=None, header_params=None, body=None, post_params=None,
files=None, response_type=None, auth_settings=None,
_return_http_data_only=None, collection_formats=None,
_preload_content=True, _request_timeout=None):
config = self.configuration
@@ -116,7 +115,9 @@ class ApiClient(object):
for k, v in path_params:
# specified safe chars, encode everything
resource_path = resource_path.replace(
'{%s}' % k, quote(str(v), safe=config.safe_chars_for_path_param))
'{%s}' % k,
quote(str(v), safe=config.safe_chars_for_path_param)
)
# query parameters
if query_params:
@@ -142,14 +143,14 @@ class ApiClient(object):
url = self.configuration.host + resource_path
# perform request and return response
response_data = {{#asyncio}}await {{/asyncio}}{{#tornado}}yield {{/tornado}}self.request(method, url,
query_params=query_params,
headers=header_params,
post_params=post_params, body=body,
_preload_content=_preload_content,
_request_timeout=_request_timeout)
response_data = {{#asyncio}}await {{/asyncio}}{{#tornado}}yield {{/tornado}}self.request(
method, url, query_params=query_params, headers=header_params,
post_params=post_params, body=body,
_preload_content=_preload_content,
_request_timeout=_request_timeout)
self.last_response = response_data
{{^tornado}}
return_data = response_data
if _preload_content:
@@ -162,11 +163,12 @@ class ApiClient(object):
if _return_http_data_only:
return (return_data)
else:
return (return_data, response_data.status, response_data.getheaders())
return (return_data, response_data.status,
response_data.getheaders())
{{/tornado}}
def sanitize_for_serialization(self, obj):
"""
Builds a JSON POST object.
"""Builds a JSON POST object.
If obj is None, return None.
If obj is str, int, long, float, bool, return directly.
@@ -189,7 +191,7 @@ class ApiClient(object):
elif isinstance(obj, tuple):
return tuple(self.sanitize_for_serialization(sub_obj)
for sub_obj in obj)
elif isinstance(obj, (datetime, date)):
elif isinstance(obj, (datetime.datetime, datetime.date)):
return obj.isoformat()
if isinstance(obj, dict):
@@ -201,15 +203,14 @@ class ApiClient(object):
# Convert attribute name to json key in
# model definition for request.
obj_dict = {obj.attribute_map[attr]: getattr(obj, attr)
for attr, _ in iteritems(obj.swagger_types)
for attr, _ in six.iteritems(obj.swagger_types)
if getattr(obj, attr) is not None}
return {key: self.sanitize_for_serialization(val)
for key, val in iteritems(obj_dict)}
for key, val in six.iteritems(obj_dict)}
def deserialize(self, response, response_type):
"""
Deserializes response into an object.
"""Deserializes response into an object.
:param response: RESTResponse object to be deserialized.
:param response_type: class literal for
@@ -231,8 +232,7 @@ class ApiClient(object):
return self.__deserialize(data, response_type)
def __deserialize(self, data, klass):
"""
Deserializes dict, list, str into an object.
"""Deserializes dict, list, str into an object.
:param data: dict, list or str.
:param klass: class literal, or string of class name.
@@ -251,21 +251,21 @@ class ApiClient(object):
if klass.startswith('dict('):
sub_kls = re.match('dict\(([^,]*), (.*)\)', klass).group(2)
return {k: self.__deserialize(v, sub_kls)
for k, v in iteritems(data)}
for k, v in six.iteritems(data)}
# convert str to class
if klass in self.NATIVE_TYPES_MAPPING:
klass = self.NATIVE_TYPES_MAPPING[klass]
else:
klass = getattr(models, klass)
klass = getattr({{modelPackage}}, klass)
if klass in self.PRIMITIVE_TYPES:
return self.__deserialize_primitive(data, klass)
elif klass == object:
return self.__deserialize_object(data)
elif klass == date:
elif klass == datetime.date:
return self.__deserialize_date(data)
elif klass == datetime:
elif klass == datetime.datetime:
return self.__deserialize_datatime(data)
else:
return self.__deserialize_model(data, klass)
@@ -274,10 +274,10 @@ class ApiClient(object):
path_params=None, query_params=None, header_params=None,
body=None, post_params=None, files=None,
response_type=None, auth_settings=None, async=None,
_return_http_data_only=None, collection_formats=None, _preload_content=True,
_request_timeout=None):
"""
Makes the HTTP request (synchronous) and return the deserialized data.
_return_http_data_only=None, collection_formats=None,
_preload_content=True, _request_timeout=None):
"""Makes the HTTP request (synchronous) and returns deserialized data.
To make an async request, set the async parameter.
:param resource_path: Path to method endpoint.
@@ -294,13 +294,17 @@ class ApiClient(object):
:param files dict: key -> filename, value -> filepath,
for `multipart/form-data`.
:param async bool: execute request asynchronously
:param _return_http_data_only: response data without head status code and headers
:param _return_http_data_only: response data without head status code
and headers
:param collection_formats: dict of collection formats for path, query,
header, and post parameters.
:param _preload_content: if False, the urllib3.HTTPResponse object will be returned without
reading/decoding response data. Default is True.
:param _request_timeout: timeout setting for this request. If one number provided, it will be total request
timeout. It can also be a pair (tuple) of (connection, read) timeouts.
:param _preload_content: if False, the urllib3.HTTPResponse object will
be returned without reading/decoding response
data. Default is True.
:param _request_timeout: timeout setting for this request. If one
number provided, it will be total request
timeout. It can also be a pair (tuple) of
(connection, read) timeouts.
:return:
If async parameter is True,
the request will be called asynchronously.
@@ -313,22 +317,23 @@ class ApiClient(object):
path_params, query_params, header_params,
body, post_params, files,
response_type, auth_settings,
_return_http_data_only, collection_formats, _preload_content, _request_timeout)
_return_http_data_only, collection_formats,
_preload_content, _request_timeout)
else:
thread = self.pool.apply_async(self.__call_api, (resource_path, method,
path_params, query_params,
thread = self.pool.apply_async(self.__call_api, (resource_path,
method, path_params, query_params,
header_params, body,
post_params, files,
response_type, auth_settings,
_return_http_data_only,
collection_formats, _preload_content, _request_timeout))
collection_formats,
_preload_content, _request_timeout))
return thread
def request(self, method, url, query_params=None, headers=None,
post_params=None, body=None, _preload_content=True, _request_timeout=None):
"""
Makes the HTTP request using RESTClient.
"""
post_params=None, body=None, _preload_content=True,
_request_timeout=None):
"""Makes the HTTP request using RESTClient."""
if method == "GET":
return self.rest_client.GET(url,
query_params=query_params,
@@ -387,8 +392,7 @@ class ApiClient(object):
)
def parameters_to_tuples(self, params, collection_formats):
"""
Get parameters as list of tuples, formatting collections.
"""Get parameters as list of tuples, formatting collections.
:param params: Parameters as dict or list of two-tuples
:param dict collection_formats: Parameter collection formats
@@ -397,7 +401,7 @@ class ApiClient(object):
new_params = []
if collection_formats is None:
collection_formats = {}
for k, v in iteritems(params) if isinstance(params, dict) else params:
for k, v in six.iteritems(params) if isinstance(params, dict) else params: # noqa: E501
if k in collection_formats:
collection_format = collection_formats[k]
if collection_format == 'multi':
@@ -418,8 +422,7 @@ class ApiClient(object):
return new_params
def prepare_post_parameters(self, post_params=None, files=None):
"""
Builds form parameters.
"""Builds form parameters.
:param post_params: Normal form parameters.
:param files: File parameters.
@@ -431,7 +434,7 @@ class ApiClient(object):
params = post_params
if files:
for k, v in iteritems(files):
for k, v in six.iteritems(files):
if not v:
continue
file_names = v if type(v) is list else [v]
@@ -439,15 +442,15 @@ class ApiClient(object):
with open(n, 'rb') as f:
filename = os.path.basename(f.name)
filedata = f.read()
mimetype = mimetypes.\
guess_type(filename)[0] or 'application/octet-stream'
params.append(tuple([k, tuple([filename, filedata, mimetype])]))
mimetype = (mimetypes.guess_type(filename)[0] or
'application/octet-stream')
params.append(
tuple([k, tuple([filename, filedata, mimetype])]))
return params
def select_header_accept(self, accepts):
"""
Returns `Accept` based on an array of accepts provided.
"""Returns `Accept` based on an array of accepts provided.
:param accepts: List of headers.
:return: Accept (e.g. application/json).
@@ -463,8 +466,7 @@ class ApiClient(object):
return ', '.join(accepts)
def select_header_content_type(self, content_types):
"""
Returns `Content-Type` based on an array of content_types provided.
"""Returns `Content-Type` based on an array of content_types provided.
:param content_types: List of content-types.
:return: Content-Type (e.g. application/json).
@@ -480,8 +482,7 @@ class ApiClient(object):
return content_types[0]
def update_params_for_auth(self, headers, querys, auth_settings):
"""
Updates header and query params based on authentication setting.
"""Updates header and query params based on authentication setting.
:param headers: Header parameters dict to be updated.
:param querys: Query parameters tuple list to be updated.
@@ -505,7 +506,8 @@ class ApiClient(object):
)
def __deserialize_file(self, response):
"""
"""Deserializes body to file
Saves response body into a file in a temporary folder,
using the filename from the `Content-Disposition` header if provided.
@@ -518,9 +520,8 @@ class ApiClient(object):
content_disposition = response.getheader("Content-Disposition")
if content_disposition:
filename = re.\
search(r'filename=[\'"]?([^\'"\s]+)[\'"]?', content_disposition).\
group(1)
filename = re.search(r'filename=[\'"]?([^\'"\s]+)[\'"]?',
content_disposition).group(1)
path = os.path.join(os.path.dirname(path), filename)
with open(path, "w") as f:
@@ -529,8 +530,7 @@ class ApiClient(object):
return path
def __deserialize_primitive(self, data, klass):
"""
Deserializes string to primitive type.
"""Deserializes string to primitive type.
:param data: str.
:param klass: class literal.
@@ -540,21 +540,19 @@ class ApiClient(object):
try:
return klass(data)
except UnicodeEncodeError:
return unicode(data)
return unicode(data) # noqa: F821
except TypeError:
return data
def __deserialize_object(self, value):
"""
Return a original value.
"""Return a original value.
:return: object.
"""
return value
def __deserialize_date(self, string):
"""
Deserializes string to date.
"""Deserializes string to date.
:param string: str.
:return: date.
@@ -565,14 +563,13 @@ class ApiClient(object):
except ImportError:
return string
except ValueError:
raise ApiException(
raise rest.ApiException(
status=0,
reason="Failed to parse `{0}` into a date object".format(string)
reason="Failed to parse `{0}` as date object".format(string)
)
def __deserialize_datatime(self, string):
"""
Deserializes string to datetime.
"""Deserializes string to datetime.
The string should be in iso8601 datetime format.
@@ -585,32 +582,32 @@ class ApiClient(object):
except ImportError:
return string
except ValueError:
raise ApiException(
raise rest.ApiException(
status=0,
reason=(
"Failed to parse `{0}` into a datetime object"
"Failed to parse `{0}` as datetime object"
.format(string)
)
)
def __deserialize_model(self, data, klass):
"""
Deserializes list or dict to model.
"""Deserializes list or dict to model.
:param data: dict, list.
:param klass: class literal.
:return: model object.
"""
if not klass.swagger_types and not hasattr(klass, 'get_real_child_model'):
if not klass.swagger_types and not hasattr(klass,
'get_real_child_model'):
return data
kwargs = {}
if klass.swagger_types is not None:
for attr, attr_type in iteritems(klass.swagger_types):
if data is not None \
and klass.attribute_map[attr] in data \
and isinstance(data, (list, dict)):
for attr, attr_type in six.iteritems(klass.swagger_types):
if (data is not None and
klass.attribute_map[attr] in data and
isinstance(data, (list, dict))):
value = data[klass.attribute_map[attr]]
kwargs[attr] = self.__deserialize(value, attr_type)

View File

@@ -17,7 +17,7 @@ Method | HTTP request | Description
{{{notes}}}{{/notes}}
### Example
### Example
```python
from __future__ import print_function
import time
@@ -51,7 +51,7 @@ api_instance = {{{packageName}}}.{{{classname}}}()
{{/allParams}}
{{/hasAuthMethods}}
try:
try:
{{#summary}} # {{{.}}}
{{/summary}} {{#returnType}}api_response = {{/returnType}}api_instance.{{{operationId}}}({{#allParams}}{{#required}}{{paramName}}{{/required}}{{^required}}{{paramName}}={{paramName}}{{/required}}{{#hasMore}}, {{/hasMore}}{{/allParams}}){{#returnType}}
pprint(api_response){{/returnType}}

View File

@@ -4,30 +4,29 @@
from __future__ import absolute_import
import os
import sys
import unittest
import {{packageName}}
from {{apiPackage}}.{{classVarName}} import {{classname}} # noqa: E501
from {{packageName}}.rest import ApiException
from {{packageName}}.apis.{{classVarName}} import {{classname}}
class {{#operations}}Test{{classname}}(unittest.TestCase):
""" {{classname}} unit test stubs """
"""{{classname}} unit test stubs"""
def setUp(self):
self.api = {{packageName}}.apis.{{classVarName}}.{{classname}}()
self.api = {{apiPackage}}.{{classVarName}}.{{classname}}() # noqa: E501
def tearDown(self):
pass
{{#operation}}
def test_{{operationId}}(self):
"""
Test case for {{{operationId}}}
"""Test case for {{{operationId}}}
{{{summary}}}
{{#summary}}
{{{summary}}} # noqa: E501
{{/summary}}
"""
pass

View File

@@ -2,16 +2,15 @@
{{>partial_header}}
import aiohttp
import io
import json
import ssl
import certifi
import logging
import re
import ssl
import aiohttp
import certifi
# python 2 and python 3 compatibility library
from six import PY3
from six.moves.urllib.parse import urlencode
logger = logging.getLogger(__name__)
@@ -26,22 +25,18 @@ class RESTResponse(io.IOBase):
self.data = data
def getheaders(self):
"""
Returns a CIMultiDictProxy of the response headers.
"""
"""Returns a CIMultiDictProxy of the response headers."""
return self.aiohttp_response.headers
def getheader(self, name, default=None):
"""
Returns a given response header.
"""
"""Returns a given response header."""
return self.aiohttp_response.headers.get(name, default)
class RESTClientObject:
class RESTClientObject(object):
def __init__(self, configuration, pools_size=4, maxsize=4):
# maxsize is the number of requests to host that are allowed in parallel
# maxsize is number of requests to host that are allowed in parallel
# ca_certs vs cert_file vs key_file
# http://stackoverflow.com/a/23957365/2985775
@@ -53,6 +48,7 @@ class RESTClientObject:
ca_certs = certifi.where()
ssl_context = ssl.SSLContext()
ssl_context.load_verify_locations(cafile=ca_certs)
if configuration.cert_file:
ssl_context.load_cert_chain(
configuration.cert_file, keyfile=configuration.key_file
@@ -60,6 +56,7 @@ class RESTClientObject:
connector = aiohttp.TCPConnector(
limit=maxsize,
ssl_context=ssl_context,
verify_ssl=configuration.verify_ssl
)
@@ -75,8 +72,10 @@ class RESTClientObject:
)
async def request(self, method, url, query_params=None, headers=None,
body=None, post_params=None, _preload_content=True, _request_timeout=None):
"""
body=None, post_params=None, _preload_content=True,
_request_timeout=None):
"""Execute request
:param method: http request method
:param url: http request url
:param query_params: query parameters in the url
@@ -85,12 +84,16 @@ class RESTClientObject:
:param post_params: request post parameters,
`application/x-www-form-urlencoded`
and `multipart/form-data`
:param _preload_content: this is a non-applicable field for the AiohttpClient.
:param _request_timeout: timeout setting for this request. If one number provided, it will be total request
timeout. It can also be a pair (tuple) of (connection, read) timeouts.
:param _preload_content: this is a non-applicable field for
the AiohttpClient.
:param _request_timeout: timeout setting for this request. If one
number provided, it will be total request
timeout. It can also be a pair (tuple) of
(connection, read) timeouts.
"""
method = method.upper()
assert method in ['GET', 'HEAD', 'DELETE', 'POST', 'PUT', 'PATCH', 'OPTIONS']
assert method in ['GET', 'HEAD', 'DELETE', 'POST', 'PUT',
'PATCH', 'OPTIONS']
if post_params and body:
raise ValueError(
@@ -118,7 +121,7 @@ class RESTClientObject:
if body is not None:
body = json.dumps(body)
args["data"] = body
elif headers['Content-Type'] == 'application/x-www-form-urlencoded':
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)
@@ -132,8 +135,9 @@ class RESTClientObject:
args["data"] = body
else:
# Cannot generate the request from given parameters
msg = """Cannot prepare a request message for provided arguments.
Please check that your arguments match declared content type."""
msg = """Cannot prepare a request message for provided
arguments. Please check that your arguments match
declared content type."""
raise ApiException(status=0, reason=msg)
else:
args["data"] = query_params
@@ -150,22 +154,25 @@ class RESTClientObject:
return r
async def GET(self, url, headers=None, query_params=None, _preload_content=True, _request_timeout=None):
async def GET(self, url, headers=None, query_params=None,
_preload_content=True, _request_timeout=None):
return (await self.request("GET", url,
headers=headers,
_preload_content=_preload_content,
_request_timeout=_request_timeout,
query_params=query_params))
headers=headers,
_preload_content=_preload_content,
_request_timeout=_request_timeout,
query_params=query_params))
async def HEAD(self, url, headers=None, query_params=None, _preload_content=True, _request_timeout=None):
async def HEAD(self, url, headers=None, query_params=None,
_preload_content=True, _request_timeout=None):
return (await self.request("HEAD", url,
headers=headers,
_preload_content=_preload_content,
_request_timeout=_request_timeout,
query_params=query_params))
async def OPTIONS(self, url, headers=None, query_params=None, post_params=None, body=None, _preload_content=True,
_request_timeout=None):
async def OPTIONS(self, url, headers=None, query_params=None,
post_params=None, body=None, _preload_content=True,
_request_timeout=None):
return (await self.request("OPTIONS", url,
headers=headers,
query_params=query_params,
@@ -174,7 +181,8 @@ class RESTClientObject:
_request_timeout=_request_timeout,
body=body))
async def DELETE(self, url, headers=None, query_params=None, body=None, _preload_content=True, _request_timeout=None):
async def DELETE(self, url, headers=None, query_params=None, body=None,
_preload_content=True, _request_timeout=None):
return (await self.request("DELETE", url,
headers=headers,
query_params=query_params,
@@ -182,8 +190,9 @@ class RESTClientObject:
_request_timeout=_request_timeout,
body=body))
async def POST(self, url, headers=None, query_params=None, post_params=None, body=None, _preload_content=True,
_request_timeout=None):
async def POST(self, url, headers=None, query_params=None,
post_params=None, body=None, _preload_content=True,
_request_timeout=None):
return (await self.request("POST", url,
headers=headers,
query_params=query_params,
@@ -192,8 +201,8 @@ class RESTClientObject:
_request_timeout=_request_timeout,
body=body))
async def PUT(self, url, headers=None, query_params=None, post_params=None, body=None, _preload_content=True,
_request_timeout=None):
async def PUT(self, url, headers=None, query_params=None, post_params=None,
body=None, _preload_content=True, _request_timeout=None):
return (await self.request("PUT", url,
headers=headers,
query_params=query_params,
@@ -202,8 +211,9 @@ class RESTClientObject:
_request_timeout=_request_timeout,
body=body))
async def PATCH(self, url, headers=None, query_params=None, post_params=None, body=None, _preload_content=True,
_request_timeout=None):
async def PATCH(self, url, headers=None, query_params=None,
post_params=None, body=None, _preload_content=True,
_request_timeout=None):
return (await self.request("PATCH", url,
headers=headers,
query_params=query_params,
@@ -228,13 +238,11 @@ class ApiException(Exception):
self.headers = None
def __str__(self):
"""
Custom error messages for exception
"""
error_message = "({0})\n"\
"Reason: {1}\n".format(self.status, self.reason)
"""Custom error messages for exception"""
error_message = "({0})\nReason: {1}\n".format(self.status, self.reason)
if self.headers:
error_message += "HTTP response headers: {0}\n".format(self.headers)
error_message += "HTTP response headers: {0}\n".format(
self.headers)
if self.body:
error_message += "HTTP response body: {0}\n".format(self.body)

View File

@@ -4,24 +4,23 @@
from __future__ import absolute_import
import urllib3
import copy
import logging
import multiprocessing
import sys
import urllib3
from six import iteritems
from six import with_metaclass
import six
from six.moves import http_client as httplib
class TypeWithDefault(type):
def __init__(cls, name, bases, dct):
super(TypeWithDefault, cls).__init__(name, bases, dct)
cls._default = None
def __call__(cls):
if cls._default == None:
if cls._default is None:
cls._default = type.__call__(cls)
return copy.copy(cls._default)
@@ -29,17 +28,15 @@ class TypeWithDefault(type):
cls._default = copy.copy(default)
class Configuration(with_metaclass(TypeWithDefault, object)):
"""
NOTE: This class is auto generated by the swagger code generator program.
class Configuration(six.with_metaclass(TypeWithDefault, object)):
"""NOTE: This class is auto generated by the swagger code generator program.
Ref: https://github.com/swagger-api/swagger-codegen
Do not edit the class manually.
"""
def __init__(self):
"""
Constructor
"""
"""Constructor"""
# Default Base url
self.host = "{{{basePath}}}"
# Temp file folder for downloading files
@@ -74,7 +71,8 @@ class Configuration(with_metaclass(TypeWithDefault, object)):
self.debug = False
# SSL/TLS verification
# Set this to false to skip verifying SSL certificate when calling API from https server.
# Set this to false to skip verifying SSL certificate when calling API
# from https server.
self.verify_ssl = True
# Set this to customize the certificate file to verify the peer.
self.ssl_ca_cert = None
@@ -92,7 +90,6 @@ class Configuration(with_metaclass(TypeWithDefault, object)):
# cpu_count * 5 is used as default value to increase performance.
self.connection_pool_maxsize = multiprocessing.cpu_count() * 5
# Proxy URL
self.proxy = None
# Safe chars for path_param
@@ -102,8 +99,8 @@ class Configuration(with_metaclass(TypeWithDefault, object)):
def logger_file(self):
"""The logger file.
If the logger_file is None, then add stream handler and remove file handler.
Otherwise, add file handler and remove stream handler.
If the logger_file is None, then add stream handler and remove file
handler. Otherwise, add file handler and remove stream handler.
:param value: The logger_file path.
:type: str
@@ -114,8 +111,8 @@ class Configuration(with_metaclass(TypeWithDefault, object)):
def logger_file(self, value):
"""The logger file.
If the logger_file is None, then add stream handler and remove file handler.
Otherwise, add file handler and remove stream handler.
If the logger_file is None, then add stream handler and remove file
handler. Otherwise, add file handler and remove stream handler.
:param value: The logger_file path.
:type: str
@@ -126,7 +123,7 @@ class Configuration(with_metaclass(TypeWithDefault, object)):
# then add file handler and remove stream handler.
self.logger_file_handler = logging.FileHandler(self.__logger_file)
self.logger_file_handler.setFormatter(self.logger_formatter)
for _, logger in iteritems(self.logger):
for _, logger in six.iteritems(self.logger):
logger.addHandler(self.logger_file_handler)
if self.logger_stream_handler:
logger.removeHandler(self.logger_stream_handler)
@@ -135,7 +132,7 @@ class Configuration(with_metaclass(TypeWithDefault, object)):
# then add stream handler and remove file handler.
self.logger_stream_handler = logging.StreamHandler()
self.logger_stream_handler.setFormatter(self.logger_formatter)
for _, logger in iteritems(self.logger):
for _, logger in six.iteritems(self.logger):
logger.addHandler(self.logger_stream_handler)
if self.logger_file_handler:
logger.removeHandler(self.logger_file_handler)
@@ -159,14 +156,14 @@ class Configuration(with_metaclass(TypeWithDefault, object)):
self.__debug = value
if self.__debug:
# if debug status is True, turn on debug logging
for _, logger in iteritems(self.logger):
for _, logger in six.iteritems(self.logger):
logger.setLevel(logging.DEBUG)
# turn on httplib debug
httplib.HTTPConnection.debuglevel = 1
else:
# if debug status is False, turn off debug logging,
# setting log level to default `logging.WARNING`
for _, logger in iteritems(self.logger):
for _, logger in six.iteritems(self.logger):
logger.setLevel(logging.WARNING)
# turn off httplib debug
httplib.HTTPConnection.debuglevel = 0
@@ -200,8 +197,9 @@ class Configuration(with_metaclass(TypeWithDefault, object)):
:param identifier: The identifier of apiKey.
:return: The token for api key authentication.
"""
if self.api_key.get(identifier) and self.api_key_prefix.get(identifier):
return self.api_key_prefix[identifier] + ' ' + self.api_key[identifier]
if (self.api_key.get(identifier) and
self.api_key_prefix.get(identifier)):
return self.api_key_prefix[identifier] + ' ' + self.api_key[identifier] # noqa: E501
elif self.api_key.get(identifier):
return self.api_key[identifier]
@@ -210,8 +208,9 @@ class Configuration(with_metaclass(TypeWithDefault, object)):
:return: The token for basic HTTP authentication.
"""
return urllib3.util.make_headers(basic_auth=self.username + ':' + self.password)\
.get('authorization')
return urllib3.util.make_headers(
basic_auth=self.username + ':' + self.password
).get('authorization')
def auth_settings(self):
"""Gets Auth Settings dict for api client.

View File

@@ -2,27 +2,31 @@
{{>partial_header}}
import pprint
import re # noqa: F401
import six
{{#imports}}{{#-first}}
{{/-first}}
{{import}} # noqa: F401,E501
{{/imports}}
{{#models}}
{{#model}}
from pprint import pformat
from six import iteritems
import re
class {{classname}}(object):
"""
NOTE: This class is auto generated by the swagger code generator program.
Do not edit the class manually.
"""
"""NOTE: This class is auto generated by the swagger code generator program.
Do not edit the class manually.
"""{{#allowableValues}}
{{#allowableValues}}
"""
allowed enum values
"""
{{#enumVars}}
{{name}} = {{{value}}}
{{/enumVars}}
{{/allowableValues}}
{{name}} = {{{value}}}{{^-last}}
{{/-last}}
{{/enumVars}}{{/allowableValues}}
"""
Attributes:
@@ -32,96 +36,96 @@ class {{classname}}(object):
and the value is json key in definition.
"""
swagger_types = {
{{#vars}}'{{name}}': '{{{datatype}}}'{{#hasMore}},
{{/hasMore}}{{/vars}}
{{#vars}}
'{{name}}': '{{{datatype}}}'{{#hasMore}},{{/hasMore}}
{{/vars}}
}
attribute_map = {
{{#vars}}'{{name}}': '{{baseName}}'{{#hasMore}},
{{/hasMore}}{{/vars}}
{{#vars}}
'{{name}}': '{{baseName}}'{{#hasMore}},{{/hasMore}}
{{/vars}}
}
{{#discriminator}}
discriminator_value_class_map = {
{{#children}}'{{vendorExtensions.x-discriminator-value}}': '{{{classname}}}'{{^-last}},
{{#children}}'{{^vendorExtensions.x-discriminator-value}}{{name}}{{/vendorExtensions.x-discriminator-value}}{{#vendorExtensions.x-discriminator-value}}{{{vendorExtensions.x-discriminator-value}}}{{/vendorExtensions.x-discriminator-value}}': '{{{classname}}}'{{^-last}},
{{/-last}}{{/children}}
}
{{/discriminator}}
def __init__(self{{#vars}}, {{name}}={{#defaultValue}}{{{defaultValue}}}{{/defaultValue}}{{^defaultValue}}None{{/defaultValue}}{{/vars}}):
"""
{{classname}} - a model defined in Swagger
"""
{{#vars}}
def __init__(self{{#vars}}, {{name}}={{#defaultValue}}{{{defaultValue}}}{{/defaultValue}}{{^defaultValue}}None{{/defaultValue}}{{/vars}}): # noqa: E501
"""{{classname}} - a model defined in Swagger""" # noqa: E501
{{#vars}}{{#-first}}
{{/-first}}
self._{{name}} = None
{{/vars}}
self.discriminator = {{#discriminator}}'{{discriminator}}'{{/discriminator}}{{^discriminator}}None{{/discriminator}}
{{#vars}}
{{#vars}}{{#-first}}
{{/-first}}
{{#required}}
self.{{name}} = {{name}}
{{/required}}
{{^required}}
if {{name}} is not None:
self.{{name}} = {{name}}
self.{{name}} = {{name}}
{{/required}}
{{/vars}}
{{#vars}}
@property
def {{name}}(self):
"""
Gets the {{name}} of this {{classname}}.
"""Gets the {{name}} of this {{classname}}. # noqa: E501
{{#description}}
{{{description}}}
{{{description}}} # noqa: E501
{{/description}}
:return: The {{name}} of this {{classname}}.
:return: The {{name}} of this {{classname}}. # noqa: E501
:rtype: {{datatype}}
"""
return self._{{name}}
@{{name}}.setter
def {{name}}(self, {{name}}):
"""
Sets the {{name}} of this {{classname}}.
"""Sets the {{name}} of this {{classname}}.
{{#description}}
{{{description}}}
{{{description}}} # noqa: E501
{{/description}}
:param {{name}}: The {{name}} of this {{classname}}.
:param {{name}}: The {{name}} of this {{classname}}. # noqa: E501
:type: {{datatype}}
"""
{{#required}}
if {{name}} is None:
raise ValueError("Invalid value for `{{name}}`, must not be `None`")
raise ValueError("Invalid value for `{{name}}`, must not be `None`") # noqa: E501
{{/required}}
{{#isEnum}}
{{#isContainer}}
allowed_values = [{{#allowableValues}}{{#values}}{{#items.isString}}"{{/items.isString}}{{{this}}}{{#items.isString}}"{{/items.isString}}{{^-last}}, {{/-last}}{{/values}}{{/allowableValues}}]
allowed_values = [{{#allowableValues}}{{#values}}{{#items.isString}}"{{/items.isString}}{{{this}}}{{#items.isString}}"{{/items.isString}}{{^-last}}, {{/-last}}{{/values}}{{/allowableValues}}] # noqa: E501
{{#isListContainer}}
if not set({{{name}}}).issubset(set(allowed_values)):
raise ValueError(
"Invalid values for `{{{name}}}` [{0}], must be a subset of [{1}]"
.format(", ".join(map(str, set({{{name}}})-set(allowed_values))),
"Invalid values for `{{{name}}}` [{0}], must be a subset of [{1}]" # noqa: E501
.format(", ".join(map(str, set({{{name}}}) - set(allowed_values))), # noqa: E501
", ".join(map(str, allowed_values)))
)
{{/isListContainer}}
{{#isMapContainer}}
if not set({{{name}}}.keys()).issubset(set(allowed_values)):
raise ValueError(
"Invalid keys in `{{{name}}}` [{0}], must be a subset of [{1}]"
.format(", ".join(map(str, set({{{name}}}.keys())-set(allowed_values))),
"Invalid keys in `{{{name}}}` [{0}], must be a subset of [{1}]" # noqa: E501
.format(", ".join(map(str, set({{{name}}}.keys()) - set(allowed_values))), # noqa: E501
", ".join(map(str, allowed_values)))
)
{{/isMapContainer}}
{{/isContainer}}
{{^isContainer}}
allowed_values = [{{#allowableValues}}{{#values}}{{#isString}}"{{/isString}}{{{this}}}{{#isString}}"{{/isString}}{{^-last}}, {{/-last}}{{/values}}{{/allowableValues}}]
allowed_values = [{{#allowableValues}}{{#values}}{{#isString}}"{{/isString}}{{{this}}}{{#isString}}"{{/isString}}{{^-last}}, {{/-last}}{{/values}}{{/allowableValues}}] # noqa: E501
if {{{name}}} not in allowed_values:
raise ValueError(
"Invalid value for `{{{name}}}` ({0}), must be one of {1}"
"Invalid value for `{{{name}}}` ({0}), must be one of {1}" # noqa: E501
.format({{{name}}}, allowed_values)
)
{{/isContainer}}
@@ -130,31 +134,31 @@ class {{classname}}(object):
{{#hasValidation}}
{{#maxLength}}
if {{name}} is not None and len({{name}}) > {{maxLength}}:
raise ValueError("Invalid value for `{{name}}`, length must be less than or equal to `{{maxLength}}`")
raise ValueError("Invalid value for `{{name}}`, length must be less than or equal to `{{maxLength}}`") # noqa: E501
{{/maxLength}}
{{#minLength}}
if {{name}} is not None and len({{name}}) < {{minLength}}:
raise ValueError("Invalid value for `{{name}}`, length must be greater than or equal to `{{minLength}}`")
raise ValueError("Invalid value for `{{name}}`, length must be greater than or equal to `{{minLength}}`") # noqa: E501
{{/minLength}}
{{#maximum}}
if {{name}} is not None and {{name}} >{{#exclusiveMaximum}}={{/exclusiveMaximum}} {{maximum}}:
raise ValueError("Invalid value for `{{name}}`, must be a value less than {{^exclusiveMaximum}}or equal to {{/exclusiveMaximum}}`{{maximum}}`")
if {{name}} is not None and {{name}} >{{#exclusiveMaximum}}={{/exclusiveMaximum}} {{maximum}}: # noqa: E501
raise ValueError("Invalid value for `{{name}}`, must be a value less than {{^exclusiveMaximum}}or equal to {{/exclusiveMaximum}}`{{maximum}}`") # noqa: E501
{{/maximum}}
{{#minimum}}
if {{name}} is not None and {{name}} <{{#exclusiveMinimum}}={{/exclusiveMinimum}} {{minimum}}:
raise ValueError("Invalid value for `{{name}}`, must be a value greater than {{^exclusiveMinimum}}or equal to {{/exclusiveMinimum}}`{{minimum}}`")
if {{name}} is not None and {{name}} <{{#exclusiveMinimum}}={{/exclusiveMinimum}} {{minimum}}: # noqa: E501
raise ValueError("Invalid value for `{{name}}`, must be a value greater than {{^exclusiveMinimum}}or equal to {{/exclusiveMinimum}}`{{minimum}}`") # noqa: E501
{{/minimum}}
{{#pattern}}
if {{name}} is not None and not re.search('{{{vendorExtensions.x-regex}}}', {{name}}{{#vendorExtensions.x-modifiers}}{{#-first}}, flags={{/-first}}re.{{.}}{{^-last}} | {{/-last}}{{/vendorExtensions.x-modifiers}}):
raise ValueError("Invalid value for `{{name}}`, must be a follow pattern or equal to `{{{pattern}}}`")
if {{name}} is not None and not re.search('{{{vendorExtensions.x-regex}}}', {{name}}{{#vendorExtensions.x-modifiers}}{{#-first}}, flags={{/-first}}re.{{.}}{{^-last}} | {{/-last}}{{/vendorExtensions.x-modifiers}}): # noqa: E501
raise ValueError("Invalid value for `{{name}}`, must be a follow pattern or equal to `{{{pattern}}}`") # noqa: E501
{{/pattern}}
{{#maxItems}}
if {{name}} is not None and len({{name}}) > {{maxItems}}:
raise ValueError("Invalid value for `{{name}}`, number of items must be less than or equal to `{{maxItems}}`")
raise ValueError("Invalid value for `{{name}}`, number of items must be less than or equal to `{{maxItems}}`") # noqa: E501
{{/maxItems}}
{{#minItems}}
if {{name}} is not None and len({{name}}) < {{minItems}}:
raise ValueError("Invalid value for `{{name}}`, number of items must be greater than or equal to `{{minItems}}`")
raise ValueError("Invalid value for `{{name}}`, number of items must be greater than or equal to `{{minItems}}`") # noqa: E501
{{/minItems}}
{{/hasValidation}}
{{/isEnum}}
@@ -164,23 +168,16 @@ class {{classname}}(object):
{{/vars}}
{{#discriminator}}
def get_real_child_model(self, data):
"""
Returns the real base class specified by the discriminator
"""
"""Returns the real base class specified by the discriminator"""
discriminator_value = data[self.discriminator].lower()
if self.discriminator_value_class_map.has_key(discriminator_value):
return self.discriminator_value_class_map[discriminator_value]
else:
return None
return self.discriminator_value_class_map.get(discriminator_value)
{{/discriminator}}
def to_dict(self):
"""
Returns the model properties as a dict
"""
"""Returns the model properties as a dict"""
result = {}
for attr, _ in iteritems(self.swagger_types):
for attr, _ in six.iteritems(self.swagger_types):
value = getattr(self, attr)
if isinstance(value, list):
result[attr] = list(map(
@@ -201,30 +198,22 @@ class {{classname}}(object):
return result
def to_str(self):
"""
Returns the string representation of the model
"""
return pformat(self.to_dict())
"""Returns the string representation of the model"""
return pprint.pformat(self.to_dict())
def __repr__(self):
"""
For `print` and `pprint`
"""
"""For `print` and `pprint`"""
return self.to_str()
def __eq__(self, other):
"""
Returns true if both objects are equal
"""
"""Returns true if both objects are equal"""
if not isinstance(other, {{classname}}):
return False
return self.__dict__ == other.__dict__
def __ne__(self, other):
"""
Returns true if both objects are not equal
"""
"""Returns true if both objects are not equal"""
return not self == other
{{/model}}
{{/models}}

View File

@@ -4,19 +4,17 @@
from __future__ import absolute_import
import os
import sys
import unittest
{{#models}}
{{#model}}
import {{packageName}}
from {{modelPackage}}.{{classFilename}} import {{classname}} # noqa: E501
from {{packageName}}.rest import ApiException
from {{packageName}}.models.{{classFilename}} import {{classname}}
class Test{{classname}}(unittest.TestCase):
""" {{classname}} unit test stubs """
"""{{classname}} unit test stubs"""
def setUp(self):
pass
@@ -25,11 +23,9 @@ class Test{{classname}}(unittest.TestCase):
pass
def test{{classname}}(self):
"""
Test {{classname}}
"""
"""Test {{classname}}"""
# FIXME: construct object with mandatory attributes with example values
#model = {{packageName}}.models.{{classFilename}}.{{classname}}()
# model = {{packageName}}.models.{{classFilename}}.{{classname}}() # noqa: E501
pass
{{/model}}

View File

@@ -4,7 +4,7 @@
{{/appName}}
{{#appDescription}}
{{{appDescription}}}
{{{appDescription}}} # noqa: E501
{{/appDescription}}
{{#version}}OpenAPI spec version: {{{version}}}{{/version}}

View File

@@ -6,13 +6,13 @@ from __future__ import absolute_import
import io
import json
import ssl
import certifi
import logging
import re
import ssl
import certifi
# python 2 and python 3 compatibility library
from six import PY3
import six
from six.moves.urllib.parse import urlencode
try:
@@ -33,15 +33,11 @@ class RESTResponse(io.IOBase):
self.data = resp.data
def getheaders(self):
"""
Returns a dictionary of the response headers.
"""
"""Returns a dictionary of the response headers."""
return self.urllib3_response.getheaders()
def getheader(self, name, default=None):
"""
Returns a given response header.
"""
"""Returns a given response header."""
return self.urllib3_response.getheader(name, default)
@@ -49,10 +45,10 @@ class RESTClientObject(object):
def __init__(self, configuration, pools_size=4, maxsize=None):
# urllib3.PoolManager will pass all kw parameters to connectionpool
# https://github.com/shazow/urllib3/blob/f9409436f83aeb79fbaf090181cd81b784f1b8ce/urllib3/poolmanager.py#L75
# https://github.com/shazow/urllib3/blob/f9409436f83aeb79fbaf090181cd81b784f1b8ce/urllib3/connectionpool.py#L680
# maxsize is the number of requests to host that are allowed in parallel
# Custom SSL certificates and client certificates: http://urllib3.readthedocs.io/en/latest/advanced-usage.html
# https://github.com/shazow/urllib3/blob/f9409436f83aeb79fbaf090181cd81b784f1b8ce/urllib3/poolmanager.py#L75 # noqa: E501
# https://github.com/shazow/urllib3/blob/f9409436f83aeb79fbaf090181cd81b784f1b8ce/urllib3/connectionpool.py#L680 # noqa: E501
# maxsize is the number of requests to host that are allowed in parallel # noqa: E501
# Custom SSL certificates and client certificates: http://urllib3.readthedocs.io/en/latest/advanced-usage.html # noqa: E501
# cert_reqs
if configuration.verify_ssl:
@@ -69,7 +65,7 @@ class RESTClientObject(object):
addition_pool_args = {}
if configuration.assert_hostname is not None:
addition_pool_args['assert_hostname'] = configuration.assert_hostname
addition_pool_args['assert_hostname'] = configuration.assert_hostname # noqa: E501
if maxsize is None:
if configuration.connection_pool_maxsize is not None:
@@ -101,8 +97,10 @@ class RESTClientObject(object):
)
def request(self, method, url, query_params=None, headers=None,
body=None, post_params=None, _preload_content=True, _request_timeout=None):
"""
body=None, post_params=None, _preload_content=True,
_request_timeout=None):
"""Perform requests.
:param method: http request method
:param url: http request url
:param query_params: query parameters in the url
@@ -111,13 +109,17 @@ class RESTClientObject(object):
:param post_params: request post parameters,
`application/x-www-form-urlencoded`
and `multipart/form-data`
:param _preload_content: if False, the urllib3.HTTPResponse object will be returned without
reading/decoding response data. Default is True.
:param _request_timeout: timeout setting for this request. If one number provided, it will be total request
timeout. It can also be a pair (tuple) of (connection, read) timeouts.
:param _preload_content: if False, the urllib3.HTTPResponse object will
be returned without reading/decoding response
data. Default is True.
:param _request_timeout: timeout setting for this request. If one
number provided, it will be total request
timeout. It can also be a pair (tuple) of
(connection, read) timeouts.
"""
method = method.upper()
assert method in ['GET', 'HEAD', 'DELETE', 'POST', 'PUT', 'PATCH', 'OPTIONS']
assert method in ['GET', 'HEAD', 'DELETE', 'POST', 'PUT',
'PATCH', 'OPTIONS']
if post_params and body:
raise ValueError(
@@ -129,10 +131,12 @@ class RESTClientObject(object):
timeout = None
if _request_timeout:
if isinstance(_request_timeout, (int, ) if PY3 else (int, long)):
if isinstance(_request_timeout, (int, ) if six.PY3 else (int, long)): # noqa: E501,F821
timeout = urllib3.Timeout(total=_request_timeout)
elif isinstance(_request_timeout, tuple) and len(_request_timeout) == 2:
timeout = urllib3.Timeout(connect=_request_timeout[0], read=_request_timeout[1])
elif (isinstance(_request_timeout, tuple) and
len(_request_timeout) == 2):
timeout = urllib3.Timeout(
connect=_request_timeout[0], read=_request_timeout[1])
if 'Content-Type' not in headers:
headers['Content-Type'] = 'application/json'
@@ -146,42 +150,48 @@ class RESTClientObject(object):
request_body = None
if body is not None:
request_body = json.dumps(body)
r = self.pool_manager.request(method, url,
body=request_body,
preload_content=_preload_content,
timeout=timeout,
headers=headers)
elif headers['Content-Type'] == 'application/x-www-form-urlencoded':
r = self.pool_manager.request(method, url,
fields=post_params,
encode_multipart=False,
preload_content=_preload_content,
timeout=timeout,
headers=headers)
r = self.pool_manager.request(
method, url,
body=request_body,
preload_content=_preload_content,
timeout=timeout,
headers=headers)
elif headers['Content-Type'] == 'application/x-www-form-urlencoded': # noqa: E501
r = self.pool_manager.request(
method, url,
fields=post_params,
encode_multipart=False,
preload_content=_preload_content,
timeout=timeout,
headers=headers)
elif headers['Content-Type'] == 'multipart/form-data':
# must del headers['Content-Type'], or the correct Content-Type
# which generated by urllib3 will be overwritten.
# must del headers['Content-Type'], or the correct
# Content-Type which generated by urllib3 will be
# overwritten.
del headers['Content-Type']
r = self.pool_manager.request(method, url,
fields=post_params,
encode_multipart=True,
preload_content=_preload_content,
timeout=timeout,
headers=headers)
r = self.pool_manager.request(
method, url,
fields=post_params,
encode_multipart=True,
preload_content=_preload_content,
timeout=timeout,
headers=headers)
# Pass a `string` parameter directly in the body to support
# other content types than Json when `body` argument is provided
# in serialized form
# other content types than Json when `body` argument is
# provided in serialized form
elif isinstance(body, str):
request_body = body
r = self.pool_manager.request(method, url,
body=request_body,
preload_content=_preload_content,
timeout=timeout,
headers=headers)
r = self.pool_manager.request(
method, url,
body=request_body,
preload_content=_preload_content,
timeout=timeout,
headers=headers)
else:
# Cannot generate the request from given parameters
msg = """Cannot prepare a request message for provided arguments.
Please check that your arguments match declared content type."""
msg = """Cannot prepare a request message for provided
arguments. Please check that your arguments match
declared content type."""
raise ApiException(status=0, reason=msg)
# For `GET`, `HEAD`
else:
@@ -199,7 +209,7 @@ class RESTClientObject(object):
# In the python 3, the response.data is bytes.
# we need to decode it to string.
if PY3:
if six.PY3:
r.data = r.data.decode('utf8')
# log response body
@@ -210,22 +220,24 @@ class RESTClientObject(object):
return r
def GET(self, url, headers=None, query_params=None, _preload_content=True, _request_timeout=None):
def GET(self, url, headers=None, query_params=None, _preload_content=True,
_request_timeout=None):
return self.request("GET", url,
headers=headers,
_preload_content=_preload_content,
_request_timeout=_request_timeout,
query_params=query_params)
def HEAD(self, url, headers=None, query_params=None, _preload_content=True, _request_timeout=None):
def HEAD(self, url, headers=None, query_params=None, _preload_content=True,
_request_timeout=None):
return self.request("HEAD", url,
headers=headers,
_preload_content=_preload_content,
_request_timeout=_request_timeout,
query_params=query_params)
def OPTIONS(self, url, headers=None, query_params=None, post_params=None, body=None, _preload_content=True,
_request_timeout=None):
def OPTIONS(self, url, headers=None, query_params=None, post_params=None,
body=None, _preload_content=True, _request_timeout=None):
return self.request("OPTIONS", url,
headers=headers,
query_params=query_params,
@@ -234,7 +246,8 @@ class RESTClientObject(object):
_request_timeout=_request_timeout,
body=body)
def DELETE(self, url, headers=None, query_params=None, body=None, _preload_content=True, _request_timeout=None):
def DELETE(self, url, headers=None, query_params=None, body=None,
_preload_content=True, _request_timeout=None):
return self.request("DELETE", url,
headers=headers,
query_params=query_params,
@@ -242,8 +255,8 @@ class RESTClientObject(object):
_request_timeout=_request_timeout,
body=body)
def POST(self, url, headers=None, query_params=None, post_params=None, body=None, _preload_content=True,
_request_timeout=None):
def POST(self, url, headers=None, query_params=None, post_params=None,
body=None, _preload_content=True, _request_timeout=None):
return self.request("POST", url,
headers=headers,
query_params=query_params,
@@ -252,8 +265,8 @@ class RESTClientObject(object):
_request_timeout=_request_timeout,
body=body)
def PUT(self, url, headers=None, query_params=None, post_params=None, body=None, _preload_content=True,
_request_timeout=None):
def PUT(self, url, headers=None, query_params=None, post_params=None,
body=None, _preload_content=True, _request_timeout=None):
return self.request("PUT", url,
headers=headers,
query_params=query_params,
@@ -262,8 +275,8 @@ class RESTClientObject(object):
_request_timeout=_request_timeout,
body=body)
def PATCH(self, url, headers=None, query_params=None, post_params=None, body=None, _preload_content=True,
_request_timeout=None):
def PATCH(self, url, headers=None, query_params=None, post_params=None,
body=None, _preload_content=True, _request_timeout=None):
return self.request("PATCH", url,
headers=headers,
query_params=query_params,
@@ -288,13 +301,12 @@ class ApiException(Exception):
self.headers = None
def __str__(self):
"""
Custom error messages for exception
"""
"""Custom error messages for exception"""
error_message = "({0})\n"\
"Reason: {1}\n".format(self.status, self.reason)
if self.headers:
error_message += "HTTP response headers: {0}\n".format(self.headers)
error_message += "HTTP response headers: {0}\n".format(
self.headers)
if self.body:
error_message += "HTTP response body: {0}\n".format(self.body)

View File

@@ -2,8 +2,7 @@
{{>partial_header}}
import sys
from setuptools import setup, find_packages
from setuptools import setup, find_packages # noqa: H301
NAME = "{{{projectName}}}"
VERSION = "{{packageVersion}}"
@@ -36,7 +35,7 @@ setup(
packages=find_packages(),
include_package_data=True,
long_description="""\
{{appDescription}}
{{appDescription}} # noqa: E501
"""
)
{{/hasMore}}

View File

@@ -4,17 +4,16 @@
import io
import json
import ssl
import certifi
import logging
import re
import ssl
import certifi
# python 2 and python 3 compatibility library
from six.moves.urllib.parse import urlencode
import tornado
import tornado.gen
from tornado.httpclient import AsyncHTTPClient, HTTPRequest
# python 2 and python 3 compatibility library
from six import PY3
from six.moves.urllib.parse import urlencode
from tornado import httpclient
from urllib3.filepost import encode_multipart_formdata
logger = logging.getLogger(__name__)
@@ -29,22 +28,18 @@ class RESTResponse(io.IOBase):
self.data = data
def getheaders(self):
"""
Returns a CIMultiDictProxy of the response headers.
"""
"""Returns a CIMultiDictProxy of the response headers."""
return self.tornado_response.headers
def getheader(self, name, default=None):
"""
Returns a given response header.
"""
"""Returns a given response header."""
return self.tornado_response.headers.get(name, default)
class RESTClientObject:
class RESTClientObject(object):
def __init__(self, configuration, pools_size=4, maxsize=4):
# maxsize is the number of requests to host that are allowed in parallel
# maxsize is number of requests to host that are allowed in parallel
# ca_certs vs cert_file vs key_file
# http://stackoverflow.com/a/23957365/2985775
@@ -55,9 +50,10 @@ class RESTClientObject:
# if not set certificate file, use Mozilla's root certificates.
ca_certs = certifi.where()
self.ssl_context = ssl_context = ssl.SSLContext()
self.ssl_context = ssl.SSLContext()
self.ssl_context.load_verify_locations(cafile=ca_certs)
if configuration.cert_file:
ssl_context.load_cert_chain(
self.ssl_context.load_cert_chain(
configuration.cert_file, keyfile=configuration.key_file
)
@@ -68,12 +64,14 @@ class RESTClientObject:
self.proxy_port = 80
self.proxy_host = configuration.proxy
self.pool_manager = AsyncHTTPClient()
self.pool_manager = httpclient.AsyncHTTPClient()
@tornado.gen.coroutine
def request(self, method, url, query_params=None, headers=None,
body=None, post_params=None, _preload_content=True, _request_timeout=None):
"""
def request(self, method, url, query_params=None, headers=None, body=None,
post_params=None, _preload_content=True,
_request_timeout=None):
"""Execute Request
:param method: http request method
:param url: http request url
:param query_params: query parameters in the url
@@ -82,19 +80,23 @@ class RESTClientObject:
:param post_params: request post parameters,
`application/x-www-form-urlencoded`
and `multipart/form-data`
:param _preload_content: this is a non-applicable field for the AiohttpClient.
:param _request_timeout: timeout setting for this request. If one number provided, it will be total request
timeout. It can also be a pair (tuple) of (connection, read) timeouts.
:param _preload_content: this is a non-applicable field for
the AiohttpClient.
:param _request_timeout: timeout setting for this request. If one
number provided, it will be total request
timeout. It can also be a pair (tuple) of
(connection, read) timeouts.
"""
method = method.upper()
assert method in ['GET', 'HEAD', 'DELETE', 'POST', 'PUT', 'PATCH', 'OPTIONS']
assert method in ['GET', 'HEAD', 'DELETE', 'POST', 'PUT',
'PATCH', 'OPTIONS']
if post_params and body:
raise ValueError(
"body parameter cannot be used with post_params parameter."
)
request = HTTPRequest(url)
request = httpclient.HTTPRequest(url)
request.ssl_context = self.ssl_context
request.proxy_host = self.proxy_host
request.proxy_port = self.proxy_port
@@ -105,7 +107,6 @@ class RESTClientObject:
request.headers['Content-Type'] = 'application/json'
request.request_timeout = _request_timeout or 5 * 60
post_params = post_params or {}
if query_params:
@@ -117,9 +118,8 @@ class RESTClientObject:
if body:
body = json.dumps(body)
request.body = body
elif headers['Content-Type'] == 'application/x-www-form-urlencoded':
elif headers['Content-Type'] == 'application/x-www-form-urlencoded': # noqa: E501
request.body = urlencode(post_params)
# TODO: transform to multipart form
elif headers['Content-Type'] == 'multipart/form-data':
request.body = encode_multipart_formdata(post_params)
# Pass a `bytes` parameter directly in the body to support
@@ -129,8 +129,9 @@ class RESTClientObject:
request.body = body
else:
# Cannot generate the request from given parameters
msg = """Cannot prepare a request message for provided arguments.
Please check that your arguments match declared content type."""
msg = """Cannot prepare a request message for provided
arguments. Please check that your arguments match
declared content type."""
raise ApiException(status=0, reason=msg)
r = yield self.pool_manager.fetch(request)
@@ -142,40 +143,41 @@ class RESTClientObject:
if not 200 <= r.status <= 299:
raise ApiException(http_resp=r)
return r
@tornado.gen.coroutine
def GET(self, url, headers=None, query_params=None, _preload_content=True, _request_timeout=None):
def GET(self, url, headers=None, query_params=None, _preload_content=True,
_request_timeout=None):
result = yield self.request("GET", url,
headers=headers,
_preload_content=_preload_content,
_request_timeout=_request_timeout,
query_params=query_params)
headers=headers,
_preload_content=_preload_content,
_request_timeout=_request_timeout,
query_params=query_params)
raise tornado.gen.Return(result)
@tornado.gen.coroutine
def HEAD(self, url, headers=None, query_params=None, _preload_content=True, _request_timeout=None):
def HEAD(self, url, headers=None, query_params=None, _preload_content=True,
_request_timeout=None):
result = yield self.request("HEAD", url,
headers=headers,
_preload_content=_preload_content,
_request_timeout=_request_timeout,
query_params=query_params)
headers=headers,
_preload_content=_preload_content,
_request_timeout=_request_timeout,
query_params=query_params)
raise tornado.gen.Return(result)
@tornado.gen.coroutine
def OPTIONS(self, url, headers=None, query_params=None, post_params=None, body=None, _preload_content=True,
_request_timeout=None):
def OPTIONS(self, url, headers=None, query_params=None, post_params=None,
body=None, _preload_content=True, _request_timeout=None):
result = yield self.request("OPTIONS", url,
headers=headers,
query_params=query_params,
post_params=post_params,
_preload_content=_preload_content,
_request_timeout=_request_timeout,
body=body)
headers=headers,
query_params=query_params,
post_params=post_params,
_preload_content=_preload_content,
_request_timeout=_request_timeout,
body=body)
raise tornado.gen.Return(result)
@tornado.gen.coroutine
def DELETE(self, url, headers=None, query_params=None, body=None, _preload_content=True, _request_timeout=None):
def DELETE(self, url, headers=None, query_params=None, body=None,
_preload_content=True, _request_timeout=None):
result = yield self.request("DELETE", url,
headers=headers,
query_params=query_params,
@@ -185,39 +187,39 @@ class RESTClientObject:
raise tornado.gen.Return(result)
@tornado.gen.coroutine
def POST(self, url, headers=None, query_params=None, post_params=None, body=None, _preload_content=True,
_request_timeout=None):
def POST(self, url, headers=None, query_params=None, post_params=None,
body=None, _preload_content=True, _request_timeout=None):
result = yield self.request("POST", url,
headers=headers,
query_params=query_params,
post_params=post_params,
_preload_content=_preload_content,
_request_timeout=_request_timeout,
body=body)
headers=headers,
query_params=query_params,
post_params=post_params,
_preload_content=_preload_content,
_request_timeout=_request_timeout,
body=body)
raise tornado.gen.Return(result)
@tornado.gen.coroutine
def PUT(self, url, headers=None, query_params=None, post_params=None, body=None, _preload_content=True,
_request_timeout=None):
def PUT(self, url, headers=None, query_params=None, post_params=None,
body=None, _preload_content=True, _request_timeout=None):
result = yield self.request("PUT", url,
headers=headers,
query_params=query_params,
post_params=post_params,
_preload_content=_preload_content,
_request_timeout=_request_timeout,
body=body)
headers=headers,
query_params=query_params,
post_params=post_params,
_preload_content=_preload_content,
_request_timeout=_request_timeout,
body=body)
raise tornado.gen.Return(result)
@tornado.gen.coroutine
def PATCH(self, url, headers=None, query_params=None, post_params=None, body=None, _preload_content=True,
_request_timeout=None):
def PATCH(self, url, headers=None, query_params=None, post_params=None,
body=None, _preload_content=True, _request_timeout=None):
result = yield self.request("PATCH", url,
headers=headers,
query_params=query_params,
post_params=post_params,
_preload_content=_preload_content,
_request_timeout=_request_timeout,
body=body)
headers=headers,
query_params=query_params,
post_params=post_params,
_preload_content=_preload_content,
_request_timeout=_request_timeout,
body=body)
raise tornado.gen.Return(result)
@@ -236,13 +238,12 @@ class ApiException(Exception):
self.headers = None
def __str__(self):
"""
Custom error messages for exception
"""
error_message = "({0})\n"\
"Reason: {1}\n".format(self.status, self.reason)
"""Custom error messages for exception"""
error_message = "({0})\nReason: {1}\n".format(
self.status, self.reason)
if self.headers:
error_message += "HTTP response headers: {0}\n".format(self.headers)
error_message += "HTTP response headers: {0}\n".format(
self.headers)
if self.body:
error_message += "HTTP response body: {0}\n".format(self.body)