Merge branch 'develop_2.0' into python-enum

This commit is contained in:
geekerzp
2015-07-16 17:27:17 +08:00
126 changed files with 2795 additions and 2518 deletions
@@ -8,3 +8,7 @@ from __future__ import absolute_import
{{/apis}}{{/apiInfo}}
# import ApiClient
from .api_client import ApiClient
from .configuration import Configuration
configuration = Configuration()
@@ -27,19 +27,20 @@ import os
# python 2 and python 3 compatibility library
from six import iteritems
from .. import configuration
from ..configuration import Configuration
from ..api_client import ApiClient
{{#operations}}
class {{classname}}(object):
def __init__(self, api_client=None):
config = Configuration()
if api_client:
self.api_client = api_client
else:
if not configuration.api_client:
configuration.api_client = ApiClient('{{basePath}}')
self.api_client = configuration.api_client
if not config.api_client:
config.api_client = ApiClient('{{basePath}}')
self.api_client = config.api_client
{{#operation}}
def {{nickname}}(self, {{#allParams}}{{#required}}{{paramName}}, {{/required}}{{/allParams}}**kwargs):
@@ -47,15 +48,25 @@ class {{classname}}(object):
{{{summary}}}
{{{notes}}}
{{#allParams}}:param {{dataType}} {{paramName}}: {{{description}}} {{#required}}(required){{/required}}{{^required}}(optional){{/required}}
SDK also supports asynchronous requests in which you can define a `callback` function
to be passed along and invoked when receiving response:
>>> def callback_function(response):
>>> pprint(response)
>>>
>>> thread = api.{{nickname}}({{#allParams}}{{#required}}{{paramName}}, {{/required}}{{/allParams}}callback=callback_function)
:param callback function: The callback function for asynchronous request. (optional)
{{#allParams}}:param {{dataType}} {{paramName}}: {{{description}}} {{#required}}(required){{/required}}{{#optional}}(optional){{/optional}}
{{/allParams}}
:return: {{#returnType}}{{returnType}}{{/returnType}}{{^returnType}}None{{/returnType}}
If the method is called asynchronously, returns the request thread.
"""
{{#allParams}}{{#required}}# verify the required parameter '{{paramName}}' is set
if {{paramName}} is None:
raise ValueError("Missing the required parameter `{{paramName}}` when calling `{{nickname}}`")
{{/required}}{{/allParams}}
all_params = [{{#allParams}}'{{paramName}}'{{#hasMore}}, {{/hasMore}}{{/allParams}}]
all_params.append('callback')
params = locals()
for key, val in iteritems(params['kwargs']):
@@ -106,17 +117,7 @@ class {{classname}}(object):
response = self.api_client.call_api(resource_path, method, path_params, query_params, header_params,
body=body_params, post_params=form_params, files=files,
response_type={{#returnType}}'{{returnType}}'{{/returnType}}{{^returnType}}None{{/returnType}}, auth_settings=auth_settings)
{{#returnType}}
response_type={{#returnType}}'{{returnType}}'{{/returnType}}{{^returnType}}None{{/returnType}}, auth_settings=auth_settings, callback=params.get('callback'))
return response
{{/returnType}}{{/operation}}
{{/operation}}
{{/operations}}
@@ -15,10 +15,13 @@ import os
import re
import urllib
import json
import datetime
import mimetypes
import random
import tempfile
import threading
from datetime import datetime
from datetime import date
# python 2 and python 3 compatibility library
from six import iteritems
@@ -30,7 +33,7 @@ except ImportError:
# for python2
from urllib import quote
from . import configuration
from .configuration import Configuration
class ApiClient(object):
"""
@@ -40,7 +43,7 @@ class ApiClient(object):
: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 the API
"""
def __init__(self, host=configuration.host, header_name=None, header_value=None):
def __init__(self, host=Configuration().host, header_name=None, header_value=None):
self.default_headers = {}
if header_name is not None:
self.default_headers[header_name] = header_value
@@ -60,8 +63,8 @@ class ApiClient(object):
def set_default_header(self, header_name, header_value):
self.default_headers[header_name] = header_value
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):
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, callback=None):
# headers parameters
header_params = header_params or {}
@@ -106,9 +109,14 @@ class ApiClient(object):
# deserialize response data
if response_type:
return self.deserialize(response_data, response_type)
deserialized_data = self.deserialize(response_data, response_type)
else:
return None
deserialized_data = None
if callback:
callback(deserialized_data)
else:
return deserialized_data
def to_path_value(self, obj):
"""
@@ -140,7 +148,7 @@ class ApiClient(object):
return obj
elif isinstance(obj, list):
return [self.sanitize_for_serialization(sub_obj) for sub_obj in obj]
elif isinstance(obj, (datetime.datetime, datetime.date)):
elif isinstance(obj, (datetime, date)):
return obj.isoformat()
else:
if isinstance(obj, dict):
@@ -197,7 +205,7 @@ class ApiClient(object):
# convert str to class
# for native types
if klass in ['int', 'float', 'str', 'bool', 'datetime', "object"]:
if klass in ['int', 'float', 'str', 'bool', "date", 'datetime', "object"]:
klass = eval(klass)
# for model types
else:
@@ -207,12 +215,54 @@ class ApiClient(object):
return self.__deserialize_primitive(data, klass)
elif klass == object:
return self.__deserialize_object()
elif klass == date:
return self.__deserialize_date(data)
elif klass == datetime:
return self.__deserialize_datatime(data)
else:
return self.__deserialize_model(data, klass)
def request(self, method, url, query_params=None, headers=None, post_params=None, body=None):
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, callback=None):
"""
Perform http request and return deserialized data
:param resource_path: Path to method endpoint.
:param method: Method to call.
:param path_params: Path parameters in the url.
:param query_params: Query parameters in the url.
:param header_params: Header parameters to be placed in the request header.
:param body: Request body.
:param post_params dict: Request post form parameters, for `application/x-www-form-urlencoded`, `multipart/form-data`.
:param auth_settings list: Auth Settings names for the request.
:param response: Response data type.
:param files dict: key -> filename, value -> filepath, for `multipart/form-data`.
:param callback function: Callback function for asynchronous request.
If provide this parameter, the request will be called asynchronously.
:return:
If provide parameter callback, the request will be called asynchronously.
The method will return the request thread.
If parameter callback is None, then the method will return the response directly.
"""
if callback is None:
return self.__call_api(resource_path, method,
path_params, query_params, header_params,
body, post_params, files,
response_type, auth_settings, callback)
else:
thread = threading.Thread(target=self.__call_api,
args=(resource_path, method,
path_params, query_params, header_params,
body, post_params, files,
response_type, auth_settings, callback))
thread.start()
return thread
def request(self, method, url, query_params=None, headers=None,
post_params=None, body=None):
"""
Perform http request using RESTClient.
"""
@@ -280,11 +330,13 @@ class ApiClient(object):
"""
Update header and query params based on authentication setting
"""
config = Configuration()
if not auth_settings:
return
for auth in auth_settings:
auth_setting = configuration.auth_settings().get(auth)
auth_setting = config.auth_settings().get(auth)
if auth_setting:
if auth_setting['in'] == 'header':
headers[auth_setting['key']] = auth_setting['value']
@@ -338,6 +390,21 @@ class ApiClient(object):
"""
return object()
def __deserialize_date(self, string):
"""
Deserialize string to date
:param string: str
:return: date
"""
try:
from dateutil.parser import parse
return parse(string).date()
except ImportError:
return string
except ValueError:
raise ApiException(status=0, reason="Failed to parse `{0}` into a date object".format(string))
def __deserialize_datatime(self, string):
"""
Deserialize string to datetime.
@@ -1,52 +1,121 @@
from __future__ import absolute_import
import base64
import urllib3
import httplib
import sys
import logging
def get_api_key_with_prefix(key):
global api_key
global api_key_prefix
def singleton(cls, *args, **kw):
instances = {}
if api_key.get(key) and api_key_prefix.get(key):
return api_key_prefix[key] + ' ' + api_key[key]
elif api_key.get(key):
return api_key[key]
def _singleton():
if cls not in instances:
instances[cls] = cls(*args, **kw)
return instances[cls]
return _singleton
def get_basic_auth_token():
global username
global password
return urllib3.util.make_headers(basic_auth=username + ':' + password).get('authorization')
@singleton
class Configuration(object):
def auth_settings():
return { {{#authMethods}}{{#isApiKey}}
'{{name}}': {
'type': 'api_key',
'in': {{#isKeyInHeader}}'header'{{/isKeyInHeader}}{{#isKeyInQuery}}'query'{{/isKeyInQuery}},
'key': '{{keyParamName}}',
'value': get_api_key_with_prefix('{{keyParamName}}')
},
{{/isApiKey}}{{#isBasic}}
'{{name}}': {
'type': 'basic',
'in': 'header',
'key': 'Authorization',
'value': get_basic_auth_token()
},
{{/isBasic}}{{/authMethods}}
}
def __init__(self):
# Default Base url
self.host = "{{basePath}}"
# Default api client
self.api_client = None
# Authentication Settings
self.api_key = {}
self.api_key_prefix = {}
self.username = ""
self.password = ""
# Logging Settings
self.logging_format = '%(asctime)s %(levelname)s %(message)s'
self.__logging_file = None
self.__debug = False
self.init_logger()
# Default Base url
host = "{{basePath}}"
def init_logger(self):
self.logger = logging.getLogger()
formatter = logging.Formatter(self.logging_format)
stream_handler = logging.StreamHandler()
stream_handler.setFormatter(formatter)
self.logger.addHandler(stream_handler)
if self.__debug:
self.logger.setLevel(logging.DEBUG)
else:
self.logger.setLevel(logging.WARNING)
if self.__logging_file:
file_handler = logging.FileHandler(self.__logging_file)
file_handler.setFormatter(formatter)
self.logger.addFilter(file_handler)
@property
def logging_file(self):
return self.__logging_file
@logging_file.setter
def logging_file(self, value):
self.__logging_file = value
if self.__logging_file:
formater = logging.Formatter(self.logging_format)
file_handler = logging.FileHandler(self.__logging_file)
file_handler.setFormatter(formater)
self.logger.addHandler(file_handler)
@property
def debug(self):
return self.__debug
@debug.setter
def debug(self, value):
self.__debug = value
if self.__debug:
# if debug status is True, turn on debug logging
self.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`
self.logger.setLevel(logging.WARNING)
def get_api_key_with_prefix(self, key):
""" Return api key prepend prefix for key """
if self.api_key.get(key) and self.api_key_prefix.get(key):
return self.api_key_prefix[key] + ' ' + self.api_key[key]
elif self.api_key.get(key):
return self.api_key[key]
def get_basic_auth_token(self):
""" Return basic auth header string """
return urllib3.util.make_headers(basic_auth=self.username + ':' + self.password)\
.get('authorization')
def auth_settings(self):
""" Return Auth Settings for api client """
return { {{#authMethods}}{{#isApiKey}}
'{{name}}': {
'type': 'api_key',
'in': {{#isKeyInHeader}}'header'{{/isKeyInHeader}}{{#isKeyInQuery}}'query'{{/isKeyInQuery}},
'key': '{{keyParamName}}',
'value': self.get_api_key_with_prefix('{{keyParamName}}')
},
{{/isApiKey}}{{#isBasic}}
'{{name}}': {
'type': 'basic',
'in': 'header',
'key': 'Authorization',
'value': self.get_basic_auth_token()
},
{{/isBasic}}{{/authMethods}}
}
def to_debug_report(self):
return "Python SDK Debug Report:\n"\
"OS: {env}\n"\
"Python Version: {pyversion}\n"\
"Version of the API: {{version}}\n"\
"SDK Package Version: {{packageVersion}}".format(env=sys.platform, pyversion=sys.version)
# Default api client
api_client = None
# Authentication settings
api_key = {}
api_key_prefix = {}
username = ''
password = ''
# Temp foloder for file download
temp_folder_path = None
@@ -10,6 +10,7 @@ import io
import json
import ssl
import certifi
import logging
# python 2 and python 3 compatibility library
from six import iteritems
@@ -27,6 +28,9 @@ except ImportError:
from urllib import urlencode
logger = logging.getLogger(__name__)
class RESTResponse(io.IOBase):
def __init__(self, resp):
@@ -65,9 +69,10 @@ class RESTClientObject(object):
def agent(self, url):
"""
Return proper pool manager for the http\https schemes.
Use `urllib3.util.parse_url` for backward compatibility.
Return proper pool manager for the http/https schemes.
"""
url = urllib3.util.url.parse_url(url)
url = urllib3.util.parse_url(url)
scheme = url.scheme
if scheme == 'https':
return self.ssl_pool_manager
@@ -130,6 +135,9 @@ class RESTClientObject(object):
if sys.version_info > (3,):
r.data = r.data.decode('utf8')
# log response body
logger.debug("response body: %s" % r.data)
if r.status not in range(200, 206):
raise ApiException(http_resp=r)