diff --git a/modules/swagger-codegen/src/main/resources/php/Swagger.mustache b/modules/swagger-codegen/src/main/resources/php/Swagger.mustache index 7e1f24f49b6..1aace837b1d 100644 --- a/modules/swagger-codegen/src/main/resources/php/Swagger.mustache +++ b/modules/swagger-codegen/src/main/resources/php/Swagger.mustache @@ -37,6 +37,16 @@ class APIClient { $this->apiServer = $apiServer; } + /** + * @param integer $seconds Number of seconds before timing out [set to 0 for no timeout] + */ + public function setTimeout($seconds) { + if (!is_numeric($seconds)) { + throw new Exception('Timeout variable must be numeric.'); + } + $this->curl_timout = $seconds; + } + /** * @param string $resourcePath path to method endpoint @@ -65,14 +75,16 @@ class APIClient { $headers[] = "api_key: " . $this->apiKey; } - if (is_object($postData) or is_array($postData)) { + if (strpos($headers['Content-Type'], "multipart/form-data") < 0 and (is_object($postData) or is_array($postData))) { $postData = json_encode($this->sanitizeForSerialization($postData)); } $url = $this->apiServer . $resourcePath; $curl = curl_init(); - curl_setopt($curl, CURLOPT_TIMEOUT, 5); + if ($this->curl_timout) { + curl_setopt($curl, CURLOPT_TIMEOUT, $this->curl_timout); + } // return the result on success, rather than just TRUE curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); curl_setopt($curl, CURLOPT_HTTPHEADER, $headers); diff --git a/modules/swagger-codegen/src/main/resources/php/api.mustache b/modules/swagger-codegen/src/main/resources/php/api.mustache index 82ea7174032..d2349b18522 100644 --- a/modules/swagger-codegen/src/main/resources/php/api.mustache +++ b/modules/swagger-codegen/src/main/resources/php/api.mustache @@ -44,6 +44,7 @@ class {{classname}} { $method = "{{httpMethod}}"; $queryParams = array(); $headerParams = array(); + $formParams = array(); $headerParams['Accept'] = '{{#produces}}{{mediaType}}{{#hasMore}},{{/hasMore}}{{/produces}}'; $headerParams['Content-Type'] = '{{#consumes}}{{mediaType}}{{#hasMore}},{{/hasMore}}{{/consumes}}'; @@ -60,12 +61,21 @@ class {{classname}} { $resourcePath = str_replace("{" . "{{paramName}}" . "}", $this->apiClient->toPathValue(${{paramName}}), $resourcePath); }{{/pathParams}} + {{#formParams}} + if (${{paramName}} != null) { + $formParams[{{paramName}}] = {{#isFile}}'@' . {{/isFile}}${{paramName}} + }{{/formParams}} {{#bodyParams}}// body params $body = null; if (isset(${{paramName}})) { $body = ${{paramName}}; + }{{/bodyParams}} + + $body = $body ?: $formParams; + + if (strpos($headerParams['Content-Type'], "application/x-www-form-urlencoded") > -1) { + $body = http_build_query($body); } - {{/bodyParams}} // make the API Call $response = $this->apiClient->callAPI($resourcePath, $method, 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.