Skip to content

Commit e955c9d

Browse files
committed
MultipartForm: getting the file uploading working
1 parent 63bb202 commit e955c9d

File tree

2 files changed

+38
-31
lines changed

2 files changed

+38
-31
lines changed

src/main/resources/python/api.mustache

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ class {{classname}}(object):
5959
queryParams = {}
6060
headerParams = {}
6161
formParams = {}
62-
files = []
62+
files = {}
6363
bodyParam = None
6464

6565
headerParams['Content-type'] = '{{#consumes}}{{mediaType}}{{#hasMore}},{{/hasMore}}{{/consumes}}'
@@ -87,9 +87,9 @@ class {{classname}}(object):
8787
formParams['{{paramName}}'] = params['{{paramName}}']
8888
{{/notFile}}
8989
{{#isFile}}
90-
files.append(('{{paramName}}', params['{{paramName}}']))
90+
files['{{paramName}}'] = params['{{paramName}}']
9191
{{/isFile}}
92-
{{newline}}
92+
{{#hasMore}}{{newline}}{{/hasMore}}
9393
{{/formParams}}
9494

9595
{{#bodyParam}}

src/main/resources/python/swagger.mustache

Lines changed: 35 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@ import urllib2
1212
import httplib
1313
import json
1414
import datetime
15-
import mimetools
1615
import mimetypes
17-
import itertools
16+
import random
17+
import string
1818

1919
from models import *
2020

@@ -29,7 +29,7 @@ class ApiClient:
2929
self.apiKey = apiKey
3030
self.apiServer = apiServer
3131
self.cookie = None
32-
self.boundary = mimetools.choose_boundary()
32+
self.boundary = ''.join(random.choice(string.ascii_letters + string.digits) for _ in range(30))
3333

3434
def callAPI(self, resourcePath, method, queryParams, postData,
3535
headerParams=None, files=None):
@@ -40,7 +40,6 @@ class ApiClient:
4040
for param, value in headerParams.iteritems():
4141
headers[param] = value
4242

43-
#headers['Content-type'] = 'application/json'
4443
headers['api_key'] = self.apiKey
4544

4645
if self.cookie:
@@ -68,9 +67,10 @@ class ApiClient:
6867
if 'Content-type' not in headers:
6968
headers['Content-type'] = 'application/json'
7069
data = json.dumps(postData)
71-
elif headers['Content-type'] == 'multipart/form':
72-
headers['Content-type'] = 'multipart/form; boundry=%s' % self.boundary
70+
elif headers['Content-type'] == 'multipart/form-data':
7371
data = self.buildMultipartFormData(postData, files)
72+
headers['Content-type'] = 'multipart/form-data; boundary={0}'.format(self.boundary)
73+
headers['Content-length'] = str(len(data))
7474
else:
7575
data = urllib.urlencode(postData)
7676

@@ -135,29 +135,36 @@ class ApiClient:
135135
data = json.dumps(postData.__dict__)
136136

137137
def buildMultipartFormData(self, postData, files):
138-
parts = []
139-
part_boundary = '--' + self.boundary
140-
parts.extend(
141-
[part_boundary, 'Content-Disposition: form-data; name="%s"' % name, '', value]
142-
for name, value in postData.items()
143-
)
144-
145-
file_tuples = []
146-
for fieldname, file_path in files:
147-
filename = file_path.split('/')[-1]
148-
f = open(file_path, 'r')
138+
def escape_quotes(s):
139+
return s.replace('"', '\\"')
140+
141+
lines = []
142+
143+
for name, value in postData.items():
144+
lines.extend((
145+
'--{0}'.format(self.boundary),
146+
'Content-Disposition: form-data; name="{0}"'.format(escape_quotes(name)),
147+
'',
148+
str(value),
149+
))
150+
151+
for name, filepath in files.items():
152+
f = open(filepath, 'r')
153+
filename = filepath.split('/')[-1]
149154
mimetype = mimetypes.guess_type(filename)[0] or 'application/octet-stream'
150-
body = f.read()
151-
file_tuples.append((fieldname, filename, mimetype, body))
152-
parts.extend(
153-
[part_boundary, 'Content-Disposition file; name="%s"; filename="%s"' % (fieldname, filename), 'Content-Type: %s' % content_type, '', body]
154-
for fieldname, filename, content_type, body in file_tuples
155-
)
156-
157-
flattened = list(itertools.chain(*parts))
158-
flattened.append('--' + self.boundary + '--')
159-
flattened.append('')
160-
return '\r\n'.join(flattened)
155+
lines.extend((
156+
'--{0}'.format(self.boundary),
157+
'Content-Disposition: form-data; name="{0}"; filename="{1}"'.format(escape_quotes(name), escape_quotes(filename)),
158+
'Content-Type: {0}'.format(mimetype),
159+
'',
160+
f.read()
161+
))
162+
163+
lines.extend((
164+
'--{0}--'.format(self.boundary),
165+
''
166+
))
167+
return '\r\n'.join(lines)
161168

162169
def deserialize(self, obj, objClass):
163170
"""Derialize a JSON string into an object.

0 commit comments

Comments
 (0)