diff --git a/modules/swagger-codegen/src/main/java/com/wordnik/swagger/codegen/languages/PythonClientCodegen.java b/modules/swagger-codegen/src/main/java/com/wordnik/swagger/codegen/languages/PythonClientCodegen.java index 88da69389518..7896bf668786 100755 --- a/modules/swagger-codegen/src/main/java/com/wordnik/swagger/codegen/languages/PythonClientCodegen.java +++ b/modules/swagger-codegen/src/main/java/com/wordnik/swagger/codegen/languages/PythonClientCodegen.java @@ -34,13 +34,12 @@ public class PythonClientCodegen extends DefaultCodegen implements CodegenConfig apiTemplateFiles.put("api.mustache", ".py"); templateDir = "python"; - apiPackage = invokerPackage; + apiPackage = invokerPackage + ".apis"; modelPackage = invokerPackage + ".models"; languageSpecificPrimitives.clear(); languageSpecificPrimitives.add("int"); languageSpecificPrimitives.add("float"); - languageSpecificPrimitives.add("long"); languageSpecificPrimitives.add("list"); languageSpecificPrimitives.add("bool"); languageSpecificPrimitives.add("str"); @@ -49,7 +48,7 @@ public class PythonClientCodegen extends DefaultCodegen implements CodegenConfig typeMapping.clear(); typeMapping.put("integer", "int"); typeMapping.put("float", "float"); - typeMapping.put("long", "long"); + typeMapping.put("long", "int"); typeMapping.put("double", "float"); typeMapping.put("array", "list"); typeMapping.put("map", "map"); @@ -70,8 +69,11 @@ public class PythonClientCodegen extends DefaultCodegen implements CodegenConfig supportingFiles.add(new SupportingFile("README.mustache", eggPackage, "README.md")); supportingFiles.add(new SupportingFile("setup.mustache", eggPackage, "setup.py")); supportingFiles.add(new SupportingFile("swagger.mustache", invokerPackage, "swagger.py")); + supportingFiles.add(new SupportingFile("rest.mustache", invokerPackage, "rest.py")); + supportingFiles.add(new SupportingFile("util.mustache", invokerPackage, "util.py")); supportingFiles.add(new SupportingFile("__init__package.mustache", invokerPackage, "__init__.py")); supportingFiles.add(new SupportingFile("__init__model.mustache", modelPackage.replace('.', File.separatorChar), "__init__.py")); + supportingFiles.add(new SupportingFile("__init__api.mustache", apiPackage.replace('.', File.separatorChar), "__init__.py")); } @Override diff --git a/modules/swagger-codegen/src/main/resources/python/README.mustache b/modules/swagger-codegen/src/main/resources/python/README.mustache index 3b69aba0f82d..9c590a9a5088 100644 --- a/modules/swagger-codegen/src/main/resources/python/README.mustache +++ b/modules/swagger-codegen/src/main/resources/python/README.mustache @@ -38,5 +38,37 @@ TODO ## Tests -TODO +(Make sure you are running it inside of a [virtualenv](http://docs.python-guide.org/en/latest/dev/virtualenvs/)) + +You can run the tests in the current python platform: + +```sh +$ make test +[... magically installs dependencies and runs tests on your virtualenv] +Ran 7 tests in 19.289s + +OK +``` +or + +``` +$ mvn integration-test -rf :PythonPetstoreClientTests +Using 2195432783 as seed +[INFO] ------------------------------------------------------------------------ +[INFO] BUILD SUCCESS +[INFO] ------------------------------------------------------------------------ +[INFO] Total time: 37.594 s +[INFO] Finished at: 2015-05-16T18:00:35+08:00 +[INFO] Final Memory: 11M/156M +[INFO] ------------------------------------------------------------------------ +``` +If you want to run the tests in all the python platforms: + +```sh +$ make test-all +[... tox creates a virtualenv for every platform and runs tests inside of each] + py27: commands succeeded + py34: commands succeeded + congratulations :) +``` diff --git a/modules/swagger-codegen/src/main/resources/python/__init__api.mustache b/modules/swagger-codegen/src/main/resources/python/__init__api.mustache new file mode 100644 index 000000000000..b4442b736ff4 --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/python/__init__api.mustache @@ -0,0 +1,5 @@ +from __future__ import absolute_import + +# import apis into api package +{{#apiInfo}}{{#apis}}from .{{classVarName}} import {{classname}} +{{/apis}}{{/apiInfo}} diff --git a/modules/swagger-codegen/src/main/resources/python/__init__model.mustache b/modules/swagger-codegen/src/main/resources/python/__init__model.mustache index 93d18228d252..7a3f1866ea73 100644 --- a/modules/swagger-codegen/src/main/resources/python/__init__model.mustache +++ b/modules/swagger-codegen/src/main/resources/python/__init__model.mustache @@ -1,13 +1,5 @@ -#!/usr/bin/env python -"""Add all of the modules in the current directory to __all__""" -import os +from __future__ import absolute_import -{{#models}}{{#model}} -from .{{classVarName}} import {{classname}} +# import models into model package +{{#models}}{{#model}}from .{{classVarName}} import {{classname}} {{/model}}{{/models}} - -__all__ = [] - -for module in os.listdir(os.path.dirname(__file__)): - if module != '__init__.py' and module[-3:] == '.py': - __all__.append(module[:-3]) diff --git a/modules/swagger-codegen/src/main/resources/python/__init__package.mustache b/modules/swagger-codegen/src/main/resources/python/__init__package.mustache index e88c5f01ee23..7b48136d3a9d 100644 --- a/modules/swagger-codegen/src/main/resources/python/__init__package.mustache +++ b/modules/swagger-codegen/src/main/resources/python/__init__package.mustache @@ -1,22 +1,10 @@ -#!/usr/bin/env python -"""Add all of the modules in the current directory to __all__""" -import os +from __future__ import absolute_import -# import models into package -{{#models}}{{#model}} -from .models.{{classVarName}} import {{classname}} +# import models into sdk package +{{#models}}{{#model}}from .models.{{classVarName}} import {{classname}} {{/model}}{{/models}} - -# import apis into package -{{#apiInfo}}{{#apis}} -from .{{classVarName}} import {{classname}} +# import apis into sdk package +{{#apiInfo}}{{#apis}}from .apis.{{classVarName}} import {{classname}} {{/apis}}{{/apiInfo}} - # import ApiClient from .swagger import ApiClient - -__all__ = [] - -for module in os.listdir(os.path.dirname(__file__)): - if module != '__init__.py' and module[-3:] == '.py': - __all__.append(module[:-3]) diff --git a/modules/swagger-codegen/src/main/resources/python/api.mustache b/modules/swagger-codegen/src/main/resources/python/api.mustache index ba17e6993a2c..b853cbc9c950 100644 --- a/modules/swagger-codegen/src/main/resources/python/api.mustache +++ b/modules/swagger-codegen/src/main/resources/python/api.mustache @@ -19,100 +19,74 @@ Copyright 2015 Reverb Technologies, Inc. NOTE: This class is auto generated by the swagger code generator program. Do not edit the class manually. """ +from __future__ import absolute_import + import sys import os -import urllib -from models import * +# python 2 and python 3 compatibility library +from six import iteritems +from ..util import remove_none {{#operations}} class {{classname}}(object): - def __init__(self, apiClient): - self.apiClient = apiClient - - {{newline}} + def __init__(self, api_client): + self.api_client = api_client {{#operation}} - def {{nickname}}(self, {{#requiredParams}}{{paramName}}{{#defaultValue}} = None{{/defaultValue}}, {{/requiredParams}}**kwargs): - """{{{summary}}} + def {{nickname}}(self, {{#allParams}}{{#required}}{{paramName}}, {{/required}}{{/allParams}}**kwargs): + """ + {{{summary}}} {{{notes}}} - Args: - {{#allParams}}{{paramName}}, {{dataType}}: {{{description}}} {{^optional}}(required){{/optional}}{{#optional}}(optional){{/optional}} - {{/allParams}} - - Returns: {{returnType}} + {{#allParams}}:param {{dataType}} {{paramName}}: {{{description}}} {{#required}}(required){{/required}}{{#optional}}(optional){{/optional}} + {{/allParams}} + :return: {{#returnType}}{{returnType}}{{/returnType}}{{^returnType}}None{{/returnType}} """ - - allParams = [{{#allParams}}'{{paramName}}'{{#hasMore}}, {{/hasMore}}{{/allParams}}] + {{#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}}] params = locals() - for (key, val) in params['kwargs'].iteritems(): - if key not in allParams: + for key, val in iteritems(params['kwargs']): + if key not in all_params: raise TypeError("Got an unexpected keyword argument '%s' to method {{nickname}}" % key) params[key] = val del params['kwargs'] - resourcePath = '{{path}}' - resourcePath = resourcePath.replace('{format}', 'json') + resource_path = '{{path}}'.replace('{format}', 'json') method = '{{httpMethod}}' - queryParams = {} - headerParams = {} - formParams = {} - files = {} - bodyParam = None + path_params = remove_none(dict({{#pathParams}}{{baseName}}=params.get('{{paramName}}'){{#hasMore}}, {{/hasMore}}{{/pathParams}})) + query_params = remove_none(dict({{#queryParams}}{{baseName}}=params.get('{{paramName}}'){{#hasMore}}, {{/hasMore}}{{/queryParams}})) + header_params = remove_none(dict({{#headerParams}}{{baseName}}=params.get('{{paramName}}'){{#hasMore}}, {{/hasMore}}{{/headerParams}})) + form_params = remove_none(dict({{#formParams}}{{^isFile}}{{baseName}}=params.get('{{paramName}}'){{#hasMore}}, {{/hasMore}}{{/isFile}}{{/formParams}})) + files = remove_none(dict({{#formParams}}{{#isFile}}{{baseName}}=params.get('{{paramName}}'){{#hasMore}}, {{/hasMore}}{{/isFile}}{{/formParams}})) + body_params = {{#bodyParam}}params.get('{{paramName}}'){{/bodyParam}}{{^bodyParam}}None{{/bodyParam}} accepts = [{{#produces}}'{{mediaType}}'{{#hasMore}}, {{/hasMore}}{{/produces}}] - headerParams['Accept'] = ', '.join(accepts) + header_params['Accept'] = ', '.join(accepts) content_types = [{{#consumes}}'{{mediaType}}'{{#hasMore}}, {{/hasMore}}{{/consumes}}] - headerParams['Content-Type'] = content_types[0] if len(content_types) > 0 else 'application/json' - - {{#queryParams}} - if ('{{paramName}}' in params): - queryParams['{{baseName}}'] = self.apiClient.toPathValue(params['{{paramName}}']) - {{/queryParams}} - - {{#headerParams}} - if ('{{paramName}}' in params): - headerParams['{{baseName}}'] = params['{{paramName}}'] - {{/headerParams}} - - {{#pathParams}} - if ('{{paramName}}' in params): - replacement = str(self.apiClient.toPathValue(params['{{paramName}}'])) - replacement = urllib.quote(replacement) - resourcePath = resourcePath.replace('{' + '{{baseName}}' + '}', - replacement) - {{/pathParams}} - - {{#formParams}} - if ('{{paramName}}' in params): - {{#notFile}}formParams['{{baseName}}'] = params['{{paramName}}']{{/notFile}}{{#isFile}}files['{{baseName}}'] = params['{{paramName}}']{{/isFile}} - {{/formParams}} - - {{#bodyParam}} - if ('{{paramName}}' in params): - bodyParam = params['{{paramName}}'] - {{/bodyParam}} - - postData = (formParams if formParams else bodyParam) - - response = self.apiClient.callAPI(resourcePath, method, queryParams, - postData, headerParams, files=files) + header_params['Content-Type'] = content_types[0] if len(content_types) > 0 else 'application/json' + 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={{#returnType}}'{{returnType}}'{{/returnType}}{{^returnType}}None{{/returnType}}) {{#returnType}} - if not response: - return None - - responseObject = self.apiClient.deserialize(response, '{{returnType}}') - return responseObject - {{/returnType}} - {{newline}} - {{newline}} - {{/operation}} -{{newline}} + return response + {{/returnType}}{{/operation}} {{/operations}} -{{newline}} + + + + + + + + + diff --git a/modules/swagger-codegen/src/main/resources/python/model.mustache b/modules/swagger-codegen/src/main/resources/python/model.mustache index 6100447bb7cc..e9ede4cd221e 100644 --- a/modules/swagger-codegen/src/main/resources/python/model.mustache +++ b/modules/swagger-codegen/src/main/resources/python/model.mustache @@ -20,33 +20,30 @@ Copyright 2015 Reverb Technologies, Inc. {{#model}} 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. + """ def __init__(self): """ - Attributes: - swaggerTypes (dict): The key is attribute name and the value is attribute type. - attributeMap (dict): The key is attribute name and the value is json key in definition. + Swagger model + + :param dict swaggerTypes: The key is attribute name and the value is attribute type. + :param dict attributeMap: The key is attribute name and the value is json key in definition. """ - self.swaggerTypes = { - {{#vars}} - '{{name}}': '{{{datatype}}}'{{#hasMore}}, - {{/hasMore}} - {{/vars}}{{newline}} + self.swagger_types = { + {{#vars}}'{{name}}': '{{{datatype}}}'{{#hasMore}}, + {{/hasMore}}{{/vars}} } - self.attributeMap = { - {{#vars}} - '{{name}}': '{{baseName}}'{{#hasMore}},{{/hasMore}} - {{/vars}} + self.attribute_map = { + {{#vars}}'{{name}}': '{{baseName}}'{{#hasMore}}, + {{/hasMore}}{{/vars}} } - {{#vars}} - {{#description}}#{{description}} - {{/description}} - self.{{name}} = None # {{{datatype}}} + {{#description}}# {{description}}{{/description}} + self.{{name}} = None # {{{datatype}}} {{/vars}} def __repr__(self): @@ -58,3 +55,5 @@ class {{classname}}(object): return '<{name} {props}>'.format(name=__name__, props=' '.join(properties)) {{/model}} {{/models}} + + diff --git a/modules/swagger-codegen/src/main/resources/python/rest.mustache b/modules/swagger-codegen/src/main/resources/python/rest.mustache new file mode 100644 index 000000000000..06b817da7570 --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/python/rest.mustache @@ -0,0 +1,223 @@ +# coding: utf-8 +import sys +import io +import json + +# python 2 and python 3 compatibility library +from six import iteritems + +try: + import urllib3 +except ImportError: + raise ImportError('Swagger python client requires urllib3.') + +try: + # for python3 + from urllib.parse import urlencode +except ImportError: + # for python2 + from urllib import urlencode + + +class RESTResponse(io.IOBase): + + def __init__(self, resp): + self.urllib3_response = resp + self.status = resp.status + self.reason = resp.reason + self.data = resp.data + + def getheaders(self): + """ + Returns a dictionary of the response headers. + """ + return self.urllib3_response.getheaders() + + def getheader(self, name, default=None): + """ + Returns a given response header. + """ + return self.urllib3_response.getheader(name, default) + +class RESTClientObject(object): + + def __init__(self, pools_size=4): + self.pool_manager = urllib3.PoolManager( + num_pools=pools_size + ) + + def request(self, method, url, query_params=None, headers=None, + body=None, post_params=None): + """ + :param method: http request method + :param url: http request url + :param query_params: query parameters in the url + :param headers: http request headers + :param body: request json body, for `application/json` + :param post_params: request post parameters, `application/x-www-form-urlencode` + and `multipart/form-data` + :param raw_response: if return the raw response + """ + method = method.upper() + assert method in ['GET', 'HEAD', 'DELETE', 'POST', 'PUT', 'PATCH'] + + if post_params and body: + raise ValueError("body parameter cannot be used with post_params parameter.") + + post_params = post_params or {} + headers = headers or {} + + if 'Content-Type' not in headers: + headers['Content-Type'] = 'application/json' + + # For `POST`, `PUT`, `PATCH` + if method in ['POST', 'PUT', 'PATCH']: + if query_params: + url += '?' + urlencode(query_params) + if headers['Content-Type'] == 'application/json': + r = self.pool_manager.request(method, url, + body=json.dumps(body), + headers=headers) + if headers['Content-Type'] == 'application/x-www-form-urlencoded': + r = self.pool_manager.request(method, url, + fields=post_params, + encode_multipart=False, + headers=headers) + if headers['Content-Type'] == 'multipart/form-data': + # 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, + headers=headers) + # For `GET`, `HEAD`, `DELETE` + else: + r = self.pool_manager.request(method, url, + fields=query_params, + headers=headers) + r = RESTResponse(r) + + if r.status not in range(200, 206): + raise ErrorResponse(r) + + return self.process_response(r) + + def process_response(self, response): + # In the python 3, the response.data is bytes. + # we need to decode it to string. + if sys.version_info > (3,): + data = response.data.decode('utf8') + else: + data = response.data + try: + resp = json.loads(data) + except ValueError: + resp = data + + return resp + + def GET(self, url, headers=None, query_params=None): + return self.request("GET", url, headers=headers, query_params=query_params) + + def HEAD(self, url, headers=None, query_params=None): + return self.request("HEAD", url, headers=headers, query_params=query_params) + + def DELETE(self, url, headers=None, query_params=None): + return self.request("DELETE", url, headers=headers, query_params=query_params) + + def POST(self, url, headers=None, post_params=None, body=None): + return self.request("POST", url, headers=headers, post_params=post_params, body=body) + + def PUT(self, url, headers=None, post_params=None, body=None): + return self.request("PUT", url, headers=headers, post_params=post_params, body=body) + + def PATCH(self, url, headers=None, post_params=None, body=None): + return self.request("PATCH", url, headers=headers, post_params=post_params, body=body) + + +class ErrorResponse(Exception): + """ + Non-2xx HTTP response + """ + + def __init__(self, http_resp): + self.status = http_resp.status + self.reason = http_resp.reason + self.body = http_resp.data + self.headers = http_resp.getheaders() + + # In the python 3, the self.body is bytes. + # we need to decode it to string. + if sys.version_info > (3,): + data = self.body.decode('utf8') + else: + data = self.body + + try: + self.body = json.loads(data) + except ValueError: + self.body = data + + def __str__(self): + """ + Custom error response messages + """ + return "({0})\nReason: {1}\nHeader: {2}\nBody: {3}\n".\ + format(self.status, self.reason, self.headers, self.body) + +class RESTClient(object): + """ + A class with all class methods to perform JSON requests. + """ + + IMPL = RESTClientObject() + + @classmethod + def request(cls, *n, **kw): + """ + Perform a REST request and parse the response. + """ + return cls.IMPL.request(*n, **kw) + + @classmethod + def GET(cls, *n, **kw): + """ + Perform a GET request using `RESTClient.request()`. + """ + return cls.IMPL.GET(*n, **kw) + + @classmethod + def HEAD(cls, *n, **kw): + """ + Perform a HEAD request using `RESTClient.request()`. + """ + return cls.IMPL.GET(*n, **kw) + + @classmethod + def POST(cls, *n, **kw): + """ + Perform a POST request using `RESTClient.request()` + """ + return cls.IMPL.POST(*n, **kw) + + @classmethod + def PUT(cls, *n, **kw): + """ + Perform a PUT request using `RESTClient.request()` + """ + return cls.IMPL.PUT(*n, **kw) + + @classmethod + def PATCH(cls, *n, **kw): + """ + Perform a PATCH request using `RESTClient.request()` + """ + return cls.IMPL.PATCH(*n, **kw) + + @classmethod + def DELETE(cls, *n, **kw): + """ + Perform a DELETE request using `RESTClient.request()` + """ + return cls.IMPL.DELETE(*n, **kw) diff --git a/modules/swagger-codegen/src/main/resources/python/setup.mustache b/modules/swagger-codegen/src/main/resources/python/setup.mustache index d10da4c68d04..a049057c920d 100644 --- a/modules/swagger-codegen/src/main/resources/python/setup.mustache +++ b/modules/swagger-codegen/src/main/resources/python/setup.mustache @@ -12,7 +12,7 @@ from setuptools import setup, find_packages # Try reading the setuptools documentation: # http://pypi.python.org/pypi/setuptools -REQUIRES = [] +REQUIRES = ["urllib3 >= 1.10", "six >= 1.9"] setup( name="{{module}}", @@ -30,3 +30,11 @@ setup( ) {{/hasMore}}{{/apis}}{{/apiInfo}} + + + + + + + + diff --git a/modules/swagger-codegen/src/main/resources/python/swagger.mustache b/modules/swagger-codegen/src/main/resources/python/swagger.mustache index 10ac54d527d1..549106014e3c 100644 --- a/modules/swagger-codegen/src/main/resources/python/swagger.mustache +++ b/modules/swagger-codegen/src/main/resources/python/swagger.mustache @@ -6,118 +6,109 @@ server communication, and is invariant across implementations. Specifics of the methods and models for each application are generated from the Swagger templates.""" -import sys +from __future__ import absolute_import +from . import models +from .rest import RESTClient + import os import re import urllib -import urllib2 -import httplib import json import datetime import mimetypes import random -import string -import models + +# python 2 and python 3 compatibility library +from six import iteritems + +try: + # for python3 + from urllib.parse import quote +except ImportError: + # for python2 + from urllib import quote class ApiClient(object): - """Generic API client for Swagger client library builds - - Attributes: - host: The base path for the server to call - headerName: a header to pass when making calls to the API - headerValue: a header value to pass when making calls to the API """ - def __init__(self, host=None, headerName=None, headerValue=None): - self.defaultHeaders = {} - if (headerName is not None): - self.defaultHeaders[headerName] = headerValue + Generic API client for Swagger client library builds + + :param host: The base path for the server to call + :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=None, header_name=None, header_value=None): + self.default_headers = {} + if header_name is not None: + self.default_headers[header_name] = header_value self.host = host self.cookie = None - self.boundary = ''.join(random.choice(string.ascii_letters + string.digits) for _ in range(30)) # Set default User-Agent. self.user_agent = 'Python-Swagger' @property def user_agent(self): - return self.defaultHeaders['User-Agent'] + return self.default_headers['User-Agent'] @user_agent.setter def user_agent(self, value): - self.defaultHeaders['User-Agent'] = value + self.default_headers['User-Agent'] = value - def setDefaultHeader(self, headerName, headerValue): - self.defaultHeaders[headerName] = headerValue + def set_default_header(self, header_name, header_value): + self.default_headers[header_name] = header_value - def callAPI(self, resourcePath, method, queryParams, postData, - headerParams=None, files=None): - - url = self.host + resourcePath - - mergedHeaderParams = self.defaultHeaders.copy() - mergedHeaderParams.update(headerParams) - headers = {} - if mergedHeaderParams: - for param, value in mergedHeaderParams.iteritems(): - headers[param] = ApiClient.sanitizeForSerialization(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=None): + # headers parameters + headers = self.default_headers.copy() + headers.update(header_params) if self.cookie: - headers['Cookie'] = ApiClient.sanitizeForSerialization(self.cookie) + headers['Cookie'] = self.cookie + if headers: + headers = ApiClient.sanitize_for_serialization(headers) - data = None + # path parameters + if path_params: + path_params = ApiClient.sanitize_for_serialization(path_params) + for k, v in iteritems(path_params): + replacement = quote(str(self.to_path_value(v))) + resource_path = resource_path.replace('{' + k + '}', replacement) - if queryParams: - # Need to remove None values, these should not be sent - sentQueryParams = {} - for param, value in queryParams.items(): - if value is not None: - sentQueryParams[param] = ApiClient.sanitizeForSerialization(value) - url = url + '?' + urllib.urlencode(sentQueryParams) + # query parameters + if query_params: + query_params = ApiClient.sanitize_for_serialization(query_params) + query_params = {k: self.to_path_value(v) for k, v in iteritems(query_params)} - if method in ['GET']: - #Options to add statements later on and for compatibility - pass + # post parameters + if post_params: + post_params = self.prepare_post_parameters(post_params, files) + post_params = ApiClient.sanitize_for_serialization(post_params) - elif method in ['POST', 'PUT', 'DELETE']: - if postData: - postData = ApiClient.sanitizeForSerialization(postData) - if 'Content-Type' not in headers: - headers['Content-Type'] = 'application/json' - data = json.dumps(postData) - elif headers['Content-Type'] == 'application/json': - data = json.dumps(postData) - elif headers['Content-Type'] == 'multipart/form-data': - data = self.buildMultipartFormData(postData, files) - headers['Content-Type'] = 'multipart/form-data; boundary={0}'.format(self.boundary) - headers['Content-length'] = str(len(data)) - else: - data = urllib.urlencode(postData) + # body + if body: + body = ApiClient.sanitize_for_serialization(body) + # request url + url = self.host + resource_path + + # perform request and return response + response_data = self.request(method, url, query_params=query_params, headers=headers, + post_params=post_params, body=body) + + # deserialize response data + if response: + return self.deserialize(response_data, response) else: - raise Exception('Method ' + method + ' is not recognized.') + return None - request = MethodRequest(method=method, url=url, headers=headers, - data=data) + def to_path_value(self, obj): + """ + Convert a string or object to a path-friendly value + + :param obj: object or string value - # Make the request - response = urllib2.urlopen(request) - if 'Set-Cookie' in response.headers: - self.cookie = response.headers['Set-Cookie'] - string = response.read() - - try: - data = json.loads(string) - except ValueError: # PUT requests don't return anything - data = None - - return data - - def toPathValue(self, obj): - """Convert a string or object to a path-friendly value - Args: - obj -- object or string value - Returns: - string -- quoted value + :return string: quoted value """ if type(obj) == list: return ','.join(obj) @@ -125,12 +116,12 @@ class ApiClient(object): return str(obj) @staticmethod - def sanitizeForSerialization(obj): + def sanitize_for_serialization(obj): """ Sanitize an object for Request. If obj is None, return None. - If obj is str, int, long, float, bool, return directly. + If obj is str, int, float, bool, return directly. If obj is datetime.datetime, datetime.date convert to string in iso8601 format. If obj is list, santize each element in the list. If obj is dict, return the dict. @@ -138,113 +129,80 @@ class ApiClient(object): """ if isinstance(obj, type(None)): return None - elif isinstance(obj, (str, int, long, float, bool, file)): + elif isinstance(obj, (str, int, float, bool, tuple)): return obj elif isinstance(obj, list): - return [ApiClient.sanitizeForSerialization(subObj) for subObj in obj] + return [ApiClient.sanitize_for_serialization(sub_obj) for sub_obj in obj] elif isinstance(obj, (datetime.datetime, datetime.date)): return obj.isoformat() else: if isinstance(obj, dict): - objDict = obj + obj_dict = obj else: - # Convert model obj to dict except attributes `swaggerTypes`, `attributeMap` + # Convert model obj to dict except attributes `swagger_types`, `attribute_map` # and attributes which value is not None. # Convert attribute name to json key in model definition for request. - objDict = {obj.attributeMap[key]: val - for key, val in obj.__dict__.iteritems() - if key != 'swaggerTypes' and key != 'attributeMap' and val is not None} - return {key: ApiClient.sanitizeForSerialization(val) - for (key, val) in objDict.iteritems()} + obj_dict = {obj.attribute_map[key]: val + for key, val in iteritems(obj.__dict__) + if key != 'swagger_types' and key != 'attribute_map' and val is not None} + return {key: ApiClient.sanitize_for_serialization(val) + for key, val in iteritems(obj_dict)} - def buildMultipartFormData(self, postData, files): - def escape_quotes(s): - return s.replace('"', '\\"') + def deserialize(self, obj, obj_class): + """ + Derialize a JSON string into an object. - lines = [] + :param obj: string or object to be deserialized + :param obj_class: class literal for deserialzied object, or string of class name - for name, value in postData.items(): - lines.extend(( - '--{0}'.format(self.boundary), - 'Content-Disposition: form-data; name="{0}"'.format(escape_quotes(name)), - '', - str(value), - )) - - for name, filepath in files.items(): - f = open(filepath, 'r') - filename = filepath.split('/')[-1] - mimetype = mimetypes.guess_type(filename)[0] or 'application/octet-stream' - lines.extend(( - '--{0}'.format(self.boundary), - 'Content-Disposition: form-data; name="{0}"; filename="{1}"'.format(escape_quotes(name), escape_quotes(filename)), - 'Content-Type: {0}'.format(mimetype), - '', - f.read() - )) - - lines.extend(( - '--{0}--'.format(self.boundary), - '' - )) - return '\r\n'.join(lines) - - def deserialize(self, obj, objClass): - """Derialize a JSON string into an object. - - Args: - obj -- string or object to be deserialized - objClass -- class literal for deserialzied object, or string - of class name - Returns: - object -- deserialized object""" - - # Have to accept objClass as string or actual type. Type could be a + :return object: deserialized object + """ + # Have to accept obj_class as string or actual type. Type could be a # native Python type, or one of the model classes. - if type(objClass) == str: - if 'list[' in objClass: - match = re.match('list\[(.*)\]', objClass) - subClass = match.group(1) - return [self.deserialize(subObj, subClass) for subObj in obj] + if type(obj_class) == str: + if 'list[' in obj_class: + match = re.match('list\[(.*)\]', obj_class) + sub_class = match.group(1) + return [self.deserialize(sub_obj, sub_class) for sub_obj in obj] - if (objClass in ['int', 'float', 'long', 'dict', 'list', 'str', 'bool', 'datetime']): - objClass = eval(objClass) + if obj_class in ['int', 'float', 'dict', 'list', 'str', 'bool', 'datetime']: + obj_class = eval(obj_class) else: # not a native type, must be model class - objClass = eval('models.' + objClass) + obj_class = eval('models.' + obj_class) - if objClass in [int, long, float, dict, list, str, bool]: - return objClass(obj) - elif objClass == datetime: + if obj_class in [int, float, dict, list, str, bool]: + return obj_class(obj) + elif obj_class == datetime: return self.__parse_string_to_datetime(obj) - instance = objClass() + instance = obj_class() - for attr, attrType in instance.swaggerTypes.iteritems(): - if obj is not None and instance.attributeMap[attr] in obj and type(obj) in [list, dict]: - value = obj[instance.attributeMap[attr]] - if attrType in ['str', 'int', 'long', 'float', 'bool']: - attrType = eval(attrType) + for attr, attr_type in iteritems(instance.swagger_types): + if obj is not None and instance.attribute_map[attr] in obj and type(obj) in [list, dict]: + value = obj[instance.attribute_map[attr]] + if attr_type in ['str', 'int', 'float', 'bool']: + attr_type = eval(attr_type) try: - value = attrType(value) + value = attr_type(value) except UnicodeEncodeError: value = unicode(value) except TypeError: value = value setattr(instance, attr, value) - elif (attrType == 'datetime'): + elif attr_type == 'datetime': setattr(instance, attr, self.__parse_string_to_datetime(value)) - elif 'list[' in attrType: - match = re.match('list\[(.*)\]', attrType) - subClass = match.group(1) - subValues = [] + elif 'list[' in attr_type: + match = re.match('list\[(.*)\]', attr_type) + sub_class = match.group(1) + sub_values = [] if not value: setattr(instance, attr, None) else: - for subValue in value: - subValues.append(self.deserialize(subValue, subClass)) - setattr(instance, attr, subValues) + for sub_value in value: + sub_values.append(self.deserialize(sub_value, sub_class)) + setattr(instance, attr, sub_values) else: - setattr(instance, attr, self.deserialize(value, attrType)) + setattr(instance, attr, self.deserialize(value, attr_type)) return instance @@ -260,16 +218,42 @@ class ApiClient(object): except ImportError: return string -class MethodRequest(urllib2.Request): - def __init__(self, *args, **kwargs): - """Construct a MethodRequest. Usage is the same as for - `urllib2.Request` except it also takes an optional `method` - keyword argument. If supplied, `method` will be used instead of - the default.""" + def request(self, method, url, query_params=None, headers=None, post_params=None, body=None): + """ + Perform http request using RESTClient. + """ + if method == "GET": + return RESTClient.GET(url, query_params=query_params, headers=headers) + elif method == "HEAD": + return RESTClient.HEAD(url, query_params=query_params, headers=headers) + elif method == "POST": + return RESTClient.POST(url, headers=headers, post_params=post_params, body=body) + elif method == "PUT": + return RESTClient.PUT(url, headers=headers, post_params=post_params, body=body) + elif method == "PATCH": + return RESTClient.PATCH(url, headers=headers, post_params=post_params, body=body) + elif method == "DELETE": + return RESTClient.DELETE(url, query_params=query_params, headers=headers) + else: + raise ValueError("http method must be `GET`, `HEAD`, `POST`, `PATCH`, `PUT` or `DELETE`") + + def prepare_post_parameters(self, post_params=None, files=None): + params = {} + + if post_params: + params.update(post_params) + + if files: + for k, v in iteritems(files): + with open(v, 'rb') as f: + filename = os.path.basename(f.name) + filedata = f.read() + mimetype = mimetypes.guess_type(filename)[0] or 'application/octet-stream' + params[k] = tuple([filename, filedata, mimetype]) + + return params + + + - if 'method' in kwargs: - self.method = kwargs.pop('method') - return urllib2.Request.__init__(self, *args, **kwargs) - def get_method(self): - return getattr(self, 'method', urllib2.Request.get_method(self)) diff --git a/modules/swagger-codegen/src/main/resources/python/util.mustache b/modules/swagger-codegen/src/main/resources/python/util.mustache new file mode 100644 index 000000000000..1137a5d2d23c --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/python/util.mustache @@ -0,0 +1,17 @@ +from six import iteritems + +def remove_none(obj): + if isinstance(obj, (list, tuple, set)): + return type(obj)(remove_none(x) for x in obj if x is not None) + elif isinstance(obj, dict): + return type(obj)((remove_none(k), remove_none(v)) + for k, v in iteritems(obj) if k is not None and v is not None) + else: + return obj + + +def inspect_vars(obj): + if not hasattr(obj, '__dict__'): + return obj + else: + return {k: inspect_vars(getattr(obj, k)) for k in dir(obj)} diff --git a/samples/client/petstore/python/SwaggerPetstore-python/Makefile b/samples/client/petstore/python/SwaggerPetstore-python/Makefile new file mode 100644 index 000000000000..2811b735b542 --- /dev/null +++ b/samples/client/petstore/python/SwaggerPetstore-python/Makefile @@ -0,0 +1,37 @@ +REQUIREMENTS_FILE=dev-requirements.txt +REQUIREMENTS_OUT=dev-requirements.txt.log +SETUP_OUT=*.egg-info + +virtualenv: +ifndef VIRTUAL_ENV + $(error Must be run inside of a virtualenv\ + http://docs.python-guide.org/en/latest/dev/virtualenvs/) +endif + +setup: virtualenv $(SETUP_OUT) + +$(SETUP_OUT): setup.py setup.cfg + python setup.py develop + touch $(SETUP_OUT) + +$(REQUIREMENTS_OUT): $(REQUIREMENTS_FILE) + pip install -r $(REQUIREMENTS_FILE) | tee -a $(REQUIREMENTS_OUT) + python setup.py develop + +clean: + rm -rf $(REQUIREMENTS_OUT) + rm -rf $(SETUP_OUT) + rm -rf .tox + rm -rf .coverage + find . -name "*.py[oc]" -delete + find . -name "__pycache__" -delete + +requirements: setup $(REQUIREMENTS_OUT) + +test: clean requirements + nosetests + +test-all: clean requirements + tox + + diff --git a/samples/client/petstore/python/SwaggerPetstore-python/README.md b/samples/client/petstore/python/SwaggerPetstore-python/README.md index 3b69aba0f82d..9c590a9a5088 100644 --- a/samples/client/petstore/python/SwaggerPetstore-python/README.md +++ b/samples/client/petstore/python/SwaggerPetstore-python/README.md @@ -38,5 +38,37 @@ TODO ## Tests -TODO +(Make sure you are running it inside of a [virtualenv](http://docs.python-guide.org/en/latest/dev/virtualenvs/)) + +You can run the tests in the current python platform: + +```sh +$ make test +[... magically installs dependencies and runs tests on your virtualenv] +Ran 7 tests in 19.289s + +OK +``` +or + +``` +$ mvn integration-test -rf :PythonPetstoreClientTests +Using 2195432783 as seed +[INFO] ------------------------------------------------------------------------ +[INFO] BUILD SUCCESS +[INFO] ------------------------------------------------------------------------ +[INFO] Total time: 37.594 s +[INFO] Finished at: 2015-05-16T18:00:35+08:00 +[INFO] Final Memory: 11M/156M +[INFO] ------------------------------------------------------------------------ +``` +If you want to run the tests in all the python platforms: + +```sh +$ make test-all +[... tox creates a virtualenv for every platform and runs tests inside of each] + py27: commands succeeded + py34: commands succeeded + congratulations :) +``` diff --git a/samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/__init__.py b/samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/__init__.py index 30d634bc4b38..9d4b2db3de58 100644 --- a/samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/__init__.py +++ b/samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/__init__.py @@ -1,34 +1,16 @@ -#!/usr/bin/env python -"""Add all of the modules in the current directory to __all__""" -import os - -# import models into package +from __future__ import absolute_import +# import models into sdk package from .models.user import User - from .models.category import Category - from .models.pet import Pet - from .models.tag import Tag - from .models.order import Order - -# import apis into package - -from .user_api import UserApi - -from .pet_api import PetApi - -from .store_api import StoreApi - +# import apis into sdk package +from .apis.user_api import UserApi +from .apis.pet_api import PetApi +from .apis.store_api import StoreApi # import ApiClient from .swagger import ApiClient - -__all__ = [] - -for module in os.listdir(os.path.dirname(__file__)): - if module != '__init__.py' and module[-3:] == '.py': - __all__.append(module[:-3]) diff --git a/samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/apis/__init__.py b/samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/apis/__init__.py new file mode 100644 index 000000000000..128b25dad821 --- /dev/null +++ b/samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/apis/__init__.py @@ -0,0 +1,7 @@ +from __future__ import absolute_import + +# import apis into api package +from .user_api import UserApi +from .pet_api import PetApi +from .store_api import StoreApi + diff --git a/samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/apis/pet_api.py b/samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/apis/pet_api.py new file mode 100644 index 000000000000..e6bd35514f45 --- /dev/null +++ b/samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/apis/pet_api.py @@ -0,0 +1,384 @@ +#!/usr/bin/env python +# coding: utf-8 + +""" +PetApi.py +Copyright 2015 Reverb Technologies, Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +NOTE: This class is auto generated by the swagger code generator program. Do not edit the class manually. +""" +from __future__ import absolute_import + +import sys +import os + +# python 2 and python 3 compatibility library +from six import iteritems + +from ..util import remove_none + +class PetApi(object): + + def __init__(self, api_client): + self.api_client = api_client + + def update_pet(self, **kwargs): + """ + Update an existing pet + + + :param Pet body: Pet object that needs to be added to the store + + :return: None + """ + + all_params = ['body'] + + params = locals() + for key, val in iteritems(params['kwargs']): + if key not in all_params: + raise TypeError("Got an unexpected keyword argument '%s' to method update_pet" % key) + params[key] = val + del params['kwargs'] + + resource_path = '/pet'.replace('{format}', 'json') + method = 'PUT' + + path_params = remove_none(dict()) + query_params = remove_none(dict()) + header_params = remove_none(dict()) + form_params = remove_none(dict()) + files = remove_none(dict()) + body_params = params.get('body') + + accepts = ['application/json', 'application/xml'] + header_params['Accept'] = ', '.join(accepts) + + content_types = ['application/json', 'application/xml', ] + header_params['Content-Type'] = content_types[0] if len(content_types) > 0 else 'application/json' + + 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=None) + + def add_pet(self, **kwargs): + """ + Add a new pet to the store + + + :param Pet body: Pet object that needs to be added to the store + + :return: None + """ + + all_params = ['body'] + + params = locals() + for key, val in iteritems(params['kwargs']): + if key not in all_params: + raise TypeError("Got an unexpected keyword argument '%s' to method add_pet" % key) + params[key] = val + del params['kwargs'] + + resource_path = '/pet'.replace('{format}', 'json') + method = 'POST' + + path_params = remove_none(dict()) + query_params = remove_none(dict()) + header_params = remove_none(dict()) + form_params = remove_none(dict()) + files = remove_none(dict()) + body_params = params.get('body') + + accepts = ['application/json', 'application/xml'] + header_params['Accept'] = ', '.join(accepts) + + content_types = ['application/json', 'application/xml', ] + header_params['Content-Type'] = content_types[0] if len(content_types) > 0 else 'application/json' + + 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=None) + + def find_pets_by_status(self, **kwargs): + """ + Finds Pets by status + Multiple status values can be provided with comma seperated strings + + :param list[str] status: Status values that need to be considered for filter + + :return: list[Pet] + """ + + all_params = ['status'] + + params = locals() + for key, val in iteritems(params['kwargs']): + if key not in all_params: + raise TypeError("Got an unexpected keyword argument '%s' to method find_pets_by_status" % key) + params[key] = val + del params['kwargs'] + + resource_path = '/pet/findByStatus'.replace('{format}', 'json') + method = 'GET' + + path_params = remove_none(dict()) + query_params = remove_none(dict(status=params.get('status'))) + header_params = remove_none(dict()) + form_params = remove_none(dict()) + files = remove_none(dict()) + body_params = None + + accepts = ['application/json', 'application/xml'] + header_params['Accept'] = ', '.join(accepts) + + content_types = [] + header_params['Content-Type'] = content_types[0] if len(content_types) > 0 else 'application/json' + + 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='list[Pet]') + + return response + + def find_pets_by_tags(self, **kwargs): + """ + Finds Pets by tags + Muliple tags can be provided with comma seperated strings. Use tag1, tag2, tag3 for testing. + + :param list[str] tags: Tags to filter by + + :return: list[Pet] + """ + + all_params = ['tags'] + + params = locals() + for key, val in iteritems(params['kwargs']): + if key not in all_params: + raise TypeError("Got an unexpected keyword argument '%s' to method find_pets_by_tags" % key) + params[key] = val + del params['kwargs'] + + resource_path = '/pet/findByTags'.replace('{format}', 'json') + method = 'GET' + + path_params = remove_none(dict()) + query_params = remove_none(dict(tags=params.get('tags'))) + header_params = remove_none(dict()) + form_params = remove_none(dict()) + files = remove_none(dict()) + body_params = None + + accepts = ['application/json', 'application/xml'] + header_params['Accept'] = ', '.join(accepts) + + content_types = [] + header_params['Content-Type'] = content_types[0] if len(content_types) > 0 else 'application/json' + + 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='list[Pet]') + + return response + + def get_pet_by_id(self, pet_id, **kwargs): + """ + Find pet by ID + Returns a pet when ID < 10. ID > 10 or nonintegers will simulate API error conditions + + :param int pet_id: ID of pet that needs to be fetched (required) + + :return: Pet + """ + + # verify the required parameter 'pet_id' is set + if pet_id is None: + raise ValueError("Missing the required parameter `pet_id` when calling `get_pet_by_id`") + + all_params = ['pet_id'] + + params = locals() + for key, val in iteritems(params['kwargs']): + if key not in all_params: + raise TypeError("Got an unexpected keyword argument '%s' to method get_pet_by_id" % key) + params[key] = val + del params['kwargs'] + + resource_path = '/pet/{petId}'.replace('{format}', 'json') + method = 'GET' + + path_params = remove_none(dict(petId=params.get('pet_id'))) + query_params = remove_none(dict()) + header_params = remove_none(dict()) + form_params = remove_none(dict()) + files = remove_none(dict()) + body_params = None + + accepts = ['application/json', 'application/xml'] + header_params['Accept'] = ', '.join(accepts) + + content_types = [] + header_params['Content-Type'] = content_types[0] if len(content_types) > 0 else 'application/json' + + 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='Pet') + + return response + + def update_pet_with_form(self, pet_id, **kwargs): + """ + Updates a pet in the store with form data + + + :param str pet_id: ID of pet that needs to be updated (required) + :param str name: Updated name of the pet + :param str status: Updated status of the pet + + :return: None + """ + + # verify the required parameter 'pet_id' is set + if pet_id is None: + raise ValueError("Missing the required parameter `pet_id` when calling `update_pet_with_form`") + + all_params = ['pet_id', 'name', 'status'] + + params = locals() + for key, val in iteritems(params['kwargs']): + if key not in all_params: + raise TypeError("Got an unexpected keyword argument '%s' to method update_pet_with_form" % key) + params[key] = val + del params['kwargs'] + + resource_path = '/pet/{petId}'.replace('{format}', 'json') + method = 'POST' + + path_params = remove_none(dict(petId=params.get('pet_id'))) + query_params = remove_none(dict()) + header_params = remove_none(dict()) + form_params = remove_none(dict(name=params.get('name'), status=params.get('status'))) + files = remove_none(dict()) + body_params = None + + accepts = ['application/json', 'application/xml'] + header_params['Accept'] = ', '.join(accepts) + + content_types = ['application/x-www-form-urlencoded', ] + header_params['Content-Type'] = content_types[0] if len(content_types) > 0 else 'application/json' + + 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=None) + + def delete_pet(self, pet_id, **kwargs): + """ + Deletes a pet + + + :param str api_key: + :param int pet_id: Pet id to delete (required) + + :return: None + """ + + # verify the required parameter 'pet_id' is set + if pet_id is None: + raise ValueError("Missing the required parameter `pet_id` when calling `delete_pet`") + + all_params = ['api_key', 'pet_id'] + + params = locals() + for key, val in iteritems(params['kwargs']): + if key not in all_params: + raise TypeError("Got an unexpected keyword argument '%s' to method delete_pet" % key) + params[key] = val + del params['kwargs'] + + resource_path = '/pet/{petId}'.replace('{format}', 'json') + method = 'DELETE' + + path_params = remove_none(dict(petId=params.get('pet_id'))) + query_params = remove_none(dict()) + header_params = remove_none(dict(api_key=params.get('api_key'))) + form_params = remove_none(dict()) + files = remove_none(dict()) + body_params = None + + accepts = ['application/json', 'application/xml'] + header_params['Accept'] = ', '.join(accepts) + + content_types = [] + header_params['Content-Type'] = content_types[0] if len(content_types) > 0 else 'application/json' + + 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=None) + + def upload_file(self, pet_id, **kwargs): + """ + uploads an image + + + :param int pet_id: ID of pet to update (required) + :param str additional_metadata: Additional data to pass to server + :param file file: file to upload + + :return: None + """ + + # verify the required parameter 'pet_id' is set + if pet_id is None: + raise ValueError("Missing the required parameter `pet_id` when calling `upload_file`") + + all_params = ['pet_id', 'additional_metadata', 'file'] + + params = locals() + for key, val in iteritems(params['kwargs']): + if key not in all_params: + raise TypeError("Got an unexpected keyword argument '%s' to method upload_file" % key) + params[key] = val + del params['kwargs'] + + resource_path = '/pet/{petId}/uploadImage'.replace('{format}', 'json') + method = 'POST' + + path_params = remove_none(dict(petId=params.get('pet_id'))) + query_params = remove_none(dict()) + header_params = remove_none(dict()) + form_params = remove_none(dict(additionalMetadata=params.get('additional_metadata'), )) + files = remove_none(dict(file=params.get('file'))) + body_params = None + + accepts = ['application/json', 'application/xml'] + header_params['Accept'] = ', '.join(accepts) + + content_types = ['multipart/form-data', ] + header_params['Content-Type'] = content_types[0] if len(content_types) > 0 else 'application/json' + + 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=None) + + + + + + + + + + diff --git a/samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/apis/store_api.py b/samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/apis/store_api.py new file mode 100644 index 000000000000..0df9a84fe756 --- /dev/null +++ b/samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/apis/store_api.py @@ -0,0 +1,214 @@ +#!/usr/bin/env python +# coding: utf-8 + +""" +StoreApi.py +Copyright 2015 Reverb Technologies, Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +NOTE: This class is auto generated by the swagger code generator program. Do not edit the class manually. +""" +from __future__ import absolute_import + +import sys +import os + +# python 2 and python 3 compatibility library +from six import iteritems + +from ..util import remove_none + +class StoreApi(object): + + def __init__(self, api_client): + self.api_client = api_client + + def get_inventory(self, **kwargs): + """ + Returns pet inventories by status + Returns a map of status codes to quantities + + + :return: map(String, int) + """ + + all_params = [] + + params = locals() + for key, val in iteritems(params['kwargs']): + if key not in all_params: + raise TypeError("Got an unexpected keyword argument '%s' to method get_inventory" % key) + params[key] = val + del params['kwargs'] + + resource_path = '/store/inventory'.replace('{format}', 'json') + method = 'GET' + + path_params = remove_none(dict()) + query_params = remove_none(dict()) + header_params = remove_none(dict()) + form_params = remove_none(dict()) + files = remove_none(dict()) + body_params = None + + accepts = ['application/json', 'application/xml'] + header_params['Accept'] = ', '.join(accepts) + + content_types = [] + header_params['Content-Type'] = content_types[0] if len(content_types) > 0 else 'application/json' + + 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='map(String, int)') + + return response + + def place_order(self, **kwargs): + """ + Place an order for a pet + + + :param Order body: order placed for purchasing the pet + + :return: Order + """ + + all_params = ['body'] + + params = locals() + for key, val in iteritems(params['kwargs']): + if key not in all_params: + raise TypeError("Got an unexpected keyword argument '%s' to method place_order" % key) + params[key] = val + del params['kwargs'] + + resource_path = '/store/order'.replace('{format}', 'json') + method = 'POST' + + path_params = remove_none(dict()) + query_params = remove_none(dict()) + header_params = remove_none(dict()) + form_params = remove_none(dict()) + files = remove_none(dict()) + body_params = params.get('body') + + accepts = ['application/json', 'application/xml'] + header_params['Accept'] = ', '.join(accepts) + + content_types = [] + header_params['Content-Type'] = content_types[0] if len(content_types) > 0 else 'application/json' + + 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='Order') + + return response + + def get_order_by_id(self, order_id, **kwargs): + """ + Find purchase order by ID + For valid response try integer IDs with value <= 5 or > 10. Other values will generated exceptions + + :param str order_id: ID of pet that needs to be fetched (required) + + :return: Order + """ + + # verify the required parameter 'order_id' is set + if order_id is None: + raise ValueError("Missing the required parameter `order_id` when calling `get_order_by_id`") + + all_params = ['order_id'] + + params = locals() + for key, val in iteritems(params['kwargs']): + if key not in all_params: + raise TypeError("Got an unexpected keyword argument '%s' to method get_order_by_id" % key) + params[key] = val + del params['kwargs'] + + resource_path = '/store/order/{orderId}'.replace('{format}', 'json') + method = 'GET' + + path_params = remove_none(dict(orderId=params.get('order_id'))) + query_params = remove_none(dict()) + header_params = remove_none(dict()) + form_params = remove_none(dict()) + files = remove_none(dict()) + body_params = None + + accepts = ['application/json', 'application/xml'] + header_params['Accept'] = ', '.join(accepts) + + content_types = [] + header_params['Content-Type'] = content_types[0] if len(content_types) > 0 else 'application/json' + + 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='Order') + + return response + + def delete_order(self, order_id, **kwargs): + """ + Delete purchase order by ID + For valid response try integer IDs with value < 1000. Anything above 1000 or nonintegers will generate API errors + + :param str order_id: ID of the order that needs to be deleted (required) + + :return: None + """ + + # verify the required parameter 'order_id' is set + if order_id is None: + raise ValueError("Missing the required parameter `order_id` when calling `delete_order`") + + all_params = ['order_id'] + + params = locals() + for key, val in iteritems(params['kwargs']): + if key not in all_params: + raise TypeError("Got an unexpected keyword argument '%s' to method delete_order" % key) + params[key] = val + del params['kwargs'] + + resource_path = '/store/order/{orderId}'.replace('{format}', 'json') + method = 'DELETE' + + path_params = remove_none(dict(orderId=params.get('order_id'))) + query_params = remove_none(dict()) + header_params = remove_none(dict()) + form_params = remove_none(dict()) + files = remove_none(dict()) + body_params = None + + accepts = ['application/json', 'application/xml'] + header_params['Accept'] = ', '.join(accepts) + + content_types = [] + header_params['Content-Type'] = content_types[0] if len(content_types) > 0 else 'application/json' + + 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=None) + + + + + + + + + + diff --git a/samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/apis/user_api.py b/samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/apis/user_api.py new file mode 100644 index 000000000000..720843bd5083 --- /dev/null +++ b/samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/apis/user_api.py @@ -0,0 +1,374 @@ +#!/usr/bin/env python +# coding: utf-8 + +""" +UserApi.py +Copyright 2015 Reverb Technologies, Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +NOTE: This class is auto generated by the swagger code generator program. Do not edit the class manually. +""" +from __future__ import absolute_import + +import sys +import os + +# python 2 and python 3 compatibility library +from six import iteritems + +from ..util import remove_none + +class UserApi(object): + + def __init__(self, api_client): + self.api_client = api_client + + def create_user(self, **kwargs): + """ + Create user + This can only be done by the logged in user. + + :param User body: Created user object + + :return: None + """ + + all_params = ['body'] + + params = locals() + for key, val in iteritems(params['kwargs']): + if key not in all_params: + raise TypeError("Got an unexpected keyword argument '%s' to method create_user" % key) + params[key] = val + del params['kwargs'] + + resource_path = '/user'.replace('{format}', 'json') + method = 'POST' + + path_params = remove_none(dict()) + query_params = remove_none(dict()) + header_params = remove_none(dict()) + form_params = remove_none(dict()) + files = remove_none(dict()) + body_params = params.get('body') + + accepts = ['application/json', 'application/xml'] + header_params['Accept'] = ', '.join(accepts) + + content_types = [] + header_params['Content-Type'] = content_types[0] if len(content_types) > 0 else 'application/json' + + 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=None) + + def create_users_with_array_input(self, **kwargs): + """ + Creates list of users with given input array + + + :param list[User] body: List of user object + + :return: None + """ + + all_params = ['body'] + + params = locals() + for key, val in iteritems(params['kwargs']): + if key not in all_params: + raise TypeError("Got an unexpected keyword argument '%s' to method create_users_with_array_input" % key) + params[key] = val + del params['kwargs'] + + resource_path = '/user/createWithArray'.replace('{format}', 'json') + method = 'POST' + + path_params = remove_none(dict()) + query_params = remove_none(dict()) + header_params = remove_none(dict()) + form_params = remove_none(dict()) + files = remove_none(dict()) + body_params = params.get('body') + + accepts = ['application/json', 'application/xml'] + header_params['Accept'] = ', '.join(accepts) + + content_types = [] + header_params['Content-Type'] = content_types[0] if len(content_types) > 0 else 'application/json' + + 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=None) + + def create_users_with_list_input(self, **kwargs): + """ + Creates list of users with given input array + + + :param list[User] body: List of user object + + :return: None + """ + + all_params = ['body'] + + params = locals() + for key, val in iteritems(params['kwargs']): + if key not in all_params: + raise TypeError("Got an unexpected keyword argument '%s' to method create_users_with_list_input" % key) + params[key] = val + del params['kwargs'] + + resource_path = '/user/createWithList'.replace('{format}', 'json') + method = 'POST' + + path_params = remove_none(dict()) + query_params = remove_none(dict()) + header_params = remove_none(dict()) + form_params = remove_none(dict()) + files = remove_none(dict()) + body_params = params.get('body') + + accepts = ['application/json', 'application/xml'] + header_params['Accept'] = ', '.join(accepts) + + content_types = [] + header_params['Content-Type'] = content_types[0] if len(content_types) > 0 else 'application/json' + + 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=None) + + def login_user(self, **kwargs): + """ + Logs user into the system + + + :param str username: The user name for login + :param str password: The password for login in clear text + + :return: str + """ + + all_params = ['username', 'password'] + + params = locals() + for key, val in iteritems(params['kwargs']): + if key not in all_params: + raise TypeError("Got an unexpected keyword argument '%s' to method login_user" % key) + params[key] = val + del params['kwargs'] + + resource_path = '/user/login'.replace('{format}', 'json') + method = 'GET' + + path_params = remove_none(dict()) + query_params = remove_none(dict(username=params.get('username'), password=params.get('password'))) + header_params = remove_none(dict()) + form_params = remove_none(dict()) + files = remove_none(dict()) + body_params = None + + accepts = ['application/json', 'application/xml'] + header_params['Accept'] = ', '.join(accepts) + + content_types = [] + header_params['Content-Type'] = content_types[0] if len(content_types) > 0 else 'application/json' + + 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='str') + + return response + + def logout_user(self, **kwargs): + """ + Logs out current logged in user session + + + + :return: None + """ + + all_params = [] + + params = locals() + for key, val in iteritems(params['kwargs']): + if key not in all_params: + raise TypeError("Got an unexpected keyword argument '%s' to method logout_user" % key) + params[key] = val + del params['kwargs'] + + resource_path = '/user/logout'.replace('{format}', 'json') + method = 'GET' + + path_params = remove_none(dict()) + query_params = remove_none(dict()) + header_params = remove_none(dict()) + form_params = remove_none(dict()) + files = remove_none(dict()) + body_params = None + + accepts = ['application/json', 'application/xml'] + header_params['Accept'] = ', '.join(accepts) + + content_types = [] + header_params['Content-Type'] = content_types[0] if len(content_types) > 0 else 'application/json' + + 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=None) + + def get_user_by_name(self, username, **kwargs): + """ + Get user by user name + + + :param str username: The name that needs to be fetched. Use user1 for testing. (required) + + :return: User + """ + + # verify the required parameter 'username' is set + if username is None: + raise ValueError("Missing the required parameter `username` when calling `get_user_by_name`") + + all_params = ['username'] + + params = locals() + for key, val in iteritems(params['kwargs']): + if key not in all_params: + raise TypeError("Got an unexpected keyword argument '%s' to method get_user_by_name" % key) + params[key] = val + del params['kwargs'] + + resource_path = '/user/{username}'.replace('{format}', 'json') + method = 'GET' + + path_params = remove_none(dict(username=params.get('username'))) + query_params = remove_none(dict()) + header_params = remove_none(dict()) + form_params = remove_none(dict()) + files = remove_none(dict()) + body_params = None + + accepts = ['application/json', 'application/xml'] + header_params['Accept'] = ', '.join(accepts) + + content_types = [] + header_params['Content-Type'] = content_types[0] if len(content_types) > 0 else 'application/json' + + 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='User') + + return response + + def update_user(self, username, **kwargs): + """ + Updated user + This can only be done by the logged in user. + + :param str username: name that need to be deleted (required) + :param User body: Updated user object + + :return: None + """ + + # verify the required parameter 'username' is set + if username is None: + raise ValueError("Missing the required parameter `username` when calling `update_user`") + + all_params = ['username', 'body'] + + params = locals() + for key, val in iteritems(params['kwargs']): + if key not in all_params: + raise TypeError("Got an unexpected keyword argument '%s' to method update_user" % key) + params[key] = val + del params['kwargs'] + + resource_path = '/user/{username}'.replace('{format}', 'json') + method = 'PUT' + + path_params = remove_none(dict(username=params.get('username'))) + query_params = remove_none(dict()) + header_params = remove_none(dict()) + form_params = remove_none(dict()) + files = remove_none(dict()) + body_params = params.get('body') + + accepts = ['application/json', 'application/xml'] + header_params['Accept'] = ', '.join(accepts) + + content_types = [] + header_params['Content-Type'] = content_types[0] if len(content_types) > 0 else 'application/json' + + 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=None) + + def delete_user(self, username, **kwargs): + """ + Delete user + This can only be done by the logged in user. + + :param str username: The name that needs to be deleted (required) + + :return: None + """ + + # verify the required parameter 'username' is set + if username is None: + raise ValueError("Missing the required parameter `username` when calling `delete_user`") + + all_params = ['username'] + + params = locals() + for key, val in iteritems(params['kwargs']): + if key not in all_params: + raise TypeError("Got an unexpected keyword argument '%s' to method delete_user" % key) + params[key] = val + del params['kwargs'] + + resource_path = '/user/{username}'.replace('{format}', 'json') + method = 'DELETE' + + path_params = remove_none(dict(username=params.get('username'))) + query_params = remove_none(dict()) + header_params = remove_none(dict()) + form_params = remove_none(dict()) + files = remove_none(dict()) + body_params = None + + accepts = ['application/json', 'application/xml'] + header_params['Accept'] = ', '.join(accepts) + + content_types = [] + header_params['Content-Type'] = content_types[0] if len(content_types) > 0 else 'application/json' + + 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=None) + + + + + + + + + + diff --git a/samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/models/__init__.py b/samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/models/__init__.py index ce94c72a70c0..de307a265036 100644 --- a/samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/models/__init__.py +++ b/samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/models/__init__.py @@ -1,21 +1,9 @@ -#!/usr/bin/env python -"""Add all of the modules in the current directory to __all__""" -import os - +from __future__ import absolute_import +# import models into model package from .user import User - from .category import Category - from .pet import Pet - from .tag import Tag - from .order import Order - -__all__ = [] - -for module in os.listdir(os.path.dirname(__file__)): - if module != '__init__.py' and module[-3:] == '.py': - __all__.append(module[:-3]) diff --git a/samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/models/category.py b/samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/models/category.py index 9ed6a44fa65a..8fba78ca18e2 100644 --- a/samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/models/category.py +++ b/samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/models/category.py @@ -18,39 +18,33 @@ Copyright 2015 Reverb Technologies, Inc. """ class Category(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. + """ def __init__(self): """ - Attributes: - swaggerTypes (dict): The key is attribute name and the value is attribute type. - attributeMap (dict): The key is attribute name and the value is json key in definition. + Swagger model + + :param dict swaggerTypes: The key is attribute name and the value is attribute type. + :param dict attributeMap: The key is attribute name and the value is json key in definition. """ - self.swaggerTypes = { - - 'id': 'long', - - + self.swagger_types = { + 'id': 'int', 'name': 'str' - } - self.attributeMap = { - + self.attribute_map = { 'id': 'id', - 'name': 'name' - } - - self.id = None # long + self.id = None # int - self.name = None # str + self.name = None # str def __repr__(self): @@ -60,3 +54,5 @@ class Category(object): properties.append('{prop}={val!r}'.format(prop=p, val=self.__dict__[p])) return '<{name} {props}>'.format(name=__name__, props=' '.join(properties)) + + diff --git a/samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/models/order.py b/samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/models/order.py index 528d477ac6e4..8a84ee81bea6 100644 --- a/samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/models/order.py +++ b/samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/models/order.py @@ -18,72 +18,53 @@ Copyright 2015 Reverb Technologies, Inc. """ class Order(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. + """ def __init__(self): """ - Attributes: - swaggerTypes (dict): The key is attribute name and the value is attribute type. - attributeMap (dict): The key is attribute name and the value is json key in definition. + Swagger model + + :param dict swaggerTypes: The key is attribute name and the value is attribute type. + :param dict attributeMap: The key is attribute name and the value is json key in definition. """ - self.swaggerTypes = { - - 'id': 'long', - - - 'pet_id': 'long', - - + self.swagger_types = { + 'id': 'int', + 'pet_id': 'int', 'quantity': 'int', - - 'ship_date': 'DateTime', - - 'status': 'str', - - 'complete': 'bool' - } - self.attributeMap = { - + self.attribute_map = { 'id': 'id', - 'pet_id': 'petId', - 'quantity': 'quantity', - 'ship_date': 'shipDate', - 'status': 'status', - 'complete': 'complete' - } - - self.id = None # long + self.id = None # int - self.pet_id = None # long + self.pet_id = None # int - self.quantity = None # int + self.quantity = None # int - self.ship_date = None # DateTime + self.ship_date = None # DateTime - #Order Status - - self.status = None # str + # Order Status + self.status = None # str - self.complete = None # bool + self.complete = None # bool def __repr__(self): @@ -93,3 +74,5 @@ class Order(object): properties.append('{prop}={val!r}'.format(prop=p, val=self.__dict__[p])) return '<{name} {props}>'.format(name=__name__, props=' '.join(properties)) + + diff --git a/samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/models/pet.py b/samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/models/pet.py index b7b2dc69621c..af667e424897 100644 --- a/samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/models/pet.py +++ b/samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/models/pet.py @@ -18,72 +18,53 @@ Copyright 2015 Reverb Technologies, Inc. """ class Pet(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. + """ def __init__(self): """ - Attributes: - swaggerTypes (dict): The key is attribute name and the value is attribute type. - attributeMap (dict): The key is attribute name and the value is json key in definition. + Swagger model + + :param dict swaggerTypes: The key is attribute name and the value is attribute type. + :param dict attributeMap: The key is attribute name and the value is json key in definition. """ - self.swaggerTypes = { - - 'id': 'long', - - + self.swagger_types = { + 'id': 'int', 'category': 'Category', - - 'name': 'str', - - 'photo_urls': 'list[str]', - - 'tags': 'list[Tag]', - - 'status': 'str' - } - self.attributeMap = { - + self.attribute_map = { 'id': 'id', - 'category': 'category', - 'name': 'name', - 'photo_urls': 'photoUrls', - 'tags': 'tags', - 'status': 'status' - } - - self.id = None # long + self.id = None # int - self.category = None # Category + self.category = None # Category - self.name = None # str + self.name = None # str - self.photo_urls = None # list[str] + self.photo_urls = None # list[str] - self.tags = None # list[Tag] + self.tags = None # list[Tag] - #pet status in the store - - self.status = None # str + # pet status in the store + self.status = None # str def __repr__(self): @@ -93,3 +74,5 @@ class Pet(object): properties.append('{prop}={val!r}'.format(prop=p, val=self.__dict__[p])) return '<{name} {props}>'.format(name=__name__, props=' '.join(properties)) + + diff --git a/samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/models/tag.py b/samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/models/tag.py index f0bade25983a..08918be37fb2 100644 --- a/samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/models/tag.py +++ b/samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/models/tag.py @@ -18,39 +18,33 @@ Copyright 2015 Reverb Technologies, Inc. """ class Tag(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. + """ def __init__(self): """ - Attributes: - swaggerTypes (dict): The key is attribute name and the value is attribute type. - attributeMap (dict): The key is attribute name and the value is json key in definition. + Swagger model + + :param dict swaggerTypes: The key is attribute name and the value is attribute type. + :param dict attributeMap: The key is attribute name and the value is json key in definition. """ - self.swaggerTypes = { - - 'id': 'long', - - + self.swagger_types = { + 'id': 'int', 'name': 'str' - } - self.attributeMap = { - + self.attribute_map = { 'id': 'id', - 'name': 'name' - } - - self.id = None # long + self.id = None # int - self.name = None # str + self.name = None # str def __repr__(self): @@ -60,3 +54,5 @@ class Tag(object): properties.append('{prop}={val!r}'.format(prop=p, val=self.__dict__[p])) return '<{name} {props}>'.format(name=__name__, props=' '.join(properties)) + + diff --git a/samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/models/user.py b/samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/models/user.py index 59a169fe97bf..b218c720fae0 100644 --- a/samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/models/user.py +++ b/samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/models/user.py @@ -18,88 +18,63 @@ Copyright 2015 Reverb Technologies, Inc. """ class User(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. + """ def __init__(self): """ - Attributes: - swaggerTypes (dict): The key is attribute name and the value is attribute type. - attributeMap (dict): The key is attribute name and the value is json key in definition. + Swagger model + + :param dict swaggerTypes: The key is attribute name and the value is attribute type. + :param dict attributeMap: The key is attribute name and the value is json key in definition. """ - self.swaggerTypes = { - - 'id': 'long', - - + self.swagger_types = { + 'id': 'int', 'username': 'str', - - 'first_name': 'str', - - 'last_name': 'str', - - 'email': 'str', - - 'password': 'str', - - 'phone': 'str', - - 'user_status': 'int' - } - self.attributeMap = { - + self.attribute_map = { 'id': 'id', - 'username': 'username', - 'first_name': 'firstName', - 'last_name': 'lastName', - 'email': 'email', - 'password': 'password', - 'phone': 'phone', - 'user_status': 'userStatus' - } - - self.id = None # long + self.id = None # int - self.username = None # str + self.username = None # str - self.first_name = None # str + self.first_name = None # str - self.last_name = None # str + self.last_name = None # str - self.email = None # str + self.email = None # str - self.password = None # str + self.password = None # str - self.phone = None # str + self.phone = None # str - #User Status - - self.user_status = None # int + # User Status + self.user_status = None # int def __repr__(self): @@ -109,3 +84,5 @@ class User(object): properties.append('{prop}={val!r}'.format(prop=p, val=self.__dict__[p])) return '<{name} {props}>'.format(name=__name__, props=' '.join(properties)) + + diff --git a/samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/pet_api.py b/samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/pet_api.py deleted file mode 100644 index b9d38108718a..000000000000 --- a/samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/pet_api.py +++ /dev/null @@ -1,551 +0,0 @@ -#!/usr/bin/env python -# coding: utf-8 - -""" -PetApi.py -Copyright 2015 Reverb Technologies, Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - -NOTE: This class is auto generated by the swagger code generator program. Do not edit the class manually. -""" -import sys -import os -import urllib - -from models import * - - -class PetApi(object): - - def __init__(self, apiClient): - self.apiClient = apiClient - - - - def update_pet(self, **kwargs): - """Update an existing pet - - - Args: - body, Pet: Pet object that needs to be added to the store (required) - - - Returns: - """ - - allParams = ['body'] - - params = locals() - for (key, val) in params['kwargs'].iteritems(): - if key not in allParams: - raise TypeError("Got an unexpected keyword argument '%s' to method update_pet" % key) - params[key] = val - del params['kwargs'] - - resourcePath = '/pet' - resourcePath = resourcePath.replace('{format}', 'json') - method = 'PUT' - - queryParams = {} - headerParams = {} - formParams = {} - files = {} - bodyParam = None - - accepts = ['application/json', 'application/xml'] - headerParams['Accept'] = ', '.join(accepts) - - content_types = ['application/json', 'application/xml'] - headerParams['Content-Type'] = content_types[0] if len(content_types) > 0 else 'application/json' - - - - - - - - - - - if ('body' in params): - bodyParam = params['body'] - - - postData = (formParams if formParams else bodyParam) - - response = self.apiClient.callAPI(resourcePath, method, queryParams, - postData, headerParams, files=files) - - - - - - def add_pet(self, **kwargs): - """Add a new pet to the store - - - Args: - body, Pet: Pet object that needs to be added to the store (required) - - - Returns: - """ - - allParams = ['body'] - - params = locals() - for (key, val) in params['kwargs'].iteritems(): - if key not in allParams: - raise TypeError("Got an unexpected keyword argument '%s' to method add_pet" % key) - params[key] = val - del params['kwargs'] - - resourcePath = '/pet' - resourcePath = resourcePath.replace('{format}', 'json') - method = 'POST' - - queryParams = {} - headerParams = {} - formParams = {} - files = {} - bodyParam = None - - accepts = ['application/json', 'application/xml'] - headerParams['Accept'] = ', '.join(accepts) - - content_types = ['application/json', 'application/xml'] - headerParams['Content-Type'] = content_types[0] if len(content_types) > 0 else 'application/json' - - - - - - - - - - - if ('body' in params): - bodyParam = params['body'] - - - postData = (formParams if formParams else bodyParam) - - response = self.apiClient.callAPI(resourcePath, method, queryParams, - postData, headerParams, files=files) - - - - - - def find_pets_by_status(self, **kwargs): - """Finds Pets by status - Multiple status values can be provided with comma seperated strings - - Args: - status, list[str]: Status values that need to be considered for filter (required) - - - Returns: list[Pet] - """ - - allParams = ['status'] - - params = locals() - for (key, val) in params['kwargs'].iteritems(): - if key not in allParams: - raise TypeError("Got an unexpected keyword argument '%s' to method find_pets_by_status" % key) - params[key] = val - del params['kwargs'] - - resourcePath = '/pet/findByStatus' - resourcePath = resourcePath.replace('{format}', 'json') - method = 'GET' - - queryParams = {} - headerParams = {} - formParams = {} - files = {} - bodyParam = None - - accepts = ['application/json', 'application/xml'] - headerParams['Accept'] = ', '.join(accepts) - - content_types = [] - headerParams['Content-Type'] = content_types[0] if len(content_types) > 0 else 'application/json' - - - if ('status' in params): - queryParams['status'] = self.apiClient.toPathValue(params['status']) - - - - - - - - - - - postData = (formParams if formParams else bodyParam) - - response = self.apiClient.callAPI(resourcePath, method, queryParams, - postData, headerParams, files=files) - - - if not response: - return None - - responseObject = self.apiClient.deserialize(response, 'list[Pet]') - return responseObject - - - - - def find_pets_by_tags(self, **kwargs): - """Finds Pets by tags - Muliple tags can be provided with comma seperated strings. Use tag1, tag2, tag3 for testing. - - Args: - tags, list[str]: Tags to filter by (required) - - - Returns: list[Pet] - """ - - allParams = ['tags'] - - params = locals() - for (key, val) in params['kwargs'].iteritems(): - if key not in allParams: - raise TypeError("Got an unexpected keyword argument '%s' to method find_pets_by_tags" % key) - params[key] = val - del params['kwargs'] - - resourcePath = '/pet/findByTags' - resourcePath = resourcePath.replace('{format}', 'json') - method = 'GET' - - queryParams = {} - headerParams = {} - formParams = {} - files = {} - bodyParam = None - - accepts = ['application/json', 'application/xml'] - headerParams['Accept'] = ', '.join(accepts) - - content_types = [] - headerParams['Content-Type'] = content_types[0] if len(content_types) > 0 else 'application/json' - - - if ('tags' in params): - queryParams['tags'] = self.apiClient.toPathValue(params['tags']) - - - - - - - - - - - postData = (formParams if formParams else bodyParam) - - response = self.apiClient.callAPI(resourcePath, method, queryParams, - postData, headerParams, files=files) - - - if not response: - return None - - responseObject = self.apiClient.deserialize(response, 'list[Pet]') - return responseObject - - - - - def get_pet_by_id(self, **kwargs): - """Find pet by ID - Returns a pet when ID < 10. ID > 10 or nonintegers will simulate API error conditions - - Args: - pet_id, long: ID of pet that needs to be fetched (required) - - - Returns: Pet - """ - - allParams = ['pet_id'] - - params = locals() - for (key, val) in params['kwargs'].iteritems(): - if key not in allParams: - raise TypeError("Got an unexpected keyword argument '%s' to method get_pet_by_id" % key) - params[key] = val - del params['kwargs'] - - resourcePath = '/pet/{petId}' - resourcePath = resourcePath.replace('{format}', 'json') - method = 'GET' - - queryParams = {} - headerParams = {} - formParams = {} - files = {} - bodyParam = None - - accepts = ['application/json', 'application/xml'] - headerParams['Accept'] = ', '.join(accepts) - - content_types = [] - headerParams['Content-Type'] = content_types[0] if len(content_types) > 0 else 'application/json' - - - - - - - if ('pet_id' in params): - replacement = str(self.apiClient.toPathValue(params['pet_id'])) - replacement = urllib.quote(replacement) - resourcePath = resourcePath.replace('{' + 'petId' + '}', - replacement) - - - - - - - postData = (formParams if formParams else bodyParam) - - response = self.apiClient.callAPI(resourcePath, method, queryParams, - postData, headerParams, files=files) - - - if not response: - return None - - responseObject = self.apiClient.deserialize(response, 'Pet') - return responseObject - - - - - def update_pet_with_form(self, **kwargs): - """Updates a pet in the store with form data - - - Args: - pet_id, str: ID of pet that needs to be updated (required) - name, str: Updated name of the pet (required) - status, str: Updated status of the pet (required) - - - Returns: - """ - - allParams = ['pet_id', 'name', 'status'] - - params = locals() - for (key, val) in params['kwargs'].iteritems(): - if key not in allParams: - raise TypeError("Got an unexpected keyword argument '%s' to method update_pet_with_form" % key) - params[key] = val - del params['kwargs'] - - resourcePath = '/pet/{petId}' - resourcePath = resourcePath.replace('{format}', 'json') - method = 'POST' - - queryParams = {} - headerParams = {} - formParams = {} - files = {} - bodyParam = None - - accepts = ['application/json', 'application/xml'] - headerParams['Accept'] = ', '.join(accepts) - - content_types = ['application/x-www-form-urlencoded'] - headerParams['Content-Type'] = content_types[0] if len(content_types) > 0 else 'application/json' - - - - - - - if ('pet_id' in params): - replacement = str(self.apiClient.toPathValue(params['pet_id'])) - replacement = urllib.quote(replacement) - resourcePath = resourcePath.replace('{' + 'petId' + '}', - replacement) - - - - if ('name' in params): - formParams['name'] = params['name'] - - if ('status' in params): - formParams['status'] = params['status'] - - - - - postData = (formParams if formParams else bodyParam) - - response = self.apiClient.callAPI(resourcePath, method, queryParams, - postData, headerParams, files=files) - - - - - - def delete_pet(self, **kwargs): - """Deletes a pet - - - Args: - api_key, str: (required) - pet_id, long: Pet id to delete (required) - - - Returns: - """ - - allParams = ['api_key', 'pet_id'] - - params = locals() - for (key, val) in params['kwargs'].iteritems(): - if key not in allParams: - raise TypeError("Got an unexpected keyword argument '%s' to method delete_pet" % key) - params[key] = val - del params['kwargs'] - - resourcePath = '/pet/{petId}' - resourcePath = resourcePath.replace('{format}', 'json') - method = 'DELETE' - - queryParams = {} - headerParams = {} - formParams = {} - files = {} - bodyParam = None - - accepts = ['application/json', 'application/xml'] - headerParams['Accept'] = ', '.join(accepts) - - content_types = [] - headerParams['Content-Type'] = content_types[0] if len(content_types) > 0 else 'application/json' - - - - - if ('api_key' in params): - headerParams['api_key'] = params['api_key'] - - - - if ('pet_id' in params): - replacement = str(self.apiClient.toPathValue(params['pet_id'])) - replacement = urllib.quote(replacement) - resourcePath = resourcePath.replace('{' + 'petId' + '}', - replacement) - - - - - - - postData = (formParams if formParams else bodyParam) - - response = self.apiClient.callAPI(resourcePath, method, queryParams, - postData, headerParams, files=files) - - - - - - def upload_file(self, **kwargs): - """uploads an image - - - Args: - pet_id, long: ID of pet to update (required) - additional_metadata, str: Additional data to pass to server (required) - file, file: file to upload (required) - - - Returns: - """ - - allParams = ['pet_id', 'additional_metadata', 'file'] - - params = locals() - for (key, val) in params['kwargs'].iteritems(): - if key not in allParams: - raise TypeError("Got an unexpected keyword argument '%s' to method upload_file" % key) - params[key] = val - del params['kwargs'] - - resourcePath = '/pet/{petId}/uploadImage' - resourcePath = resourcePath.replace('{format}', 'json') - method = 'POST' - - queryParams = {} - headerParams = {} - formParams = {} - files = {} - bodyParam = None - - accepts = ['application/json', 'application/xml'] - headerParams['Accept'] = ', '.join(accepts) - - content_types = ['multipart/form-data'] - headerParams['Content-Type'] = content_types[0] if len(content_types) > 0 else 'application/json' - - - - - - - if ('pet_id' in params): - replacement = str(self.apiClient.toPathValue(params['pet_id'])) - replacement = urllib.quote(replacement) - resourcePath = resourcePath.replace('{' + 'petId' + '}', - replacement) - - - - if ('additional_metadata' in params): - formParams['additionalMetadata'] = params['additional_metadata'] - - if ('file' in params): - files['file'] = params['file'] - - - - - postData = (formParams if formParams else bodyParam) - - response = self.apiClient.callAPI(resourcePath, method, queryParams, - postData, headerParams, files=files) - - - - - - - diff --git a/samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/rest.py b/samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/rest.py new file mode 100644 index 000000000000..06b817da7570 --- /dev/null +++ b/samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/rest.py @@ -0,0 +1,223 @@ +# coding: utf-8 +import sys +import io +import json + +# python 2 and python 3 compatibility library +from six import iteritems + +try: + import urllib3 +except ImportError: + raise ImportError('Swagger python client requires urllib3.') + +try: + # for python3 + from urllib.parse import urlencode +except ImportError: + # for python2 + from urllib import urlencode + + +class RESTResponse(io.IOBase): + + def __init__(self, resp): + self.urllib3_response = resp + self.status = resp.status + self.reason = resp.reason + self.data = resp.data + + def getheaders(self): + """ + Returns a dictionary of the response headers. + """ + return self.urllib3_response.getheaders() + + def getheader(self, name, default=None): + """ + Returns a given response header. + """ + return self.urllib3_response.getheader(name, default) + +class RESTClientObject(object): + + def __init__(self, pools_size=4): + self.pool_manager = urllib3.PoolManager( + num_pools=pools_size + ) + + def request(self, method, url, query_params=None, headers=None, + body=None, post_params=None): + """ + :param method: http request method + :param url: http request url + :param query_params: query parameters in the url + :param headers: http request headers + :param body: request json body, for `application/json` + :param post_params: request post parameters, `application/x-www-form-urlencode` + and `multipart/form-data` + :param raw_response: if return the raw response + """ + method = method.upper() + assert method in ['GET', 'HEAD', 'DELETE', 'POST', 'PUT', 'PATCH'] + + if post_params and body: + raise ValueError("body parameter cannot be used with post_params parameter.") + + post_params = post_params or {} + headers = headers or {} + + if 'Content-Type' not in headers: + headers['Content-Type'] = 'application/json' + + # For `POST`, `PUT`, `PATCH` + if method in ['POST', 'PUT', 'PATCH']: + if query_params: + url += '?' + urlencode(query_params) + if headers['Content-Type'] == 'application/json': + r = self.pool_manager.request(method, url, + body=json.dumps(body), + headers=headers) + if headers['Content-Type'] == 'application/x-www-form-urlencoded': + r = self.pool_manager.request(method, url, + fields=post_params, + encode_multipart=False, + headers=headers) + if headers['Content-Type'] == 'multipart/form-data': + # 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, + headers=headers) + # For `GET`, `HEAD`, `DELETE` + else: + r = self.pool_manager.request(method, url, + fields=query_params, + headers=headers) + r = RESTResponse(r) + + if r.status not in range(200, 206): + raise ErrorResponse(r) + + return self.process_response(r) + + def process_response(self, response): + # In the python 3, the response.data is bytes. + # we need to decode it to string. + if sys.version_info > (3,): + data = response.data.decode('utf8') + else: + data = response.data + try: + resp = json.loads(data) + except ValueError: + resp = data + + return resp + + def GET(self, url, headers=None, query_params=None): + return self.request("GET", url, headers=headers, query_params=query_params) + + def HEAD(self, url, headers=None, query_params=None): + return self.request("HEAD", url, headers=headers, query_params=query_params) + + def DELETE(self, url, headers=None, query_params=None): + return self.request("DELETE", url, headers=headers, query_params=query_params) + + def POST(self, url, headers=None, post_params=None, body=None): + return self.request("POST", url, headers=headers, post_params=post_params, body=body) + + def PUT(self, url, headers=None, post_params=None, body=None): + return self.request("PUT", url, headers=headers, post_params=post_params, body=body) + + def PATCH(self, url, headers=None, post_params=None, body=None): + return self.request("PATCH", url, headers=headers, post_params=post_params, body=body) + + +class ErrorResponse(Exception): + """ + Non-2xx HTTP response + """ + + def __init__(self, http_resp): + self.status = http_resp.status + self.reason = http_resp.reason + self.body = http_resp.data + self.headers = http_resp.getheaders() + + # In the python 3, the self.body is bytes. + # we need to decode it to string. + if sys.version_info > (3,): + data = self.body.decode('utf8') + else: + data = self.body + + try: + self.body = json.loads(data) + except ValueError: + self.body = data + + def __str__(self): + """ + Custom error response messages + """ + return "({0})\nReason: {1}\nHeader: {2}\nBody: {3}\n".\ + format(self.status, self.reason, self.headers, self.body) + +class RESTClient(object): + """ + A class with all class methods to perform JSON requests. + """ + + IMPL = RESTClientObject() + + @classmethod + def request(cls, *n, **kw): + """ + Perform a REST request and parse the response. + """ + return cls.IMPL.request(*n, **kw) + + @classmethod + def GET(cls, *n, **kw): + """ + Perform a GET request using `RESTClient.request()`. + """ + return cls.IMPL.GET(*n, **kw) + + @classmethod + def HEAD(cls, *n, **kw): + """ + Perform a HEAD request using `RESTClient.request()`. + """ + return cls.IMPL.GET(*n, **kw) + + @classmethod + def POST(cls, *n, **kw): + """ + Perform a POST request using `RESTClient.request()` + """ + return cls.IMPL.POST(*n, **kw) + + @classmethod + def PUT(cls, *n, **kw): + """ + Perform a PUT request using `RESTClient.request()` + """ + return cls.IMPL.PUT(*n, **kw) + + @classmethod + def PATCH(cls, *n, **kw): + """ + Perform a PATCH request using `RESTClient.request()` + """ + return cls.IMPL.PATCH(*n, **kw) + + @classmethod + def DELETE(cls, *n, **kw): + """ + Perform a DELETE request using `RESTClient.request()` + """ + return cls.IMPL.DELETE(*n, **kw) diff --git a/samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/store_api.py b/samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/store_api.py deleted file mode 100644 index b2de83e85da0..000000000000 --- a/samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/store_api.py +++ /dev/null @@ -1,289 +0,0 @@ -#!/usr/bin/env python -# coding: utf-8 - -""" -StoreApi.py -Copyright 2015 Reverb Technologies, Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - -NOTE: This class is auto generated by the swagger code generator program. Do not edit the class manually. -""" -import sys -import os -import urllib - -from models import * - - -class StoreApi(object): - - def __init__(self, apiClient): - self.apiClient = apiClient - - - - def get_inventory(self, **kwargs): - """Returns pet inventories by status - Returns a map of status codes to quantities - - Args: - - - Returns: map(String, int) - """ - - allParams = [] - - params = locals() - for (key, val) in params['kwargs'].iteritems(): - if key not in allParams: - raise TypeError("Got an unexpected keyword argument '%s' to method get_inventory" % key) - params[key] = val - del params['kwargs'] - - resourcePath = '/store/inventory' - resourcePath = resourcePath.replace('{format}', 'json') - method = 'GET' - - queryParams = {} - headerParams = {} - formParams = {} - files = {} - bodyParam = None - - accepts = ['application/json', 'application/xml'] - headerParams['Accept'] = ', '.join(accepts) - - content_types = [] - headerParams['Content-Type'] = content_types[0] if len(content_types) > 0 else 'application/json' - - - - - - - - - - - - postData = (formParams if formParams else bodyParam) - - response = self.apiClient.callAPI(resourcePath, method, queryParams, - postData, headerParams, files=files) - - - if not response: - return None - - responseObject = self.apiClient.deserialize(response, 'map(String, int)') - return responseObject - - - - - def place_order(self, **kwargs): - """Place an order for a pet - - - Args: - body, Order: order placed for purchasing the pet (required) - - - Returns: Order - """ - - allParams = ['body'] - - params = locals() - for (key, val) in params['kwargs'].iteritems(): - if key not in allParams: - raise TypeError("Got an unexpected keyword argument '%s' to method place_order" % key) - params[key] = val - del params['kwargs'] - - resourcePath = '/store/order' - resourcePath = resourcePath.replace('{format}', 'json') - method = 'POST' - - queryParams = {} - headerParams = {} - formParams = {} - files = {} - bodyParam = None - - accepts = ['application/json', 'application/xml'] - headerParams['Accept'] = ', '.join(accepts) - - content_types = [] - headerParams['Content-Type'] = content_types[0] if len(content_types) > 0 else 'application/json' - - - - - - - - - - - if ('body' in params): - bodyParam = params['body'] - - - postData = (formParams if formParams else bodyParam) - - response = self.apiClient.callAPI(resourcePath, method, queryParams, - postData, headerParams, files=files) - - - if not response: - return None - - responseObject = self.apiClient.deserialize(response, 'Order') - return responseObject - - - - - def get_order_by_id(self, **kwargs): - """Find purchase order by ID - For valid response try integer IDs with value <= 5 or > 10. Other values will generated exceptions - - Args: - order_id, str: ID of pet that needs to be fetched (required) - - - Returns: Order - """ - - allParams = ['order_id'] - - params = locals() - for (key, val) in params['kwargs'].iteritems(): - if key not in allParams: - raise TypeError("Got an unexpected keyword argument '%s' to method get_order_by_id" % key) - params[key] = val - del params['kwargs'] - - resourcePath = '/store/order/{orderId}' - resourcePath = resourcePath.replace('{format}', 'json') - method = 'GET' - - queryParams = {} - headerParams = {} - formParams = {} - files = {} - bodyParam = None - - accepts = ['application/json', 'application/xml'] - headerParams['Accept'] = ', '.join(accepts) - - content_types = [] - headerParams['Content-Type'] = content_types[0] if len(content_types) > 0 else 'application/json' - - - - - - - if ('order_id' in params): - replacement = str(self.apiClient.toPathValue(params['order_id'])) - replacement = urllib.quote(replacement) - resourcePath = resourcePath.replace('{' + 'orderId' + '}', - replacement) - - - - - - - postData = (formParams if formParams else bodyParam) - - response = self.apiClient.callAPI(resourcePath, method, queryParams, - postData, headerParams, files=files) - - - if not response: - return None - - responseObject = self.apiClient.deserialize(response, 'Order') - return responseObject - - - - - def delete_order(self, **kwargs): - """Delete purchase order by ID - For valid response try integer IDs with value < 1000. Anything above 1000 or nonintegers will generate API errors - - Args: - order_id, str: ID of the order that needs to be deleted (required) - - - Returns: - """ - - allParams = ['order_id'] - - params = locals() - for (key, val) in params['kwargs'].iteritems(): - if key not in allParams: - raise TypeError("Got an unexpected keyword argument '%s' to method delete_order" % key) - params[key] = val - del params['kwargs'] - - resourcePath = '/store/order/{orderId}' - resourcePath = resourcePath.replace('{format}', 'json') - method = 'DELETE' - - queryParams = {} - headerParams = {} - formParams = {} - files = {} - bodyParam = None - - accepts = ['application/json', 'application/xml'] - headerParams['Accept'] = ', '.join(accepts) - - content_types = [] - headerParams['Content-Type'] = content_types[0] if len(content_types) > 0 else 'application/json' - - - - - - - if ('order_id' in params): - replacement = str(self.apiClient.toPathValue(params['order_id'])) - replacement = urllib.quote(replacement) - resourcePath = resourcePath.replace('{' + 'orderId' + '}', - replacement) - - - - - - - postData = (formParams if formParams else bodyParam) - - response = self.apiClient.callAPI(resourcePath, method, queryParams, - postData, headerParams, files=files) - - - - - - - diff --git a/samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/swagger.py b/samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/swagger.py index 10ac54d527d1..549106014e3c 100644 --- a/samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/swagger.py +++ b/samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/swagger.py @@ -6,118 +6,109 @@ server communication, and is invariant across implementations. Specifics of the methods and models for each application are generated from the Swagger templates.""" -import sys +from __future__ import absolute_import +from . import models +from .rest import RESTClient + import os import re import urllib -import urllib2 -import httplib import json import datetime import mimetypes import random -import string -import models + +# python 2 and python 3 compatibility library +from six import iteritems + +try: + # for python3 + from urllib.parse import quote +except ImportError: + # for python2 + from urllib import quote class ApiClient(object): - """Generic API client for Swagger client library builds - - Attributes: - host: The base path for the server to call - headerName: a header to pass when making calls to the API - headerValue: a header value to pass when making calls to the API """ - def __init__(self, host=None, headerName=None, headerValue=None): - self.defaultHeaders = {} - if (headerName is not None): - self.defaultHeaders[headerName] = headerValue + Generic API client for Swagger client library builds + + :param host: The base path for the server to call + :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=None, header_name=None, header_value=None): + self.default_headers = {} + if header_name is not None: + self.default_headers[header_name] = header_value self.host = host self.cookie = None - self.boundary = ''.join(random.choice(string.ascii_letters + string.digits) for _ in range(30)) # Set default User-Agent. self.user_agent = 'Python-Swagger' @property def user_agent(self): - return self.defaultHeaders['User-Agent'] + return self.default_headers['User-Agent'] @user_agent.setter def user_agent(self, value): - self.defaultHeaders['User-Agent'] = value + self.default_headers['User-Agent'] = value - def setDefaultHeader(self, headerName, headerValue): - self.defaultHeaders[headerName] = headerValue + def set_default_header(self, header_name, header_value): + self.default_headers[header_name] = header_value - def callAPI(self, resourcePath, method, queryParams, postData, - headerParams=None, files=None): - - url = self.host + resourcePath - - mergedHeaderParams = self.defaultHeaders.copy() - mergedHeaderParams.update(headerParams) - headers = {} - if mergedHeaderParams: - for param, value in mergedHeaderParams.iteritems(): - headers[param] = ApiClient.sanitizeForSerialization(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=None): + # headers parameters + headers = self.default_headers.copy() + headers.update(header_params) if self.cookie: - headers['Cookie'] = ApiClient.sanitizeForSerialization(self.cookie) + headers['Cookie'] = self.cookie + if headers: + headers = ApiClient.sanitize_for_serialization(headers) - data = None + # path parameters + if path_params: + path_params = ApiClient.sanitize_for_serialization(path_params) + for k, v in iteritems(path_params): + replacement = quote(str(self.to_path_value(v))) + resource_path = resource_path.replace('{' + k + '}', replacement) - if queryParams: - # Need to remove None values, these should not be sent - sentQueryParams = {} - for param, value in queryParams.items(): - if value is not None: - sentQueryParams[param] = ApiClient.sanitizeForSerialization(value) - url = url + '?' + urllib.urlencode(sentQueryParams) + # query parameters + if query_params: + query_params = ApiClient.sanitize_for_serialization(query_params) + query_params = {k: self.to_path_value(v) for k, v in iteritems(query_params)} - if method in ['GET']: - #Options to add statements later on and for compatibility - pass + # post parameters + if post_params: + post_params = self.prepare_post_parameters(post_params, files) + post_params = ApiClient.sanitize_for_serialization(post_params) - elif method in ['POST', 'PUT', 'DELETE']: - if postData: - postData = ApiClient.sanitizeForSerialization(postData) - if 'Content-Type' not in headers: - headers['Content-Type'] = 'application/json' - data = json.dumps(postData) - elif headers['Content-Type'] == 'application/json': - data = json.dumps(postData) - elif headers['Content-Type'] == 'multipart/form-data': - data = self.buildMultipartFormData(postData, files) - headers['Content-Type'] = 'multipart/form-data; boundary={0}'.format(self.boundary) - headers['Content-length'] = str(len(data)) - else: - data = urllib.urlencode(postData) + # body + if body: + body = ApiClient.sanitize_for_serialization(body) + # request url + url = self.host + resource_path + + # perform request and return response + response_data = self.request(method, url, query_params=query_params, headers=headers, + post_params=post_params, body=body) + + # deserialize response data + if response: + return self.deserialize(response_data, response) else: - raise Exception('Method ' + method + ' is not recognized.') + return None - request = MethodRequest(method=method, url=url, headers=headers, - data=data) + def to_path_value(self, obj): + """ + Convert a string or object to a path-friendly value + + :param obj: object or string value - # Make the request - response = urllib2.urlopen(request) - if 'Set-Cookie' in response.headers: - self.cookie = response.headers['Set-Cookie'] - string = response.read() - - try: - data = json.loads(string) - except ValueError: # PUT requests don't return anything - data = None - - return data - - def toPathValue(self, obj): - """Convert a string or object to a path-friendly value - Args: - obj -- object or string value - Returns: - string -- quoted value + :return string: quoted value """ if type(obj) == list: return ','.join(obj) @@ -125,12 +116,12 @@ class ApiClient(object): return str(obj) @staticmethod - def sanitizeForSerialization(obj): + def sanitize_for_serialization(obj): """ Sanitize an object for Request. If obj is None, return None. - If obj is str, int, long, float, bool, return directly. + If obj is str, int, float, bool, return directly. If obj is datetime.datetime, datetime.date convert to string in iso8601 format. If obj is list, santize each element in the list. If obj is dict, return the dict. @@ -138,113 +129,80 @@ class ApiClient(object): """ if isinstance(obj, type(None)): return None - elif isinstance(obj, (str, int, long, float, bool, file)): + elif isinstance(obj, (str, int, float, bool, tuple)): return obj elif isinstance(obj, list): - return [ApiClient.sanitizeForSerialization(subObj) for subObj in obj] + return [ApiClient.sanitize_for_serialization(sub_obj) for sub_obj in obj] elif isinstance(obj, (datetime.datetime, datetime.date)): return obj.isoformat() else: if isinstance(obj, dict): - objDict = obj + obj_dict = obj else: - # Convert model obj to dict except attributes `swaggerTypes`, `attributeMap` + # Convert model obj to dict except attributes `swagger_types`, `attribute_map` # and attributes which value is not None. # Convert attribute name to json key in model definition for request. - objDict = {obj.attributeMap[key]: val - for key, val in obj.__dict__.iteritems() - if key != 'swaggerTypes' and key != 'attributeMap' and val is not None} - return {key: ApiClient.sanitizeForSerialization(val) - for (key, val) in objDict.iteritems()} + obj_dict = {obj.attribute_map[key]: val + for key, val in iteritems(obj.__dict__) + if key != 'swagger_types' and key != 'attribute_map' and val is not None} + return {key: ApiClient.sanitize_for_serialization(val) + for key, val in iteritems(obj_dict)} - def buildMultipartFormData(self, postData, files): - def escape_quotes(s): - return s.replace('"', '\\"') + def deserialize(self, obj, obj_class): + """ + Derialize a JSON string into an object. - lines = [] + :param obj: string or object to be deserialized + :param obj_class: class literal for deserialzied object, or string of class name - for name, value in postData.items(): - lines.extend(( - '--{0}'.format(self.boundary), - 'Content-Disposition: form-data; name="{0}"'.format(escape_quotes(name)), - '', - str(value), - )) - - for name, filepath in files.items(): - f = open(filepath, 'r') - filename = filepath.split('/')[-1] - mimetype = mimetypes.guess_type(filename)[0] or 'application/octet-stream' - lines.extend(( - '--{0}'.format(self.boundary), - 'Content-Disposition: form-data; name="{0}"; filename="{1}"'.format(escape_quotes(name), escape_quotes(filename)), - 'Content-Type: {0}'.format(mimetype), - '', - f.read() - )) - - lines.extend(( - '--{0}--'.format(self.boundary), - '' - )) - return '\r\n'.join(lines) - - def deserialize(self, obj, objClass): - """Derialize a JSON string into an object. - - Args: - obj -- string or object to be deserialized - objClass -- class literal for deserialzied object, or string - of class name - Returns: - object -- deserialized object""" - - # Have to accept objClass as string or actual type. Type could be a + :return object: deserialized object + """ + # Have to accept obj_class as string or actual type. Type could be a # native Python type, or one of the model classes. - if type(objClass) == str: - if 'list[' in objClass: - match = re.match('list\[(.*)\]', objClass) - subClass = match.group(1) - return [self.deserialize(subObj, subClass) for subObj in obj] + if type(obj_class) == str: + if 'list[' in obj_class: + match = re.match('list\[(.*)\]', obj_class) + sub_class = match.group(1) + return [self.deserialize(sub_obj, sub_class) for sub_obj in obj] - if (objClass in ['int', 'float', 'long', 'dict', 'list', 'str', 'bool', 'datetime']): - objClass = eval(objClass) + if obj_class in ['int', 'float', 'dict', 'list', 'str', 'bool', 'datetime']: + obj_class = eval(obj_class) else: # not a native type, must be model class - objClass = eval('models.' + objClass) + obj_class = eval('models.' + obj_class) - if objClass in [int, long, float, dict, list, str, bool]: - return objClass(obj) - elif objClass == datetime: + if obj_class in [int, float, dict, list, str, bool]: + return obj_class(obj) + elif obj_class == datetime: return self.__parse_string_to_datetime(obj) - instance = objClass() + instance = obj_class() - for attr, attrType in instance.swaggerTypes.iteritems(): - if obj is not None and instance.attributeMap[attr] in obj and type(obj) in [list, dict]: - value = obj[instance.attributeMap[attr]] - if attrType in ['str', 'int', 'long', 'float', 'bool']: - attrType = eval(attrType) + for attr, attr_type in iteritems(instance.swagger_types): + if obj is not None and instance.attribute_map[attr] in obj and type(obj) in [list, dict]: + value = obj[instance.attribute_map[attr]] + if attr_type in ['str', 'int', 'float', 'bool']: + attr_type = eval(attr_type) try: - value = attrType(value) + value = attr_type(value) except UnicodeEncodeError: value = unicode(value) except TypeError: value = value setattr(instance, attr, value) - elif (attrType == 'datetime'): + elif attr_type == 'datetime': setattr(instance, attr, self.__parse_string_to_datetime(value)) - elif 'list[' in attrType: - match = re.match('list\[(.*)\]', attrType) - subClass = match.group(1) - subValues = [] + elif 'list[' in attr_type: + match = re.match('list\[(.*)\]', attr_type) + sub_class = match.group(1) + sub_values = [] if not value: setattr(instance, attr, None) else: - for subValue in value: - subValues.append(self.deserialize(subValue, subClass)) - setattr(instance, attr, subValues) + for sub_value in value: + sub_values.append(self.deserialize(sub_value, sub_class)) + setattr(instance, attr, sub_values) else: - setattr(instance, attr, self.deserialize(value, attrType)) + setattr(instance, attr, self.deserialize(value, attr_type)) return instance @@ -260,16 +218,42 @@ class ApiClient(object): except ImportError: return string -class MethodRequest(urllib2.Request): - def __init__(self, *args, **kwargs): - """Construct a MethodRequest. Usage is the same as for - `urllib2.Request` except it also takes an optional `method` - keyword argument. If supplied, `method` will be used instead of - the default.""" + def request(self, method, url, query_params=None, headers=None, post_params=None, body=None): + """ + Perform http request using RESTClient. + """ + if method == "GET": + return RESTClient.GET(url, query_params=query_params, headers=headers) + elif method == "HEAD": + return RESTClient.HEAD(url, query_params=query_params, headers=headers) + elif method == "POST": + return RESTClient.POST(url, headers=headers, post_params=post_params, body=body) + elif method == "PUT": + return RESTClient.PUT(url, headers=headers, post_params=post_params, body=body) + elif method == "PATCH": + return RESTClient.PATCH(url, headers=headers, post_params=post_params, body=body) + elif method == "DELETE": + return RESTClient.DELETE(url, query_params=query_params, headers=headers) + else: + raise ValueError("http method must be `GET`, `HEAD`, `POST`, `PATCH`, `PUT` or `DELETE`") + + def prepare_post_parameters(self, post_params=None, files=None): + params = {} + + if post_params: + params.update(post_params) + + if files: + for k, v in iteritems(files): + with open(v, 'rb') as f: + filename = os.path.basename(f.name) + filedata = f.read() + mimetype = mimetypes.guess_type(filename)[0] or 'application/octet-stream' + params[k] = tuple([filename, filedata, mimetype]) + + return params + + + - if 'method' in kwargs: - self.method = kwargs.pop('method') - return urllib2.Request.__init__(self, *args, **kwargs) - def get_method(self): - return getattr(self, 'method', urllib2.Request.get_method(self)) diff --git a/samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/user_api.py b/samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/user_api.py deleted file mode 100644 index d36a95514bde..000000000000 --- a/samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/user_api.py +++ /dev/null @@ -1,526 +0,0 @@ -#!/usr/bin/env python -# coding: utf-8 - -""" -UserApi.py -Copyright 2015 Reverb Technologies, Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - -NOTE: This class is auto generated by the swagger code generator program. Do not edit the class manually. -""" -import sys -import os -import urllib - -from models import * - - -class UserApi(object): - - def __init__(self, apiClient): - self.apiClient = apiClient - - - - def create_user(self, **kwargs): - """Create user - This can only be done by the logged in user. - - Args: - body, User: Created user object (required) - - - Returns: - """ - - allParams = ['body'] - - params = locals() - for (key, val) in params['kwargs'].iteritems(): - if key not in allParams: - raise TypeError("Got an unexpected keyword argument '%s' to method create_user" % key) - params[key] = val - del params['kwargs'] - - resourcePath = '/user' - resourcePath = resourcePath.replace('{format}', 'json') - method = 'POST' - - queryParams = {} - headerParams = {} - formParams = {} - files = {} - bodyParam = None - - accepts = ['application/json', 'application/xml'] - headerParams['Accept'] = ', '.join(accepts) - - content_types = [] - headerParams['Content-Type'] = content_types[0] if len(content_types) > 0 else 'application/json' - - - - - - - - - - - if ('body' in params): - bodyParam = params['body'] - - - postData = (formParams if formParams else bodyParam) - - response = self.apiClient.callAPI(resourcePath, method, queryParams, - postData, headerParams, files=files) - - - - - - def create_users_with_array_input(self, **kwargs): - """Creates list of users with given input array - - - Args: - body, list[User]: List of user object (required) - - - Returns: - """ - - allParams = ['body'] - - params = locals() - for (key, val) in params['kwargs'].iteritems(): - if key not in allParams: - raise TypeError("Got an unexpected keyword argument '%s' to method create_users_with_array_input" % key) - params[key] = val - del params['kwargs'] - - resourcePath = '/user/createWithArray' - resourcePath = resourcePath.replace('{format}', 'json') - method = 'POST' - - queryParams = {} - headerParams = {} - formParams = {} - files = {} - bodyParam = None - - accepts = ['application/json', 'application/xml'] - headerParams['Accept'] = ', '.join(accepts) - - content_types = [] - headerParams['Content-Type'] = content_types[0] if len(content_types) > 0 else 'application/json' - - - - - - - - - - - if ('body' in params): - bodyParam = params['body'] - - - postData = (formParams if formParams else bodyParam) - - response = self.apiClient.callAPI(resourcePath, method, queryParams, - postData, headerParams, files=files) - - - - - - def create_users_with_list_input(self, **kwargs): - """Creates list of users with given input array - - - Args: - body, list[User]: List of user object (required) - - - Returns: - """ - - allParams = ['body'] - - params = locals() - for (key, val) in params['kwargs'].iteritems(): - if key not in allParams: - raise TypeError("Got an unexpected keyword argument '%s' to method create_users_with_list_input" % key) - params[key] = val - del params['kwargs'] - - resourcePath = '/user/createWithList' - resourcePath = resourcePath.replace('{format}', 'json') - method = 'POST' - - queryParams = {} - headerParams = {} - formParams = {} - files = {} - bodyParam = None - - accepts = ['application/json', 'application/xml'] - headerParams['Accept'] = ', '.join(accepts) - - content_types = [] - headerParams['Content-Type'] = content_types[0] if len(content_types) > 0 else 'application/json' - - - - - - - - - - - if ('body' in params): - bodyParam = params['body'] - - - postData = (formParams if formParams else bodyParam) - - response = self.apiClient.callAPI(resourcePath, method, queryParams, - postData, headerParams, files=files) - - - - - - def login_user(self, **kwargs): - """Logs user into the system - - - Args: - username, str: The user name for login (required) - password, str: The password for login in clear text (required) - - - Returns: str - """ - - allParams = ['username', 'password'] - - params = locals() - for (key, val) in params['kwargs'].iteritems(): - if key not in allParams: - raise TypeError("Got an unexpected keyword argument '%s' to method login_user" % key) - params[key] = val - del params['kwargs'] - - resourcePath = '/user/login' - resourcePath = resourcePath.replace('{format}', 'json') - method = 'GET' - - queryParams = {} - headerParams = {} - formParams = {} - files = {} - bodyParam = None - - accepts = ['application/json', 'application/xml'] - headerParams['Accept'] = ', '.join(accepts) - - content_types = [] - headerParams['Content-Type'] = content_types[0] if len(content_types) > 0 else 'application/json' - - - if ('username' in params): - queryParams['username'] = self.apiClient.toPathValue(params['username']) - - if ('password' in params): - queryParams['password'] = self.apiClient.toPathValue(params['password']) - - - - - - - - - - - postData = (formParams if formParams else bodyParam) - - response = self.apiClient.callAPI(resourcePath, method, queryParams, - postData, headerParams, files=files) - - - if not response: - return None - - responseObject = self.apiClient.deserialize(response, 'str') - return responseObject - - - - - def logout_user(self, **kwargs): - """Logs out current logged in user session - - - Args: - - - Returns: - """ - - allParams = [] - - params = locals() - for (key, val) in params['kwargs'].iteritems(): - if key not in allParams: - raise TypeError("Got an unexpected keyword argument '%s' to method logout_user" % key) - params[key] = val - del params['kwargs'] - - resourcePath = '/user/logout' - resourcePath = resourcePath.replace('{format}', 'json') - method = 'GET' - - queryParams = {} - headerParams = {} - formParams = {} - files = {} - bodyParam = None - - accepts = ['application/json', 'application/xml'] - headerParams['Accept'] = ', '.join(accepts) - - content_types = [] - headerParams['Content-Type'] = content_types[0] if len(content_types) > 0 else 'application/json' - - - - - - - - - - - - postData = (formParams if formParams else bodyParam) - - response = self.apiClient.callAPI(resourcePath, method, queryParams, - postData, headerParams, files=files) - - - - - - def get_user_by_name(self, **kwargs): - """Get user by user name - - - Args: - username, str: The name that needs to be fetched. Use user1 for testing. (required) - - - Returns: User - """ - - allParams = ['username'] - - params = locals() - for (key, val) in params['kwargs'].iteritems(): - if key not in allParams: - raise TypeError("Got an unexpected keyword argument '%s' to method get_user_by_name" % key) - params[key] = val - del params['kwargs'] - - resourcePath = '/user/{username}' - resourcePath = resourcePath.replace('{format}', 'json') - method = 'GET' - - queryParams = {} - headerParams = {} - formParams = {} - files = {} - bodyParam = None - - accepts = ['application/json', 'application/xml'] - headerParams['Accept'] = ', '.join(accepts) - - content_types = [] - headerParams['Content-Type'] = content_types[0] if len(content_types) > 0 else 'application/json' - - - - - - - if ('username' in params): - replacement = str(self.apiClient.toPathValue(params['username'])) - replacement = urllib.quote(replacement) - resourcePath = resourcePath.replace('{' + 'username' + '}', - replacement) - - - - - - - postData = (formParams if formParams else bodyParam) - - response = self.apiClient.callAPI(resourcePath, method, queryParams, - postData, headerParams, files=files) - - - if not response: - return None - - responseObject = self.apiClient.deserialize(response, 'User') - return responseObject - - - - - def update_user(self, **kwargs): - """Updated user - This can only be done by the logged in user. - - Args: - username, str: name that need to be deleted (required) - body, User: Updated user object (required) - - - Returns: - """ - - allParams = ['username', 'body'] - - params = locals() - for (key, val) in params['kwargs'].iteritems(): - if key not in allParams: - raise TypeError("Got an unexpected keyword argument '%s' to method update_user" % key) - params[key] = val - del params['kwargs'] - - resourcePath = '/user/{username}' - resourcePath = resourcePath.replace('{format}', 'json') - method = 'PUT' - - queryParams = {} - headerParams = {} - formParams = {} - files = {} - bodyParam = None - - accepts = ['application/json', 'application/xml'] - headerParams['Accept'] = ', '.join(accepts) - - content_types = [] - headerParams['Content-Type'] = content_types[0] if len(content_types) > 0 else 'application/json' - - - - - - - if ('username' in params): - replacement = str(self.apiClient.toPathValue(params['username'])) - replacement = urllib.quote(replacement) - resourcePath = resourcePath.replace('{' + 'username' + '}', - replacement) - - - - - - if ('body' in params): - bodyParam = params['body'] - - - postData = (formParams if formParams else bodyParam) - - response = self.apiClient.callAPI(resourcePath, method, queryParams, - postData, headerParams, files=files) - - - - - - def delete_user(self, **kwargs): - """Delete user - This can only be done by the logged in user. - - Args: - username, str: The name that needs to be deleted (required) - - - Returns: - """ - - allParams = ['username'] - - params = locals() - for (key, val) in params['kwargs'].iteritems(): - if key not in allParams: - raise TypeError("Got an unexpected keyword argument '%s' to method delete_user" % key) - params[key] = val - del params['kwargs'] - - resourcePath = '/user/{username}' - resourcePath = resourcePath.replace('{format}', 'json') - method = 'DELETE' - - queryParams = {} - headerParams = {} - formParams = {} - files = {} - bodyParam = None - - accepts = ['application/json', 'application/xml'] - headerParams['Accept'] = ', '.join(accepts) - - content_types = [] - headerParams['Content-Type'] = content_types[0] if len(content_types) > 0 else 'application/json' - - - - - - - if ('username' in params): - replacement = str(self.apiClient.toPathValue(params['username'])) - replacement = urllib.quote(replacement) - resourcePath = resourcePath.replace('{' + 'username' + '}', - replacement) - - - - - - - postData = (formParams if formParams else bodyParam) - - response = self.apiClient.callAPI(resourcePath, method, queryParams, - postData, headerParams, files=files) - - - - - - - diff --git a/samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/util.py b/samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/util.py new file mode 100644 index 000000000000..1137a5d2d23c --- /dev/null +++ b/samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/util.py @@ -0,0 +1,17 @@ +from six import iteritems + +def remove_none(obj): + if isinstance(obj, (list, tuple, set)): + return type(obj)(remove_none(x) for x in obj if x is not None) + elif isinstance(obj, dict): + return type(obj)((remove_none(k), remove_none(v)) + for k, v in iteritems(obj) if k is not None and v is not None) + else: + return obj + + +def inspect_vars(obj): + if not hasattr(obj, '__dict__'): + return obj + else: + return {k: inspect_vars(getattr(obj, k)) for k in dir(obj)} diff --git a/samples/client/petstore/python/SwaggerPetstore-python/dev-requirements.txt b/samples/client/petstore/python/SwaggerPetstore-python/dev-requirements.txt new file mode 100644 index 000000000000..01a2e25f1c7b --- /dev/null +++ b/samples/client/petstore/python/SwaggerPetstore-python/dev-requirements.txt @@ -0,0 +1,4 @@ +nose +tox +coverage +randomize diff --git a/samples/client/petstore/python/SwaggerPetstore-python/pom.xml b/samples/client/petstore/python/SwaggerPetstore-python/pom.xml index c06d3a1cdf63..e21eb2f5a96a 100644 --- a/samples/client/petstore/python/SwaggerPetstore-python/pom.xml +++ b/samples/client/petstore/python/SwaggerPetstore-python/pom.xml @@ -26,21 +26,6 @@ exec-maven-plugin 1.2.1 - - nose-install - pre-integration-test - - exec - - - pip - - install - nose - --user - - - nose-test integration-test @@ -48,9 +33,9 @@ exec - nosetests + make - -v + test diff --git a/samples/client/petstore/python/SwaggerPetstore-python/setup.cfg b/samples/client/petstore/python/SwaggerPetstore-python/setup.cfg new file mode 100644 index 000000000000..e62af0800348 --- /dev/null +++ b/samples/client/petstore/python/SwaggerPetstore-python/setup.cfg @@ -0,0 +1,11 @@ +[nosetests] +logging-clear-handlers=true +verbosity=2 +randomize=true +exe=true +with-coverage=true +cover-package=SwaggerPetstore +cover-erase=true + +[flake8] +max-line-length=99 diff --git a/samples/client/petstore/python/SwaggerPetstore-python/setup.py b/samples/client/petstore/python/SwaggerPetstore-python/setup.py index 14d6a73b3b14..fd0b786efa3d 100644 --- a/samples/client/petstore/python/SwaggerPetstore-python/setup.py +++ b/samples/client/petstore/python/SwaggerPetstore-python/setup.py @@ -12,7 +12,7 @@ from setuptools import setup, find_packages # Try reading the setuptools documentation: # http://pypi.python.org/pypi/setuptools -REQUIRES = [] +REQUIRES = ["urllib3 >= 1.10", "six >= 1.9"] setup( name="SwaggerPetstore", @@ -30,3 +30,11 @@ setup( ) + + + + + + + + diff --git a/samples/client/petstore/python/SwaggerPetstore-python/tests/test_pet_api.py b/samples/client/petstore/python/SwaggerPetstore-python/tests/test_pet_api.py index b6088ae34b95..f0b8ab03d810 100644 --- a/samples/client/petstore/python/SwaggerPetstore-python/tests/test_pet_api.py +++ b/samples/client/petstore/python/SwaggerPetstore-python/tests/test_pet_api.py @@ -10,9 +10,9 @@ $ nosetests -v import os import time import unittest -import urllib2 import SwaggerPetstore +from SwaggerPetstore.rest import ErrorResponse HOST = 'http://petstore.swagger.io/v2' @@ -31,15 +31,15 @@ class PetApiTests(unittest.TestCase): def setUpModels(self): self.category = SwaggerPetstore.Category() - self.category.id = 1010 + self.category.id = int(time.time()) self.category.name = "dog" self.tag = SwaggerPetstore.Tag() - self.tag.id = 1010 + self.tag.id = int(time.time()) self.tag.name = "blank" self.pet = SwaggerPetstore.Pet() - self.pet.id = 1010 + self.pet.id = int(time.time()) self.pet.name = "hello kity" - self.pet.photo_urls = ["sample urls"] + self.pet.photo_urls = ["http://foo.bar.com/1", "http://foo.bar.com/2"] self.pet.status = "sold" self.pet.category = self.category self.pet.tags = [self.tag] @@ -49,48 +49,55 @@ class PetApiTests(unittest.TestCase): self.test_file_dir = os.path.realpath(self.test_file_dir) self.foo = os.path.join(self.test_file_dir, "foo.png") - def test_1_add_pet(self): - try: - self.pet_api.add_pet(body=self.pet) - except (urllib2.HTTPError, urllib2.URLError) as e: - self.fail("add_pet() raised {0} unexpectedly".format(type(e))) + def test_add_pet_and_get_pet_by_id(self): + self.pet_api.add_pet(body=self.pet) - def test_2_get_pet_by_id(self): - self.assertEqual( - dir(self.pet_api.get_pet_by_id(pet_id=self.pet.id)), - dir(self.pet) - ) + fetched = self.pet_api.get_pet_by_id(pet_id=self.pet.id) + self.assertIsNotNone(fetched) + self.assertEqual(self.pet.id, fetched.id) + self.assertIsNotNone(fetched.category) + self.assertEqual(self.pet.category.name, fetched.category.name) - def test_3_update_pet(self): - try: - self.pet.name = "hello kity with updated" - self.pet_api.update_pet(body=self.pet) - except (urllib2.HTTPError, urllib2.URLError) as e: - self.fail("update_pet() raised {0} unexpectedly".format(type(e))) + def test_update_pet(self): + self.pet.name = "hello kity with updated" + self.pet_api.update_pet(body=self.pet) - def test_4_find_pets_by_status(self): + fetched = self.pet_api.get_pet_by_id(pet_id=self.pet.id) + self.assertIsNotNone(fetched) + self.assertEqual(self.pet.id, fetched.id) + self.assertEqual(self.pet.name, fetched.name) + self.assertIsNotNone(fetched.category) + self.assertEqual(fetched.category.name, self.pet.category.name) + + def test_find_pets_by_status(self): + self.pet_api.add_pet(body=self.pet) + self.assertIn( - dir(self.pet), - map(dir, self.pet_api.find_pets_by_status(status=["sold"])) + self.pet.id, + list(map(lambda x: getattr(x, 'id'), self.pet_api.find_pets_by_status(status=[self.pet.status]))) ) - def test_5_find_pets_by_tags(self): + def test_find_pets_by_tags(self): + self.pet_api.add_pet(body=self.pet) + self.assertIn( - dir(self.pet), - map(dir, self.pet_api.find_pets_by_tags(tags=["blank"])) + self.pet.id, + list(map(lambda x: getattr(x, 'id'), self.pet_api.find_pets_by_tags(tags=[self.tag.name]))) ) - def test_6_update_pet_with_form(self): - try: - name = "hello kity with form updated" - status = "pending" - self.pet_api.update_pet_with_form( - pet_id=self.pet.id, name=name, status=status - ) - except (urllib2.HTTPError, urllib2.URLError) as e: - self.fail("update_pet_with_form() raised {0} unexpectedly".format(type(e))) + def test_update_pet_with_form(self): + self.pet_api.add_pet(body=self.pet) + + name = "hello kity with form updated" + status = "pending" + self.pet_api.update_pet_with_form(pet_id=self.pet.id, name=name, status=status) - def test_7_upload_file(self): + fetched = self.pet_api.get_pet_by_id(pet_id=self.pet.id) + self.assertEqual(self.pet.id, fetched.id) + self.assertEqual(name, fetched.name) + self.assertEqual(status, fetched.status) + + def test_upload_file(self): try: additional_metadata = "special" self.pet_api.upload_file( @@ -98,16 +105,23 @@ class PetApiTests(unittest.TestCase): additional_metadata=additional_metadata, file=self.foo ) - except (urllib2.HTTPError, urllib2.URLError) as e: + except ErrorResponse as e: self.fail("upload_file() raised {0} unexpectedly".format(type(e))) - def test_8_delete_pet(self): + def test_delete_pet(self): + self.pet_api.add_pet(body=self.pet) + self.pet_api.delete_pet(pet_id=self.pet.id, api_key="special-key") + try: - api_key = "special-key" - self.pet_api.delete_pet(pet_id=self.pet.id, api_key=api_key) - except (urllib2.HTTPError, urllib2.URLError) as e: - self.fail("delete_pet() raised {0} unexpectedly".format(type(e))) - + self.pet_api.get_pet_by_id(pet_id=self.pet.id) + raise "expected an error" + except ErrorResponse as e: + self.assertEqual(404, e.status) if __name__ == '__main__': unittest.main() + + + + + diff --git a/samples/client/petstore/python/SwaggerPetstore-python/tox.ini b/samples/client/petstore/python/SwaggerPetstore-python/tox.ini new file mode 100644 index 000000000000..9f62f3845bf5 --- /dev/null +++ b/samples/client/petstore/python/SwaggerPetstore-python/tox.ini @@ -0,0 +1,10 @@ +[tox] +envlist = py27, py34 + +[testenv] +deps= -r{toxinidir}/dev-requirements.txt +commands= + nosetests \ + [] +setenv = + PYTHONWARNINGS=always::DeprecationWarning