From 09bfecf76eddd6310c3356d2beb3a657fde3bb8d Mon Sep 17 00:00:00 2001 From: James Ebentier Date: Fri, 6 Feb 2015 11:32:15 -0800 Subject: [PATCH] Python: adding in support for formParams as well as multipart-form requests --- .../src/main/resources/python/api.mustache | 18 ++++++- .../main/resources/python/swagger.mustache | 52 +++++++++++++++++-- 2 files changed, 63 insertions(+), 7 deletions(-) diff --git a/modules/swagger-codegen/src/main/resources/python/api.mustache b/modules/swagger-codegen/src/main/resources/python/api.mustache index 1650effd991..4a5b7fba410 100644 --- a/modules/swagger-codegen/src/main/resources/python/api.mustache +++ b/modules/swagger-codegen/src/main/resources/python/api.mustache @@ -58,6 +58,10 @@ class {{classname}}(object): queryParams = {} headerParams = {} + formParams = {} + files = {} + bodyParam = None + $headerParams['Accept'] = '{{#produces}}{{mediaType}}{{#hasMore}},{{/hasMore}}{{/produces}}'; $headerParams['Content-Type'] = '{{#consumes}}{{mediaType}}{{#hasMore}},{{/hasMore}}{{/consumes}}'; @@ -78,10 +82,20 @@ class {{classname}}(object): replacement) {{/pathParams}} - postData = (params['body'] if 'body' in params else None) + {{#formParams}} + if ('{{paramName}}' in params): + {{#notFile}}formParams['{{paramName}}'] = params['{{paramName}}']{{/notFile}}{{#isFile}}files['{{paramName}}'] = 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) + postData, headerParams, files=files) {{#returnType}} if not response: diff --git a/modules/swagger-codegen/src/main/resources/python/swagger.mustache b/modules/swagger-codegen/src/main/resources/python/swagger.mustache index e62f854c7bf..59b6d38fbd6 100644 --- a/modules/swagger-codegen/src/main/resources/python/swagger.mustache +++ b/modules/swagger-codegen/src/main/resources/python/swagger.mustache @@ -12,6 +12,9 @@ import urllib2 import httplib import json import datetime +import mimetypes +import random +import string from models import * @@ -26,9 +29,10 @@ class ApiClient: self.apiKey = apiKey self.apiServer = apiServer self.cookie = None + self.boundary = ''.join(random.choice(string.ascii_letters + string.digits) for _ in range(30)) def callAPI(self, resourcePath, method, queryParams, postData, - headerParams=None): + headerParams=None, files=None): url = self.apiServer + resourcePath headers = {} @@ -36,7 +40,6 @@ class ApiClient: for param, value in headerParams.iteritems(): headers[param] = value - #headers['Content-type'] = 'application/json' headers['api_key'] = self.apiKey if self.cookie: @@ -60,9 +63,16 @@ class ApiClient: elif method in ['POST', 'PUT', 'DELETE']: if postData: - headers['Content-type'] = 'application/json' - data = self.sanitizeForSerialization(postData) - data = json.dumps(data) + postData = self.sanitizeForSerialization(postData) + if 'Content-type' not in headers: + 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) else: raise Exception('Method ' + method + ' is not recognized.') @@ -124,6 +134,38 @@ class ApiClient: elif type(postData) not in safeToDump: data = json.dumps(postData.__dict__) + def buildMultipartFormData(self, postData, files): + def escape_quotes(s): + return s.replace('"', '\\"') + + lines = [] + + 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.