diff --git a/src/main/resources/python/api.mustache b/src/main/resources/python/api.mustache index 1b304e81d96..09a33ec88a9 100644 --- a/src/main/resources/python/api.mustache +++ b/src/main/resources/python/api.mustache @@ -59,8 +59,11 @@ class {{classname}}(object): queryParams = {} headerParams = {} formParams = {} + files = [] bodyParam = None + headerParams['Content-type'] = '{{#consumes}}{{mediaType}}{{#hasMore}},{{/hasMore}}{{/consumes}}' + {{#queryParams}} if ('{{paramName}}' in params): queryParams['{{paramName}}'] = self.apiClient.toPathValue(params['{{paramName}}']) @@ -80,10 +83,14 @@ class {{classname}}(object): {{#formParams}} if ('{{paramName}}' in params): + {{#notFile}} formParams['{{paramName}}'] = params['{{paramName}}'] + {{/notFile}} + {{#isFile}} + files.append(('{{paramName}}', params['{{paramName}}'])) + {{/isFile}} {{/formParams}} - if formParams: - headerParams['Content-type'] = 'application/x-www-form-urlencoded' + {{newline}} {{#bodyParam}} if ('{{paramName}}' in params): @@ -93,7 +100,7 @@ class {{classname}}(object): 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/src/main/resources/python/swagger.mustache b/src/main/resources/python/swagger.mustache index b4e1fab3595..e87b834d786 100644 --- a/src/main/resources/python/swagger.mustache +++ b/src/main/resources/python/swagger.mustache @@ -12,6 +12,9 @@ import urllib2 import httplib import json import datetime +import mimetools +import mimetypes +import itertools from models import * @@ -26,9 +29,10 @@ class ApiClient: self.apiKey = apiKey self.apiServer = apiServer self.cookie = None + self.boundary = mimetools.choose_boundary() def callAPI(self, resourcePath, method, queryParams, postData, - headerParams=None): + headerParams=None, files=None): url = self.apiServer + resourcePath headers = {} @@ -60,12 +64,15 @@ class ApiClient: elif method in ['POST', 'PUT', 'DELETE']: if postData: - data = self.sanitizeForSerialization(postData) + postData = self.sanitizeForSerialization(postData) if 'Content-type' not in headers: headers['Content-type'] = 'application/json' - data = json.dumps(data) + data = json.dumps(postData) + else if headers['Content-type'] == 'multipart/form': + headers['Content-type'] = 'multipart/form; boundry=%s' % self.boundary + data = self.buildMultipartFormData(postData, files) else: - data = urllib.urlencode(data) + data = urllib.urlencode(postData) else: raise Exception('Method ' + method + ' is not recognized.') @@ -127,6 +134,31 @@ class ApiClient: elif type(postData) not in safeToDump: data = json.dumps(postData.__dict__) + def buildMultipartFormData(self, postData, files): + parts = [] + part_boundary = '--' + self.boundary + parts.extend( + [part_boundary, 'Content-Disposition: form-data; name="%s"' % name, '', value] + for name, value in postData.items() + ) + + file_tuples = [] + for fieldname, file_path in files: + filename = file_path.split('/')[-1] + f = open(file_path, 'r') + mimetype = mimetypes.guess_type(filename)[0] or 'application/octet-stream' + body = f.read() + file_tuples.append((fieldname, filename, mimetype, body)) + parts.extend( + [part_boundary, 'Content-Disposition file; name="%s"; filename="%s"' % (fieldname, filename), 'Content-Type: %s' % content_type, '', body] + for fieldname, filename, content_type, body in file_tuples + ) + + flattened = list(itertools.chain(*parts)) + flattened.append('--' + self.boundary + '--') + flattened.append('') + return '\r\n'.join(flattened) + def deserialize(self, obj, objClass): """Derialize a JSON string into an object.