added python3 support

This commit is contained in:
Russell Horton 2012-09-09 23:48:30 -07:00
parent 4c0cd15a40
commit cf53a24271
6 changed files with 404 additions and 0 deletions

View File

@ -0,0 +1,9 @@
#!/usr/bin/env python
"""Add all of the modules in the current directory to __all__"""
import os
__all__ = []
for module in os.listdir(os.path.dirname(__file__)):
if module != '__init__.py' and module[-3:] == '.py':
__all__.append(module[:-3])

View File

@ -0,0 +1,96 @@
#!/usr/bin/env python
"""
WordAPI.py
Copyright 2012 Wordnik, 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
from .models import *
{{#operations}}
class {{classname}}(object):
def __init__(self, apiClient):
self.apiClient = apiClient
{{newline}}
{{#operation}}
def {{nickname}}(self, {{#requiredParams}}{{paramName}}{{#defaultValue}} = None{{/defaultValue}}, {{/requiredParams}}**kwargs):
"""{{summary}}
Args:
{{#allParams}}
{{paramName}}, {{dataType}}: {{description}} {{^optional}}(required){{/optional}}{{#optional}}(optional){{/optional}}
{{newline}}
{{/allParams}}
{{newline}}
Returns: {{returnType}}
"""
allParams = [{{#allParams}}'{{paramName}}'{{#hasMore}}, {{/hasMore}}{{/allParams}}]
params = locals()
for (key, val) in params['kwargs'].items():
if key not in allParams:
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')
method = '{{httpMethod}}'
queryParams = {}
headerParams = {}
{{#queryParams}}
if ('{{paramName}}' in params):
queryParams['{{paramName}}'] = self.apiClient.toPathValue(params['{{paramName}}'])
{{/queryParams}}
{{#headerParams}}
if ('{{paramName}}' in params):
headerParams['{{paramName}}'] = params['{{paramName}}']
{{/headerParams}}
{{#pathParams}}
if ('{{paramName}}' in params):
replacement = str(self.apiClient.toPathValue(params['{{paramName}}']))
resourcePath = resourcePath.replace('{' + '{{baseName}}' + '}',
replacement)
{{/pathParams}}
postData = (params['body'] if 'body' in params else None)
response = self.apiClient.callAPI(resourcePath, method, queryParams,
postData, headerParams)
{{#returnType}}
if not response:
return None
responseObject = self.apiClient.deserialize(response, '{{returnType}}')
return responseObject
{{/returnType}}
{{newline}}
{{newline}}
{{/operation}}
{{newline}}
{{/operations}}
{{newline}}

View File

@ -0,0 +1,40 @@
#!/usr/bin/env python
"""
Copyright 2012 Wordnik, 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.
"""
{{#models}}
{{#model}}
class {{classname}}:
"""NOTE: This class is auto generated by the swagger code generator program.
Do not edit the class manually."""
def __init__(self):
self.swaggerTypes = {
{{#vars}}
'{{name}}': '{{{datatype}}}'{{#hasMore}},
{{/hasMore}}
{{/vars}}{{newline}}
}
{{#vars}}
{{#description}}#{{description}}
{{/description}}
self.{{name}} = None # {{{datatype}}}
{{/vars}}
{{/model}}
{{/models}}

View File

@ -0,0 +1,194 @@
#!/usr/bin/env python
"""Wordnik.com's Swagger generic API client. This client handles the client-
server communication, and is invariant across implementations. Specifics of
the methods and models for each application are generated from the Swagger
templates."""
import sys
import os
import re
import urllib.request, urllib.error, urllib.parse
import http.client
import json
import datetime
from .models import *
class ApiClient:
"""Generic API client for Swagger client library builds"""
def __init__(self, apiKey=None, apiServer=None):
if apiKey == None:
raise Exception('You must pass an apiKey when instantiating the '
'APIClient')
self.apiKey = apiKey
self.apiServer = apiServer
self.cookie = None
def callAPI(self, resourcePath, method, queryParams, postData,
headerParams=None):
url = self.apiServer + resourcePath
headers = {}
if headerParams:
for param, value in headerParams.items():
headers[param] = value
headers['Content-type'] = 'application/json'
headers['api_key'] = self.apiKey
if self.cookie:
headers['Cookie'] = self.cookie
data = None
if method == 'GET':
if queryParams:
# Need to remove None values, these should not be sent
sentQueryParams = {}
for param, value in queryParams.items():
if value != None:
sentQueryParams[param] = value
url = url + '?' + urllib.parse.urlencode(sentQueryParams)
elif method in ['POST', 'PUT', 'DELETE']:
if postData:
headers['Content-type'] = 'application/json'
data = self.sanitizeForSerialization(postData)
data = json.dumps(data)
else:
raise Exception('Method ' + method + ' is not recognized.')
if data:
data = data.encode('utf-8')
requestParams = MethodRequest(method=method, url=url,
headers=headers, data=data)
# Make the request
request = urllib.request.urlopen(requestParams)
encoding = request.headers.get_content_charset()
if not encoding:
encoding = 'iso-8859-1'
response = request.read().decode(encoding)
try:
data = json.loads(response)
except ValueError: # PUT requests don't return anything
data = None
return data
def toPathValue(self, obj):
"""Serialize a list to a CSV string, if necessary.
Args:
obj -- data object to be serialized
Returns:
string -- json serialization of object
"""
if type(obj) == list:
return ','.join(obj)
else:
return obj
def sanitizeForSerialization(self, obj):
"""Dump an object into JSON for POSTing."""
if not obj:
return None
elif type(obj) in [str, int, float, bool]:
return obj
elif type(obj) == list:
return [self.sanitizeForSerialization(subObj) for subObj in obj]
elif type(obj) == datetime.datetime:
return obj.isoformat()
else:
if type(obj) == dict:
objDict = obj
else:
objDict = obj.__dict__
return {key: self.sanitizeForSerialization(val)
for (key, val) in objDict.items()
if key != 'swaggerTypes'}
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
# 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 (objClass in ['int', 'float', 'dict', 'list', 'str']):
objClass = eval(objClass)
else: # not a native type, must be model class
objClass = eval(objClass + '.' + objClass)
if objClass in [str, int, float, bool]:
return objClass(obj)
elif objClass == datetime:
# Server will always return a time stamp in UTC, but with
# trailing +0000 indicating no offset from UTC. So don't process
# last 5 characters.
return datetime.datetime.strptime(obj[:-5],
"%Y-%m-%dT%H:%M:%S.%f")
instance = objClass()
for attr, attrType in instance.swaggerTypes.items():
if attr in obj:
value = obj[attr]
if attrType in ['str', 'int', 'float', 'bool']:
attrType = eval(attrType)
try:
value = attrType(value)
except UnicodeEncodeError:
value = unicode(value)
setattr(instance, attr, value)
elif 'list[' in attrType:
match = re.match('list\[(.*)\]', attrType)
subClass = match.group(1)
subValues = []
if not value:
setattr(instance, attr, None)
else:
for subValue in value:
subValues.append(self.deserialize(subValue,
subClass))
setattr(instance, attr, subValues)
else:
setattr(instance, attr, self.deserialize(value,
objClass))
return instance
class MethodRequest(urllib.request.Request):
def __init__(self, *args, **kwargs):
"""Construct a MethodRequest. Usage is the same as for
`urllib.Request` except it also takes an optional `method`
keyword argument. If supplied, `method` will be used instead of
the default."""
if 'method' in kwargs:
self.method = kwargs.pop('method')
return urllib.request.Request.__init__(self, *args, **kwargs)
def get_method(self):
return getattr(self, 'method', urllib.request.Request.get_method(self))

View File

@ -0,0 +1,17 @@
import com.wordnik.swagger.codegen.BasicPython3Generator
import com.wordnik.swagger.core._
import java.io.File
object Python3PetstoreCodegen extends BasicPython3Generator {
def main(args: Array[String]) = generateClient(args)
override def templateDir = "python3"
override def destinationDir = "samples/petstore/python3"
override def supportingFiles = List(
("__init__.mustache", destinationDir, "__init__.py"),
("swagger.mustache", destinationDir + File.separator + apiPackage.get, "swagger.py"),
("__init__.mustache", destinationDir + File.separator + modelPackage.get, "__init__.py"))
}

View File

@ -0,0 +1,48 @@
/**
* Copyright 2012 Wordnik, 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.
*/
package com.wordnik.swagger.codegen
import com.wordnik.swagger.core._
import java.io.File
object BasicPython3Generator extends BasicPython3Generator {
def main(args: Array[String]) = generateClient(args)
}
class BasicPython3Generator extends BasicPythonGenerator {
// location of templates
override def templateDir = "python3"
// where to write generated code
override def destinationDir = "generated-code/python3"
// Python3 erases int/long distinction
override def typeMapping = Map(
"String" -> "str",
"Int" -> "int",
"Float" -> "float",
"Long" -> "int",
"long" -> "int",
"Double" -> "float",
"Array" -> "list",
"Boolean" -> "bool",
"Date" -> "datetime",
"string" -> "str"
)
}