From e5daa6855c86de4644397e659c0d0497b267f681 Mon Sep 17 00:00:00 2001 From: cbornet Date: Sun, 13 Nov 2016 20:20:28 +0100 Subject: [PATCH] add models support to flask --- bin/flaskConnexion-python2.sh | 3 +- bin/flaskConnexion.sh | 3 +- .../io/swagger/codegen/DefaultCodegen.java | 3 + .../languages/FlaskConnexionCodegen.java | 217 ++++++++++++++- .../resources/flaskConnexion/README.mustache | 2 +- ..._.mustache => __init__controller.mustache} | 0 .../flaskConnexion/__init__model.mustache | 6 + .../resources/flaskConnexion/app.mustache | 21 ++ .../flaskConnexion/base_model_.mustache | 79 ++++++ .../flaskConnexion/controller.mustache | 100 ++++++- .../resources/flaskConnexion/model.mustache | 148 +++++++++++ .../flaskConnexion/param_type.mustache | 1 + .../resources/flaskConnexion/util.mustache | 149 +++++++++++ .../petstore/flaskConnexion-python2/README.md | 2 +- .../petstore/flaskConnexion-python2/app.py | 21 ++ .../controllers/pet_controller.py | 99 ++++++- .../controllers/store_controller.py | 42 +++ .../controllers/user_controller.py | 88 +++++++ .../flaskConnexion-python2/models/__init__.py | 10 + .../models/api_response.py | 116 ++++++++ .../models/base_model_.py | 72 +++++ .../flaskConnexion-python2/models/category.py | 90 +++++++ .../flaskConnexion-python2/models/order.py | 202 ++++++++++++++ .../flaskConnexion-python2/models/pet.py | 208 +++++++++++++++ .../flaskConnexion-python2/models/tag.py | 90 +++++++ .../flaskConnexion-python2/models/user.py | 248 ++++++++++++++++++ .../swagger/swagger.yaml | 10 +- .../petstore/flaskConnexion-python2/util.py | 149 +++++++++++ samples/server/petstore/flaskConnexion/app.py | 21 ++ .../flaskConnexion/controllers/init.py | 0 .../controllers/pet_controller.py | 109 +++++++- .../controllers/store_controller.py | 50 +++- .../controllers/user_controller.py | 104 +++++++- .../server/petstore/flaskConnexion/init.py | 0 .../flaskConnexion/models/__init__.py | 10 + .../flaskConnexion/models/api_response.py | 116 ++++++++ .../flaskConnexion/models/base_model_.py | 75 ++++++ .../flaskConnexion/models/category.py | 90 +++++++ .../petstore/flaskConnexion/models/order.py | 202 ++++++++++++++ .../petstore/flaskConnexion/models/pet.py | 208 +++++++++++++++ .../petstore/flaskConnexion/models/tag.py | 90 +++++++ .../petstore/flaskConnexion/models/user.py | 248 ++++++++++++++++++ .../flaskConnexion/swagger/swagger.yaml | 10 +- .../server/petstore/flaskConnexion/util.py | 149 +++++++++++ 44 files changed, 3615 insertions(+), 46 deletions(-) rename modules/swagger-codegen/src/main/resources/flaskConnexion/{__init__.mustache => __init__controller.mustache} (100%) create mode 100644 modules/swagger-codegen/src/main/resources/flaskConnexion/__init__model.mustache create mode 100644 modules/swagger-codegen/src/main/resources/flaskConnexion/base_model_.mustache create mode 100644 modules/swagger-codegen/src/main/resources/flaskConnexion/model.mustache create mode 100644 modules/swagger-codegen/src/main/resources/flaskConnexion/param_type.mustache create mode 100644 modules/swagger-codegen/src/main/resources/flaskConnexion/util.mustache create mode 100644 samples/server/petstore/flaskConnexion-python2/models/__init__.py create mode 100644 samples/server/petstore/flaskConnexion-python2/models/api_response.py create mode 100644 samples/server/petstore/flaskConnexion-python2/models/base_model_.py create mode 100644 samples/server/petstore/flaskConnexion-python2/models/category.py create mode 100644 samples/server/petstore/flaskConnexion-python2/models/order.py create mode 100644 samples/server/petstore/flaskConnexion-python2/models/pet.py create mode 100644 samples/server/petstore/flaskConnexion-python2/models/tag.py create mode 100644 samples/server/petstore/flaskConnexion-python2/models/user.py create mode 100644 samples/server/petstore/flaskConnexion-python2/util.py delete mode 100644 samples/server/petstore/flaskConnexion/controllers/init.py delete mode 100644 samples/server/petstore/flaskConnexion/init.py create mode 100644 samples/server/petstore/flaskConnexion/models/__init__.py create mode 100644 samples/server/petstore/flaskConnexion/models/api_response.py create mode 100644 samples/server/petstore/flaskConnexion/models/base_model_.py create mode 100644 samples/server/petstore/flaskConnexion/models/category.py create mode 100644 samples/server/petstore/flaskConnexion/models/order.py create mode 100644 samples/server/petstore/flaskConnexion/models/pet.py create mode 100644 samples/server/petstore/flaskConnexion/models/tag.py create mode 100644 samples/server/petstore/flaskConnexion/models/user.py create mode 100644 samples/server/petstore/flaskConnexion/util.py diff --git a/bin/flaskConnexion-python2.sh b/bin/flaskConnexion-python2.sh index 313ef297bf8..579e6d94be2 100755 --- a/bin/flaskConnexion-python2.sh +++ b/bin/flaskConnexion-python2.sh @@ -27,6 +27,7 @@ fi # if you've executed sbt assembly previously it will use that instead. export JAVA_OPTS="${JAVA_OPTS} -XX:MaxPermSize=256M -Xmx1024M -DloggerPath=conf/log4j.properties" #ags="$@ generate -i modules/swagger-codegen/src/test/resources/2_0/petstore.yaml -l python-flask -o samples/server/petstore/flaskConnexion-python2 -DsupportPython2=true" -ags="$@ generate -i modules/swagger-codegen/src/test/resources/2_0/petstore.yaml -l python-flask -o samples/server/petstore/flaskConnexion-python2 -c bin/supportPython2.json" +ags="$@ generate -t modules/swagger-codegen/src/main/resources/flaskConnexion -i modules/swagger-codegen/src/test/resources/2_0/petstore.yaml -l python-flask -o samples/server/petstore/flaskConnexion-python2 -c bin/supportPython2.json" +rm -rf samples/server/petstore/flaskConnexion-python2/* java $JAVA_OPTS -Dservice -jar $executable $ags diff --git a/bin/flaskConnexion.sh b/bin/flaskConnexion.sh index 563718f9061..c09c83b2daa 100755 --- a/bin/flaskConnexion.sh +++ b/bin/flaskConnexion.sh @@ -26,6 +26,7 @@ fi # if you've executed sbt assembly previously it will use that instead. export JAVA_OPTS="${JAVA_OPTS} -XX:MaxPermSize=256M -Xmx1024M -DloggerPath=conf/log4j.properties" -ags="$@ generate -i modules/swagger-codegen/src/test/resources/2_0/petstore.yaml -l python-flask -o samples/server/petstore/flaskConnexion " +ags="$@ generate -t modules/swagger-codegen/src/main/resources/flaskConnexion -i modules/swagger-codegen/src/test/resources/2_0/petstore.yaml -l python-flask -o samples/server/petstore/flaskConnexion " +rm -rf samples/server/petstore/flaskConnexion/* java $JAVA_OPTS -Dservice -jar $executable $ags diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/DefaultCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/DefaultCodegen.java index 63cad401d02..5ccc9b24945 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/DefaultCodegen.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/DefaultCodegen.java @@ -2234,6 +2234,7 @@ public class DefaultCodegen { collectionFormat = "csv"; } CodegenProperty pr = fromProperty("inner", inner); + p.items = pr; p.baseType = pr.datatype; p.isContainer = true; p.isListContainer = true; @@ -2247,6 +2248,7 @@ public class DefaultCodegen { property = new MapProperty(inner); collectionFormat = qp.getCollectionFormat(); CodegenProperty pr = fromProperty("inner", inner); + p.items = pr; p.baseType = pr.datatype; p.isContainer = true; p.isMapContainer = true; @@ -2360,6 +2362,7 @@ public class DefaultCodegen { imports.add(cp.complexType); } imports.add(cp.baseType); + p.items = cp; p.dataType = cp.datatype; p.baseType = cp.complexType; p.isPrimitiveType = cp.isPrimitiveType; diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/FlaskConnexionCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/FlaskConnexionCodegen.java index 2ac51c7e9e1..63e3f3c3705 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/FlaskConnexionCodegen.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/FlaskConnexionCodegen.java @@ -5,17 +5,18 @@ import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.Lists; import com.google.common.collect.Multimap; -import config.ConfigParser; import io.swagger.codegen.*; import io.swagger.models.HttpMethod; import io.swagger.models.Operation; import io.swagger.models.Path; import io.swagger.models.Swagger; +import io.swagger.models.properties.*; import io.swagger.util.Yaml; import java.io.File; import java.util.*; +import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -39,11 +40,13 @@ public class FlaskConnexionCodegen extends DefaultCodegen implements CodegenConf languageSpecificPrimitives.clear(); languageSpecificPrimitives.add("int"); languageSpecificPrimitives.add("float"); - languageSpecificPrimitives.add("list"); + languageSpecificPrimitives.add("List"); + languageSpecificPrimitives.add("Dict"); languageSpecificPrimitives.add("bool"); languageSpecificPrimitives.add("str"); languageSpecificPrimitives.add("datetime"); languageSpecificPrimitives.add("date"); + languageSpecificPrimitives.add("file"); typeMapping.clear(); typeMapping.put("integer", "int"); @@ -51,8 +54,8 @@ public class FlaskConnexionCodegen extends DefaultCodegen implements CodegenConf typeMapping.put("number", "float"); typeMapping.put("long", "int"); typeMapping.put("double", "float"); - typeMapping.put("array", "list"); - typeMapping.put("map", "dict"); + typeMapping.put("array", "List"); + typeMapping.put("map", "Dict"); typeMapping.put("boolean", "bool"); typeMapping.put("string", "str"); typeMapping.put("date", "date"); @@ -63,9 +66,8 @@ public class FlaskConnexionCodegen extends DefaultCodegen implements CodegenConf // set the output folder here outputFolder = "generated-code/connexion"; - modelTemplateFiles.clear(); - apiTemplateFiles.put("controller.mustache", ".py"); + modelTemplateFiles.put("model.mustache", ".py"); /* * Template Location. This is the location which templates will be read from. The generator @@ -102,11 +104,15 @@ public class FlaskConnexionCodegen extends DefaultCodegen implements CodegenConf "", "app.py") ); + supportingFiles.add(new SupportingFile("util.mustache", + "", + "util.py") + ); supportingFiles.add(new SupportingFile("README.mustache", "", "README.md") ); - supportingFiles.add(new SupportingFile("__init__.mustache", + supportingFiles.add(new SupportingFile("__init__controller.mustache", "", "__init__.py") ); @@ -142,14 +148,29 @@ public class FlaskConnexionCodegen extends DefaultCodegen implements CodegenConf if (Boolean.TRUE.equals(additionalProperties.get(SUPPORT_PYTHON2))) { additionalProperties.put(SUPPORT_PYTHON2, Boolean.TRUE); + typeMapping.put("long", "long"); } if(!new java.io.File(controllerPackage + File.separator + defaultController + ".py").exists()) { - supportingFiles.add(new SupportingFile("__init__.mustache", + supportingFiles.add(new SupportingFile("__init__controller.mustache", controllerPackage, "__init__.py") ); } + + supportingFiles.add(new SupportingFile("__init__model.mustache", + modelPackage, + "__init__.py") + ); + + supportingFiles.add(new SupportingFile("base_model_.mustache", + modelPackage, + "base_model_.py") + ); + } + + private static String dropDots(String str) { + return str.replaceAll("\\.", "_"); } @Override @@ -224,6 +245,36 @@ public class FlaskConnexionCodegen extends DefaultCodegen implements CodegenConf return outputFolder + File.separator + apiPackage().replace('.', File.separatorChar); } + @Override + public String getTypeDeclaration(Property p) { + if (p instanceof ArrayProperty) { + ArrayProperty ap = (ArrayProperty) p; + Property inner = ap.getItems(); + return getSwaggerType(p) + "[" + getTypeDeclaration(inner) + "]"; + } else if (p instanceof MapProperty) { + MapProperty mp = (MapProperty) p; + Property inner = mp.getAdditionalProperties(); + + return getSwaggerType(p) + "[str, " + getTypeDeclaration(inner) + "]"; + } + return super.getTypeDeclaration(p); + } + + @Override + public String getSwaggerType(Property p) { + String swaggerType = super.getSwaggerType(p); + String type = null; + if (typeMapping.containsKey(swaggerType)) { + type = typeMapping.get(swaggerType); + if (languageSpecificPrimitives.contains(type)) { + return type; + } + } else { + type = toModelName(swaggerType); + } + return type; + } + @Override public void preprocessSwagger(Swagger swagger) { @@ -333,6 +384,96 @@ public class FlaskConnexionCodegen extends DefaultCodegen implements CodegenConf return super.postProcessSupportingFileData(objs); } + @Override + public String toVarName(String name) { + // sanitize name + name = sanitizeName(name); // FIXME: a parameter should not be assigned. Also declare the methods parameters as 'final'. + + // remove dollar sign + name = name.replaceAll("$", ""); + + // if it's all uppper case, convert to lower case + if (name.matches("^[A-Z_]*$")) { + name = name.toLowerCase(); + } + + // underscore the variable name + // petId => pet_id + name = underscore(name); + + // remove leading underscore + name = name.replaceAll("^_*", ""); + + // for reserved word or word starting with number, append _ + if (isReservedWord(name) || name.matches("^\\d.*")) { + name = escapeReservedWord(name); + } + + return name; + } + + @Override + public String toModelFilename(String name) { + name = sanitizeName(name); // FIXME: a parameter should not be assigned. Also declare the methods parameters as 'final'. + // remove dollar sign + name = name.replaceAll("$", ""); + + // model name cannot use reserved keyword, e.g. return + if (isReservedWord(name)) { + LOGGER.warn(name + " (reserved word) cannot be used as model filename. Renamed to " + underscore(dropDots("model_" + name))); + name = "model_" + name; // e.g. return => ModelReturn (after camelize) + } + + // model name starts with number + if (name.matches("^\\d.*")) { + LOGGER.warn(name + " (model name starts with number) cannot be used as model name. Renamed to " + underscore("model_" + name)); + name = "model_" + name; // e.g. 200Response => Model200Response (after camelize) + } + + if (!StringUtils.isEmpty(modelNamePrefix)) { + name = modelNamePrefix + "_" + name; + } + + if (!StringUtils.isEmpty(modelNameSuffix)) { + name = name + "_" + modelNameSuffix; + } + + // underscore the model file name + // PhoneNumber => phone_number + return underscore(dropDots(name)); + } + + @Override + public String toModelName(String name) { + name = sanitizeName(name); // FIXME: a parameter should not be assigned. Also declare the methods parameters as 'final'. + // remove dollar sign + name = name.replaceAll("$", ""); + + // model name cannot use reserved keyword, e.g. return + if (isReservedWord(name)) { + LOGGER.warn(name + " (reserved word) cannot be used as model name. Renamed to " + camelize("model_" + name)); + name = "model_" + name; // e.g. return => ModelReturn (after camelize) + } + + // model name starts with number + if (name.matches("^\\d.*")) { + LOGGER.warn(name + " (model name starts with number) cannot be used as model name. Renamed to " + camelize("model_" + name)); + name = "model_" + name; // e.g. 200Response => Model200Response (after camelize) + } + + if (!StringUtils.isEmpty(modelNamePrefix)) { + name = modelNamePrefix + "_" + name; + } + + if (!StringUtils.isEmpty(modelNameSuffix)) { + name = name + "_" + modelNameSuffix; + } + + // camelize the model name + // phone_number => PhoneNumber + return camelize(name); + } + @Override public String toOperationId(String operationId) { operationId = super.toOperationId(operationId); // FIXME: a parameter should not be assigned. Also declare the methods parameters as 'final'. @@ -344,6 +485,56 @@ public class FlaskConnexionCodegen extends DefaultCodegen implements CodegenConf return underscore(operationId); } + /** + * Return the default value of the property + * + * @param p Swagger property object + * @return string presentation of the default value of the property + */ + @Override + public String toDefaultValue(Property p) { + if (p instanceof StringProperty) { + StringProperty dp = (StringProperty) p; + if (dp.getDefault() != null) { + return "'" + dp.getDefault() + "'"; + } + } else if (p instanceof BooleanProperty) { + BooleanProperty dp = (BooleanProperty) p; + if (dp.getDefault() != null) { + if (dp.getDefault().toString().equalsIgnoreCase("false")) + return "False"; + else + return "True"; + } + } else if (p instanceof DateProperty) { + // TODO + } else if (p instanceof DateTimeProperty) { + // TODO + } else if (p instanceof DoubleProperty) { + DoubleProperty dp = (DoubleProperty) p; + if (dp.getDefault() != null) { + return dp.getDefault().toString(); + } + } else if (p instanceof FloatProperty) { + FloatProperty dp = (FloatProperty) p; + if (dp.getDefault() != null) { + return dp.getDefault().toString(); + } + } else if (p instanceof IntegerProperty) { + IntegerProperty dp = (IntegerProperty) p; + if (dp.getDefault() != null) { + return dp.getDefault().toString(); + } + } else if (p instanceof LongProperty) { + LongProperty dp = (LongProperty) p; + if (dp.getDefault() != null) { + return dp.getDefault().toString(); + } + } + + return null; + } + @Override public String escapeQuotationMark(String input) { // remove ' to avoid code injection @@ -355,4 +546,14 @@ public class FlaskConnexionCodegen extends DefaultCodegen implements CodegenConf // remove multiline comment return input.replace("'''", "'_'_'"); } + + @Override + public String toModelImport(String name) { + String modelImport = "from "; + if (!"".equals(modelPackage())) { + modelImport += modelPackage() + "."; + } + modelImport += toModelFilename(name)+ " import " + name; + return modelImport; + } } diff --git a/modules/swagger-codegen/src/main/resources/flaskConnexion/README.mustache b/modules/swagger-codegen/src/main/resources/flaskConnexion/README.mustache index d53139b49b2..e037cf1fe15 100644 --- a/modules/swagger-codegen/src/main/resources/flaskConnexion/README.mustache +++ b/modules/swagger-codegen/src/main/resources/flaskConnexion/README.mustache @@ -11,7 +11,7 @@ To run the server, please execute the following: ``` {{#supportPython2}} -sudo pip install -U connexion # install Connexion from PyPI +sudo pip install -U connexion typing # install Connexion and Typing from PyPI python app.py {{/supportPython2}} {{^supportPython2}} diff --git a/modules/swagger-codegen/src/main/resources/flaskConnexion/__init__.mustache b/modules/swagger-codegen/src/main/resources/flaskConnexion/__init__controller.mustache similarity index 100% rename from modules/swagger-codegen/src/main/resources/flaskConnexion/__init__.mustache rename to modules/swagger-codegen/src/main/resources/flaskConnexion/__init__controller.mustache diff --git a/modules/swagger-codegen/src/main/resources/flaskConnexion/__init__model.mustache b/modules/swagger-codegen/src/main/resources/flaskConnexion/__init__model.mustache new file mode 100644 index 00000000000..764211e2120 --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/flaskConnexion/__init__model.mustache @@ -0,0 +1,6 @@ +# coding: utf-8 + +from __future__ import absolute_import +# import models into model package +{{#models}}{{#model}}from .{{classFilename}} import {{classname}}{{/model}} +{{/models}} \ No newline at end of file diff --git a/modules/swagger-codegen/src/main/resources/flaskConnexion/app.mustache b/modules/swagger-codegen/src/main/resources/flaskConnexion/app.mustache index 85fd9a354f1..8428dedddaa 100644 --- a/modules/swagger-codegen/src/main/resources/flaskConnexion/app.mustache +++ b/modules/swagger-codegen/src/main/resources/flaskConnexion/app.mustache @@ -6,8 +6,29 @@ {{/supportPython2}} import connexion +from connexion.decorators import produces +from six import iteritems +from {{modelPackage}}.base_model_ import Model + + +class JSONEncoder(produces.JSONEncoder): + include_nulls = False + + def default(self, o): + if isinstance(o, Model): + dikt = {} + for attr, _ in iteritems(o.swagger_types): + value = getattr(o, attr) + if value is None and not self.include_nulls: + continue + attr = o.attribute_map[attr] + dikt[attr] = value + return dikt + return produces.JSONEncoder.default(self, o) + if __name__ == '__main__': app = connexion.App(__name__, specification_dir='./swagger/') + app.app.json_encoder = JSONEncoder app.add_api('swagger.yaml', arguments={'title': '{{appDescription}}'}) app.run(port={{serverPort}}) diff --git a/modules/swagger-codegen/src/main/resources/flaskConnexion/base_model_.mustache b/modules/swagger-codegen/src/main/resources/flaskConnexion/base_model_.mustache new file mode 100644 index 00000000000..ba7b5b23dc1 --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/flaskConnexion/base_model_.mustache @@ -0,0 +1,79 @@ +from pprint import pformat +{{^supportPython2}} +from typing import TypeVar, Type +{{/supportPython2}} +from six import iteritems +from util import deserialize_model +{{^supportPython2}} + +T = TypeVar('T') +{{/supportPython2}} + + +class Model(object): + # swaggerTypes: The key is attribute name and the value is attribute type. + swagger_types = {} + + # attributeMap: The key is attribute name and the value is json key in definition. + attribute_map = {} + + @classmethod + def from_dict(cls{{^supportPython2}}: Type[T]{{/supportPython2}}, dikt){{^supportPython2}} -> T{{/supportPython2}}: + """ + Returns the dict as a model + """ + return deserialize_model(dikt, cls) + + def to_dict(self): + """ + Returns the model properties as a dict + + :rtype: dict + """ + result = {} + + for attr, _ in iteritems(self.swagger_types): + value = getattr(self, attr) + if isinstance(value, list): + result[attr] = list(map( + lambda x: x.to_dict() if hasattr(x, "to_dict") else x, + value + )) + elif hasattr(value, "to_dict"): + result[attr] = value.to_dict() + elif isinstance(value, dict): + result[attr] = dict(map( + lambda item: (item[0], item[1].to_dict()) + if hasattr(item[1], "to_dict") else item, + value.items() + )) + else: + result[attr] = value + + return result + + def to_str(self): + """ + Returns the string representation of the model + + :rtype: str + """ + return pformat(self.to_dict()) + + def __repr__(self): + """ + For `print` and `pprint` + """ + return self.to_str() + + def __eq__(self, other): + """ + Returns true if both objects are equal + """ + return self.__dict__ == other.__dict__ + + def __ne__(self, other): + """ + Returns true if both objects are not equal + """ + return not self == other \ No newline at end of file diff --git a/modules/swagger-codegen/src/main/resources/flaskConnexion/controller.mustache b/modules/swagger-codegen/src/main/resources/flaskConnexion/controller.mustache index 8050f04ba51..f762017284d 100644 --- a/modules/swagger-codegen/src/main/resources/flaskConnexion/controller.mustache +++ b/modules/swagger-codegen/src/main/resources/flaskConnexion/controller.mustache @@ -1,7 +1,105 @@ +import connexion +{{#imports}}{{import}} +{{/imports}} +from datetime import date, datetime +from typing import List, Dict +from six import iteritems +from util import deserialize_date, deserialize_datetime {{#operations}} {{#operation}} -def {{operationId}}({{#allParams}}{{paramName}}{{^required}} = None{{/required}}{{#hasMore}}, {{/hasMore}}{{/allParams}}){{^supportPython2}} -> str{{/supportPython2}}: + +def {{operationId}}({{#allParams}}{{paramName}}{{^required}}=None{{/required}}{{#hasMore}}, {{/hasMore}}{{/allParams}}): + """ + {{#summary}}{{.}}{{/summary}}{{^summary}}{{operationId}}{{/summary}} + {{#notes}}{{.}}{{/notes}} + {{#allParams}} + :param {{paramName}}: {{description}} + {{^isContainer}} + {{#isPrimitiveType}} + :type {{paramName}}: {{>param_type}} + {{/isPrimitiveType}} + {{^isPrimitiveType}} + {{#isFile}} + :type {{paramName}}: werkzeug.datastructures.FileStorage + {{/isFile}} + {{^isFile}} + :type {{paramName}}: dict | bytes + {{/isFile}} + {{/isPrimitiveType}} + {{/isContainer}} + {{#isListContainer}} + {{#items}} + {{#isPrimitiveType}} + :type {{paramName}}: List[{{>param_type}}] + {{/isPrimitiveType}} + {{^isPrimitiveType}} + :type {{paramName}}: list | bytes + {{/isPrimitiveType}} + {{/items}} + {{/isListContainer}} + {{#isMapContainer}} + {{#items}} + {{#isPrimitiveType}} + :type {{paramName}}: Dict[str, {{>param_type}}] + {{/isPrimitiveType}} + {{^isPrimitiveType}} + :type {{paramName}}: dict | bytes + {{/isPrimitiveType}} + {{/items}} + {{/isMapContainer}} + {{/allParams}} + + :rtype: {{#returnType}}{{.}}{{/returnType}}{{^returnType}}None{{/returnType}} + """ + {{#allParams}} + {{^isContainer}} + {{#isDate}} + {{paramName}} = deserialize_date({{paramName}}) + {{/isDate}} + {{#isDateTime}} + {{paramName}} = deserialize_datetime({{paramName}}) + {{/isDateTime}} + {{^isPrimitiveType}} + {{^isFile}} + if connexion.request.is_json: + {{paramName}} = {{baseType}}.from_dict(connexion.request.get_json()) + {{/isFile}} + {{/isPrimitiveType}} + {{/isContainer}} + {{#isListContainer}} + {{#items}} + {{#isDate}} + if connexion.request.is_json: + {{paramName}} = [deserialize_date(s) for s in connexion.request.get_json()] + {{/isDate}} + {{#isDateTime}} + if connexion.request.is_json: + {{paramName}} = [deserialize_datetime(s) for s in connexion.request.get_json()] + {{/isDateTime}} + {{#complexType}} + if connexion.request.is_json: + {{paramName}} = [{{complexType}}.from_dict(d) for d in connexion.request.get_json()] + {{/complexType}} + {{/items}} + {{/isListContainer}} + {{#isMapContainer}} + {{#items}} + {{#isDate}} + if connexion.request.is_json: + {{paramName}} = {k: deserialize_date(v) for k, v in iteritems(connexion.request.get_json())} + {{/isDate}} + {{#isDateTime}} + if connexion.request.is_json: + {{paramName}} = {k: deserialize_datetime(v) for k, v in iteritems(connexion.request.get_json())} + {{/isDateTime}} + {{#complexType}} + if connexion.request.is_json: + {{paramName}} = {k: {{baseType}}.from_dict(v) for k, v in iteritems(connexion.request.get_json())} + {{/complexType}} + {{/items}} + {{/isMapContainer}} + {{/allParams}} return 'do some magic!' {{/operation}} {{/operations}} diff --git a/modules/swagger-codegen/src/main/resources/flaskConnexion/model.mustache b/modules/swagger-codegen/src/main/resources/flaskConnexion/model.mustache new file mode 100644 index 00000000000..36b0af83c69 --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/flaskConnexion/model.mustache @@ -0,0 +1,148 @@ +# coding: utf-8 + +from __future__ import absolute_import +{{#imports}}{{import}} +{{/imports}} +from .base_model_ import Model +from datetime import date, datetime +from typing import List, Dict +from util import deserialize_model + + +{{#models}} +{{#model}} +class {{classname}}(Model): + """ + NOTE: This class is auto generated by the swagger code generator program. + Do not edit the class manually. + """ + def __init__(self{{#vars}}, {{name}}{{^supportPython2}}: {{datatype}}{{/supportPython2}}={{#defaultValue}}{{{defaultValue}}}{{/defaultValue}}{{^defaultValue}}None{{/defaultValue}}{{/vars}}): + """ + {{classname}} - a model defined in Swagger + + {{#vars}} + :param {{name}}: The {{name}} of this {{classname}}. + :type {{name}}: {{datatype}} + {{/vars}} + """ + self.swagger_types = { + {{#vars}}'{{name}}': {{{datatype}}}{{#hasMore}}, + {{/hasMore}}{{/vars}} + } + + self.attribute_map = { + {{#vars}}'{{name}}': '{{baseName}}'{{#hasMore}}, + {{/hasMore}}{{/vars}} + } + +{{#vars}} + self._{{name}} = {{name}} +{{/vars}} + + @classmethod + def from_dict(cls, dikt){{^supportPython2}} -> '{{classname}}'{{/supportPython2}}: + """ + Returns the dict as a model + + :param dikt: A dict. + :type: dict + :return: The {{name}} of this {{classname}}. + :rtype: {{classname}} + """ + return deserialize_model(dikt, cls) +{{#vars}}{{#-first}} +{{/-first}} + @property + def {{name}}(self){{^supportPython2}} -> {{datatype}}{{/supportPython2}}: + """ + Gets the {{name}} of this {{classname}}. + {{#description}} + {{{description}}} + {{/description}} + + :return: The {{name}} of this {{classname}}. + :rtype: {{datatype}} + """ + return self._{{name}} + + @{{name}}.setter + def {{name}}(self, {{name}}{{^supportPython2}}: {{datatype}}{{/supportPython2}}): + """ + Sets the {{name}} of this {{classname}}. + {{#description}} + {{{description}}} + {{/description}} + + :param {{name}}: The {{name}} of this {{classname}}. + :type {{name}}: {{datatype}} + """ +{{#isEnum}} + allowed_values = [{{#allowableValues}}{{#values}}"{{{this}}}"{{^-last}}, {{/-last}}{{/values}}{{/allowableValues}}] +{{#isContainer}} +{{#isListContainer}} + if not set({{{name}}}).issubset(set(allowed_values)): + raise ValueError( + "Invalid values for `{{{name}}}` [{0}], must be a subset of [{1}]" + .format(", ".join(map(str, set({{{name}}})-set(allowed_values))), + ", ".join(map(str, allowed_values))) + ) +{{/isListContainer}} +{{#isMapContainer}} + if not set({{{name}}}.keys()).issubset(set(allowed_values)): + raise ValueError( + "Invalid keys in `{{{name}}}` [{0}], must be a subset of [{1}]" + .format(", ".join(map(str, set({{{name}}}.keys())-set(allowed_values))), + ", ".join(map(str, allowed_values))) + ) +{{/isMapContainer}} +{{/isContainer}} +{{^isContainer}} + if {{{name}}} not in allowed_values: + raise ValueError( + "Invalid value for `{{{name}}}` ({0}), must be one of {1}" + .format({{{name}}}, allowed_values) + ) +{{/isContainer}} +{{/isEnum}} +{{^isEnum}} +{{#required}} + if {{name}} is None: + raise ValueError("Invalid value for `{{name}}`, must not be `None`") +{{/required}} +{{#hasValidation}} +{{#maxLength}} + if {{name}} is not None and len({{name}}) > {{maxLength}}: + raise ValueError("Invalid value for `{{name}}`, length must be less than or equal to `{{maxLength}}`") +{{/maxLength}} +{{#minLength}} + if {{name}} is not None and len({{name}}) < {{minLength}}: + raise ValueError("Invalid value for `{{name}}`, length must be greater than or equal to `{{minLength}}`") +{{/minLength}} +{{#maximum}} + if {{name}} is not None and {{name}} >{{#exclusiveMaximum}}={{/exclusiveMaximum}} {{maximum}}: + raise ValueError("Invalid value for `{{name}}`, must be a value less than {{^exclusiveMaximum}}or equal to {{/exclusiveMaximum}}`{{maximum}}`") +{{/maximum}} +{{#minimum}} + if {{name}} is not None and {{name}} <{{#exclusiveMinimum}}={{/exclusiveMinimum}} {{minimum}}: + raise ValueError("Invalid value for `{{name}}`, must be a value greater than {{^exclusiveMinimum}}or equal to {{/exclusiveMinimum}}`{{minimum}}`") +{{/minimum}} +{{#pattern}} + if {{name}} is not None and not re.search('{{{vendorExtensions.x-regex}}}', {{name}}{{#vendorExtensions.x-modifiers}}{{#-first}}, flags={{/-first}}re.{{.}}{{^-last}} | {{/-last}}{{/vendorExtensions.x-modifiers}}): + raise ValueError("Invalid value for `{{name}}`, must be a follow pattern or equal to `{{{pattern}}}`") +{{/pattern}} +{{#maxItems}} + if {{name}} is not None and len({{name}}) > {{maxItems}}: + raise ValueError("Invalid value for `{{name}}`, number of items must be less than or equal to `{{maxItems}}`") +{{/maxItems}} +{{#minItems}} + if {{name}} is not None and len({{name}}) < {{minItems}}: + raise ValueError("Invalid value for `{{name}}`, number of items must be greater than or equal to `{{minItems}}`") +{{/minItems}} +{{/hasValidation}} +{{/isEnum}} + + self._{{name}} = {{name}} + +{{/vars}} +{{/model}} +{{/models}} diff --git a/modules/swagger-codegen/src/main/resources/flaskConnexion/param_type.mustache b/modules/swagger-codegen/src/main/resources/flaskConnexion/param_type.mustache new file mode 100644 index 00000000000..21e7e07ec53 --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/flaskConnexion/param_type.mustache @@ -0,0 +1 @@ +{{#isString}}str{{/isString}}{{#isInteger}}int{{/isInteger}}{{#isLong}}int{{/isLong}}{{#isFloat}}float{{/isFloat}}{{#isDouble}}float{{/isDouble}}{{#isByteArray}}str{{/isByteArray}}{{#isBinary}}str{{/isBinary}}{{#isBoolean}}bool{{/isBoolean}}{{#isDate}}str{{/isDate}}{{#isDateTime}}str{{/isDateTime}} \ No newline at end of file diff --git a/modules/swagger-codegen/src/main/resources/flaskConnexion/util.mustache b/modules/swagger-codegen/src/main/resources/flaskConnexion/util.mustache new file mode 100644 index 00000000000..40c72d43ebd --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/flaskConnexion/util.mustache @@ -0,0 +1,149 @@ +from typing import GenericMeta +from datetime import datetime, date +from six import integer_types, iteritems + + +def _deserialize(data, klass): + """ + Deserializes dict, list, str into an object. + + :param data: dict, list or str. + :param klass: class literal, or string of class name. + + :return: object. + """ + if data is None: + return None + + if klass in integer_types or klass in (float, str, bool): + return _deserialize_primitive(data, klass) + elif klass == object: + return _deserialize_object(data) + elif klass == date: + return deserialize_date(data) + elif klass == datetime: + return deserialize_datetime(data) + elif type(klass) == GenericMeta: + if klass.__extra__ == list: + return _deserialize_list(data, klass.__args__[0]) + if klass.__extra__ == dict: + return _deserialize_dict(data, klass.__args__[1]) + else: + return deserialize_model(data, klass) + + +def _deserialize_primitive(data, klass): + """ + Deserializes to primitive type. + + :param data: data to deserialize. + :param klass: class literal. + + :return: int, long, float, str, bool. + :rtype: int | long | float | str | bool + """ + try: + value = klass(data) + except UnicodeEncodeError: + value = unicode(data) + except TypeError: + value = data + return value + + +def _deserialize_object(value): + """ + Return a original value. + + :return: object. + """ + return value + + +def deserialize_date(string): + """ + Deserializes string to date. + + :param string: str. + :type string: str + :return: date. + :rtype: date + """ + try: + from dateutil.parser import parse + return parse(string).date() + except ImportError: + return string + + +def deserialize_datetime(string): + """ + Deserializes string to datetime. + + The string should be in iso8601 datetime format. + + :param string: str. + :type string: str + :return: datetime. + :rtype: datetime + """ + try: + from dateutil.parser import parse + return parse(string) + except ImportError: + return string + + +def deserialize_model(data, klass): + """ + Deserializes list or dict to model. + + :param data: dict, list. + :type data: dict | list + :param klass: class literal. + :return: model object. + """ + instance = klass() + + if not instance.swagger_types: + return data + + for attr, attr_type in iteritems(instance.swagger_types): + if data is not None \ + and instance.attribute_map[attr] in data \ + and isinstance(data, (list, dict)): + value = data[instance.attribute_map[attr]] + setattr(instance, attr, _deserialize(value, attr_type)) + + return instance + + +def _deserialize_list(data, boxed_type): + """ + Deserializes a list and its elements. + + :param data: list to deserialize. + :type data: list + :param boxed_type: class literal. + + :return: deserialized list. + :rtype: list + """ + return [_deserialize(sub_data, boxed_type) + for sub_data in data] + + + +def _deserialize_dict(data, boxed_type): + """ + Deserializes a dict and its elements. + + :param data: dict to deserialize. + :type data: dict + :param boxed_type: class literal. + + :return: deserialized dict. + :rtype: dict + """ + return {k: _deserialize(v, boxed_type) + for k, v in iteritems(data)} diff --git a/samples/server/petstore/flaskConnexion-python2/README.md b/samples/server/petstore/flaskConnexion-python2/README.md index cfc25505bd7..da392f1dd02 100644 --- a/samples/server/petstore/flaskConnexion-python2/README.md +++ b/samples/server/petstore/flaskConnexion-python2/README.md @@ -10,7 +10,7 @@ This example uses the [Connexion](https://github.com/zalando/connexion) library To run the server, please execute the following: ``` -sudo pip install -U connexion # install Connexion from PyPI +sudo pip install -U connexion typing # install Connexion and Typing from PyPI python app.py ``` diff --git a/samples/server/petstore/flaskConnexion-python2/app.py b/samples/server/petstore/flaskConnexion-python2/app.py index 47814427205..413af17ec79 100644 --- a/samples/server/petstore/flaskConnexion-python2/app.py +++ b/samples/server/petstore/flaskConnexion-python2/app.py @@ -1,8 +1,29 @@ #!/usr/bin/env python import connexion +from connexion.decorators import produces +from six import iteritems +from models.base_model_ import Model + + +class JSONEncoder(produces.JSONEncoder): + include_nulls = False + + def default(self, o): + if isinstance(o, Model): + dikt = {} + for attr, _ in iteritems(o.swagger_types): + value = getattr(o, attr) + if value is None and not self.include_nulls: + continue + attr = o.attribute_map[attr] + dikt[attr] = value + return dikt + return produces.JSONEncoder.default(self, o) + if __name__ == '__main__': app = connexion.App(__name__, specification_dir='./swagger/') + app.app.json_encoder = JSONEncoder app.add_api('swagger.yaml', arguments={'title': 'This is a sample server Petstore server. You can find out more about Swagger at [http://swagger.io](http://swagger.io) or on [irc.freenode.net, #swagger](http://swagger.io/irc/). For this sample, you can use the api key `special-key` to test the authorization filters.'}) app.run(port=8080) diff --git a/samples/server/petstore/flaskConnexion-python2/controllers/pet_controller.py b/samples/server/petstore/flaskConnexion-python2/controllers/pet_controller.py index d58d3973ca2..461f6163a63 100644 --- a/samples/server/petstore/flaskConnexion-python2/controllers/pet_controller.py +++ b/samples/server/petstore/flaskConnexion-python2/controllers/pet_controller.py @@ -1,24 +1,117 @@ +import connexion +from models.pet import Pet +from models.api_response import ApiResponse +from datetime import date, datetime +from typing import List, Dict +from six import iteritems +from util import deserialize_date, deserialize_datetime + def add_pet(body): + """ + Add a new pet to the store + + :param body: Pet object that needs to be added to the store + :type body: dict | bytes + + :rtype: None + """ + if connexion.request.is_json: + body = Pet.from_dict(connexion.request.get_json()) return 'do some magic!' -def delete_pet(petId, apiKey = None): + +def delete_pet(petId, apiKey=None): + """ + Deletes a pet + + :param petId: Pet id to delete + :type petId: int + :param apiKey: + :type apiKey: str + + :rtype: None + """ return 'do some magic!' + def find_pets_by_status(status): + """ + Finds Pets by status + Multiple status values can be provided with comma separated strings + :param status: Status values that need to be considered for filter + :type status: List[str] + + :rtype: List[Pet] + """ return 'do some magic!' + def find_pets_by_tags(tags): + """ + Finds Pets by tags + Multiple tags can be provided with comma separated strings. Use tag1, tag2, tag3 for testing. + :param tags: Tags to filter by + :type tags: List[str] + + :rtype: List[Pet] + """ return 'do some magic!' + def get_pet_by_id(petId): + """ + Find pet by ID + Returns a single pet + :param petId: ID of pet to return + :type petId: int + + :rtype: Pet + """ return 'do some magic!' + def update_pet(body): + """ + Update an existing pet + + :param body: Pet object that needs to be added to the store + :type body: dict | bytes + + :rtype: None + """ + if connexion.request.is_json: + body = Pet.from_dict(connexion.request.get_json()) return 'do some magic!' -def update_pet_with_form(petId, name = None, status = None): + +def update_pet_with_form(petId, name=None, status=None): + """ + Updates a pet in the store with form data + + :param petId: ID of pet that needs to be updated + :type petId: int + :param name: Updated name of the pet + :type name: str + :param status: Updated status of the pet + :type status: str + + :rtype: None + """ return 'do some magic!' -def upload_file(petId, additionalMetadata = None, file = None): + +def upload_file(petId, additionalMetadata=None, file=None): + """ + uploads an image + + :param petId: ID of pet to update + :type petId: int + :param additionalMetadata: Additional data to pass to server + :type additionalMetadata: str + :param file: file to upload + :type file: werkzeug.datastructures.FileStorage + + :rtype: ApiResponse + """ return 'do some magic!' diff --git a/samples/server/petstore/flaskConnexion-python2/controllers/store_controller.py b/samples/server/petstore/flaskConnexion-python2/controllers/store_controller.py index a25eb40febb..5373cbf5f71 100644 --- a/samples/server/petstore/flaskConnexion-python2/controllers/store_controller.py +++ b/samples/server/petstore/flaskConnexion-python2/controllers/store_controller.py @@ -1,12 +1,54 @@ +import connexion +from models.order import Order +from datetime import date, datetime +from typing import List, Dict +from six import iteritems +from util import deserialize_date, deserialize_datetime + def delete_order(orderId): + """ + Delete purchase order by ID + For valid response try integer IDs with value < 1000. Anything above 1000 or nonintegers will generate API errors + :param orderId: ID of the order that needs to be deleted + :type orderId: str + + :rtype: None + """ return 'do some magic!' + def get_inventory(): + """ + Returns pet inventories by status + Returns a map of status codes to quantities + + :rtype: Dict[str, int] + """ return 'do some magic!' + def get_order_by_id(orderId): + """ + Find purchase order by ID + For valid response try integer IDs with value <= 5 or > 10. Other values will generated exceptions + :param orderId: ID of pet that needs to be fetched + :type orderId: int + + :rtype: Order + """ return 'do some magic!' + def place_order(body): + """ + Place an order for a pet + + :param body: order placed for purchasing the pet + :type body: dict | bytes + + :rtype: Order + """ + if connexion.request.is_json: + body = Order.from_dict(connexion.request.get_json()) return 'do some magic!' diff --git a/samples/server/petstore/flaskConnexion-python2/controllers/user_controller.py b/samples/server/petstore/flaskConnexion-python2/controllers/user_controller.py index ec4efef29eb..0e406488a7f 100644 --- a/samples/server/petstore/flaskConnexion-python2/controllers/user_controller.py +++ b/samples/server/petstore/flaskConnexion-python2/controllers/user_controller.py @@ -1,24 +1,112 @@ +import connexion +from models.user import User +from datetime import date, datetime +from typing import List, Dict +from six import iteritems +from util import deserialize_date, deserialize_datetime + def create_user(body): + """ + Create user + This can only be done by the logged in user. + :param body: Created user object + :type body: dict | bytes + + :rtype: None + """ + if connexion.request.is_json: + body = User.from_dict(connexion.request.get_json()) return 'do some magic!' + def create_users_with_array_input(body): + """ + Creates list of users with given input array + + :param body: List of user object + :type body: list | bytes + + :rtype: None + """ + if connexion.request.is_json: + body = [User.from_dict(d) for d in connexion.request.get_json()] return 'do some magic!' + def create_users_with_list_input(body): + """ + Creates list of users with given input array + + :param body: List of user object + :type body: list | bytes + + :rtype: None + """ + if connexion.request.is_json: + body = [User.from_dict(d) for d in connexion.request.get_json()] return 'do some magic!' + def delete_user(username): + """ + Delete user + This can only be done by the logged in user. + :param username: The name that needs to be deleted + :type username: str + + :rtype: None + """ return 'do some magic!' + def get_user_by_name(username): + """ + Get user by user name + + :param username: The name that needs to be fetched. Use user1 for testing. + :type username: str + + :rtype: User + """ return 'do some magic!' + def login_user(username, password): + """ + Logs user into the system + + :param username: The user name for login + :type username: str + :param password: The password for login in clear text + :type password: str + + :rtype: str + """ return 'do some magic!' + def logout_user(): + """ + Logs out current logged in user session + + + :rtype: None + """ return 'do some magic!' + def update_user(username, body): + """ + Updated user + This can only be done by the logged in user. + :param username: name that need to be deleted + :type username: str + :param body: Updated user object + :type body: dict | bytes + + :rtype: None + """ + if connexion.request.is_json: + body = User.from_dict(connexion.request.get_json()) return 'do some magic!' diff --git a/samples/server/petstore/flaskConnexion-python2/models/__init__.py b/samples/server/petstore/flaskConnexion-python2/models/__init__.py new file mode 100644 index 00000000000..6571ad28e0f --- /dev/null +++ b/samples/server/petstore/flaskConnexion-python2/models/__init__.py @@ -0,0 +1,10 @@ +# coding: utf-8 + +from __future__ import absolute_import +# import models into model package +from .api_response import ApiResponse +from .category import Category +from .order import Order +from .pet import Pet +from .tag import Tag +from .user import User diff --git a/samples/server/petstore/flaskConnexion-python2/models/api_response.py b/samples/server/petstore/flaskConnexion-python2/models/api_response.py new file mode 100644 index 00000000000..aeeee173602 --- /dev/null +++ b/samples/server/petstore/flaskConnexion-python2/models/api_response.py @@ -0,0 +1,116 @@ +# coding: utf-8 + +from __future__ import absolute_import +from .base_model_ import Model +from datetime import date, datetime +from typing import List, Dict +from util import deserialize_model + + +class ApiResponse(Model): + """ + NOTE: This class is auto generated by the swagger code generator program. + Do not edit the class manually. + """ + def __init__(self, code=None, type=None, message=None): + """ + ApiResponse - a model defined in Swagger + + :param code: The code of this ApiResponse. + :type code: int + :param type: The type of this ApiResponse. + :type type: str + :param message: The message of this ApiResponse. + :type message: str + """ + self.swagger_types = { + 'code': int, + 'type': str, + 'message': str + } + + self.attribute_map = { + 'code': 'code', + 'type': 'type', + 'message': 'message' + } + + self._code = code + self._type = type + self._message = message + + @classmethod + def from_dict(cls, dikt): + """ + Returns the dict as a model + + :param dikt: A dict. + :type: dict + :return: The ApiResponse of this ApiResponse. + :rtype: ApiResponse + """ + return deserialize_model(dikt, cls) + + @property + def code(self): + """ + Gets the code of this ApiResponse. + + :return: The code of this ApiResponse. + :rtype: int + """ + return self._code + + @code.setter + def code(self, code): + """ + Sets the code of this ApiResponse. + + :param code: The code of this ApiResponse. + :type code: int + """ + + self._code = code + + @property + def type(self): + """ + Gets the type of this ApiResponse. + + :return: The type of this ApiResponse. + :rtype: str + """ + return self._type + + @type.setter + def type(self, type): + """ + Sets the type of this ApiResponse. + + :param type: The type of this ApiResponse. + :type type: str + """ + + self._type = type + + @property + def message(self): + """ + Gets the message of this ApiResponse. + + :return: The message of this ApiResponse. + :rtype: str + """ + return self._message + + @message.setter + def message(self, message): + """ + Sets the message of this ApiResponse. + + :param message: The message of this ApiResponse. + :type message: str + """ + + self._message = message + diff --git a/samples/server/petstore/flaskConnexion-python2/models/base_model_.py b/samples/server/petstore/flaskConnexion-python2/models/base_model_.py new file mode 100644 index 00000000000..61136d40eff --- /dev/null +++ b/samples/server/petstore/flaskConnexion-python2/models/base_model_.py @@ -0,0 +1,72 @@ +from pprint import pformat +from six import iteritems +from util import deserialize_model + + +class Model(object): + # swaggerTypes: The key is attribute name and the value is attribute type. + swagger_types = {} + + # attributeMap: The key is attribute name and the value is json key in definition. + attribute_map = {} + + @classmethod + def from_dict(cls, dikt): + """ + Returns the dict as a model + """ + return deserialize_model(dikt, cls) + + def to_dict(self): + """ + Returns the model properties as a dict + + :rtype: dict + """ + result = {} + + for attr, _ in iteritems(self.swagger_types): + value = getattr(self, attr) + if isinstance(value, list): + result[attr] = list(map( + lambda x: x.to_dict() if hasattr(x, "to_dict") else x, + value + )) + elif hasattr(value, "to_dict"): + result[attr] = value.to_dict() + elif isinstance(value, dict): + result[attr] = dict(map( + lambda item: (item[0], item[1].to_dict()) + if hasattr(item[1], "to_dict") else item, + value.items() + )) + else: + result[attr] = value + + return result + + def to_str(self): + """ + Returns the string representation of the model + + :rtype: str + """ + return pformat(self.to_dict()) + + def __repr__(self): + """ + For `print` and `pprint` + """ + return self.to_str() + + def __eq__(self, other): + """ + Returns true if both objects are equal + """ + return self.__dict__ == other.__dict__ + + def __ne__(self, other): + """ + Returns true if both objects are not equal + """ + return not self == other \ No newline at end of file diff --git a/samples/server/petstore/flaskConnexion-python2/models/category.py b/samples/server/petstore/flaskConnexion-python2/models/category.py new file mode 100644 index 00000000000..82fd59fe337 --- /dev/null +++ b/samples/server/petstore/flaskConnexion-python2/models/category.py @@ -0,0 +1,90 @@ +# coding: utf-8 + +from __future__ import absolute_import +from .base_model_ import Model +from datetime import date, datetime +from typing import List, Dict +from util import deserialize_model + + +class Category(Model): + """ + NOTE: This class is auto generated by the swagger code generator program. + Do not edit the class manually. + """ + def __init__(self, id=None, name=None): + """ + Category - a model defined in Swagger + + :param id: The id of this Category. + :type id: int + :param name: The name of this Category. + :type name: str + """ + self.swagger_types = { + 'id': int, + 'name': str + } + + self.attribute_map = { + 'id': 'id', + 'name': 'name' + } + + self._id = id + self._name = name + + @classmethod + def from_dict(cls, dikt): + """ + Returns the dict as a model + + :param dikt: A dict. + :type: dict + :return: The Category of this Category. + :rtype: Category + """ + return deserialize_model(dikt, cls) + + @property + def id(self): + """ + Gets the id of this Category. + + :return: The id of this Category. + :rtype: int + """ + return self._id + + @id.setter + def id(self, id): + """ + Sets the id of this Category. + + :param id: The id of this Category. + :type id: int + """ + + self._id = id + + @property + def name(self): + """ + Gets the name of this Category. + + :return: The name of this Category. + :rtype: str + """ + return self._name + + @name.setter + def name(self, name): + """ + Sets the name of this Category. + + :param name: The name of this Category. + :type name: str + """ + + self._name = name + diff --git a/samples/server/petstore/flaskConnexion-python2/models/order.py b/samples/server/petstore/flaskConnexion-python2/models/order.py new file mode 100644 index 00000000000..20c6fbe4102 --- /dev/null +++ b/samples/server/petstore/flaskConnexion-python2/models/order.py @@ -0,0 +1,202 @@ +# coding: utf-8 + +from __future__ import absolute_import +from .base_model_ import Model +from datetime import date, datetime +from typing import List, Dict +from util import deserialize_model + + +class Order(Model): + """ + NOTE: This class is auto generated by the swagger code generator program. + Do not edit the class manually. + """ + def __init__(self, id=None, pet_id=None, quantity=None, ship_date=None, status=None, complete=False): + """ + Order - a model defined in Swagger + + :param id: The id of this Order. + :type id: int + :param pet_id: The pet_id of this Order. + :type pet_id: int + :param quantity: The quantity of this Order. + :type quantity: int + :param ship_date: The ship_date of this Order. + :type ship_date: datetime + :param status: The status of this Order. + :type status: str + :param complete: The complete of this Order. + :type complete: bool + """ + self.swagger_types = { + 'id': int, + 'pet_id': int, + 'quantity': int, + 'ship_date': datetime, + 'status': str, + 'complete': bool + } + + self.attribute_map = { + 'id': 'id', + 'pet_id': 'petId', + 'quantity': 'quantity', + 'ship_date': 'shipDate', + 'status': 'status', + 'complete': 'complete' + } + + self._id = id + self._pet_id = pet_id + self._quantity = quantity + self._ship_date = ship_date + self._status = status + self._complete = complete + + @classmethod + def from_dict(cls, dikt): + """ + Returns the dict as a model + + :param dikt: A dict. + :type: dict + :return: The Order of this Order. + :rtype: Order + """ + return deserialize_model(dikt, cls) + + @property + def id(self): + """ + Gets the id of this Order. + + :return: The id of this Order. + :rtype: int + """ + return self._id + + @id.setter + def id(self, id): + """ + Sets the id of this Order. + + :param id: The id of this Order. + :type id: int + """ + + self._id = id + + @property + def pet_id(self): + """ + Gets the pet_id of this Order. + + :return: The pet_id of this Order. + :rtype: int + """ + return self._pet_id + + @pet_id.setter + def pet_id(self, pet_id): + """ + Sets the pet_id of this Order. + + :param pet_id: The pet_id of this Order. + :type pet_id: int + """ + + self._pet_id = pet_id + + @property + def quantity(self): + """ + Gets the quantity of this Order. + + :return: The quantity of this Order. + :rtype: int + """ + return self._quantity + + @quantity.setter + def quantity(self, quantity): + """ + Sets the quantity of this Order. + + :param quantity: The quantity of this Order. + :type quantity: int + """ + + self._quantity = quantity + + @property + def ship_date(self): + """ + Gets the ship_date of this Order. + + :return: The ship_date of this Order. + :rtype: datetime + """ + return self._ship_date + + @ship_date.setter + def ship_date(self, ship_date): + """ + Sets the ship_date of this Order. + + :param ship_date: The ship_date of this Order. + :type ship_date: datetime + """ + + self._ship_date = ship_date + + @property + def status(self): + """ + Gets the status of this Order. + Order Status + + :return: The status of this Order. + :rtype: str + """ + return self._status + + @status.setter + def status(self, status): + """ + Sets the status of this Order. + Order Status + + :param status: The status of this Order. + :type status: str + """ + allowed_values = ["placed", "approved", "delivered"] + if status not in allowed_values: + raise ValueError( + "Invalid value for `status` ({0}), must be one of {1}" + .format(status, allowed_values) + ) + + self._status = status + + @property + def complete(self): + """ + Gets the complete of this Order. + + :return: The complete of this Order. + :rtype: bool + """ + return self._complete + + @complete.setter + def complete(self, complete): + """ + Sets the complete of this Order. + + :param complete: The complete of this Order. + :type complete: bool + """ + + self._complete = complete + diff --git a/samples/server/petstore/flaskConnexion-python2/models/pet.py b/samples/server/petstore/flaskConnexion-python2/models/pet.py new file mode 100644 index 00000000000..5bd32865fbd --- /dev/null +++ b/samples/server/petstore/flaskConnexion-python2/models/pet.py @@ -0,0 +1,208 @@ +# coding: utf-8 + +from __future__ import absolute_import +from models.category import Category +from models.tag import Tag +from .base_model_ import Model +from datetime import date, datetime +from typing import List, Dict +from util import deserialize_model + + +class Pet(Model): + """ + NOTE: This class is auto generated by the swagger code generator program. + Do not edit the class manually. + """ + def __init__(self, id=None, category=None, name=None, photo_urls=None, tags=None, status=None): + """ + Pet - a model defined in Swagger + + :param id: The id of this Pet. + :type id: int + :param category: The category of this Pet. + :type category: Category + :param name: The name of this Pet. + :type name: str + :param photo_urls: The photo_urls of this Pet. + :type photo_urls: List[str] + :param tags: The tags of this Pet. + :type tags: List[Tag] + :param status: The status of this Pet. + :type status: str + """ + self.swagger_types = { + 'id': int, + 'category': Category, + 'name': str, + 'photo_urls': List[str], + 'tags': List[Tag], + 'status': str + } + + self.attribute_map = { + 'id': 'id', + 'category': 'category', + 'name': 'name', + 'photo_urls': 'photoUrls', + 'tags': 'tags', + 'status': 'status' + } + + self._id = id + self._category = category + self._name = name + self._photo_urls = photo_urls + self._tags = tags + self._status = status + + @classmethod + def from_dict(cls, dikt): + """ + Returns the dict as a model + + :param dikt: A dict. + :type: dict + :return: The Pet of this Pet. + :rtype: Pet + """ + return deserialize_model(dikt, cls) + + @property + def id(self): + """ + Gets the id of this Pet. + + :return: The id of this Pet. + :rtype: int + """ + return self._id + + @id.setter + def id(self, id): + """ + Sets the id of this Pet. + + :param id: The id of this Pet. + :type id: int + """ + + self._id = id + + @property + def category(self): + """ + Gets the category of this Pet. + + :return: The category of this Pet. + :rtype: Category + """ + return self._category + + @category.setter + def category(self, category): + """ + Sets the category of this Pet. + + :param category: The category of this Pet. + :type category: Category + """ + + self._category = category + + @property + def name(self): + """ + Gets the name of this Pet. + + :return: The name of this Pet. + :rtype: str + """ + return self._name + + @name.setter + def name(self, name): + """ + Sets the name of this Pet. + + :param name: The name of this Pet. + :type name: str + """ + if name is None: + raise ValueError("Invalid value for `name`, must not be `None`") + + self._name = name + + @property + def photo_urls(self): + """ + Gets the photo_urls of this Pet. + + :return: The photo_urls of this Pet. + :rtype: List[str] + """ + return self._photo_urls + + @photo_urls.setter + def photo_urls(self, photo_urls): + """ + Sets the photo_urls of this Pet. + + :param photo_urls: The photo_urls of this Pet. + :type photo_urls: List[str] + """ + if photo_urls is None: + raise ValueError("Invalid value for `photo_urls`, must not be `None`") + + self._photo_urls = photo_urls + + @property + def tags(self): + """ + Gets the tags of this Pet. + + :return: The tags of this Pet. + :rtype: List[Tag] + """ + return self._tags + + @tags.setter + def tags(self, tags): + """ + Sets the tags of this Pet. + + :param tags: The tags of this Pet. + :type tags: List[Tag] + """ + + self._tags = tags + + @property + def status(self): + """ + Gets the status of this Pet. + pet status in the store + + :return: The status of this Pet. + :rtype: str + """ + return self._status + + @status.setter + def status(self, status): + """ + Sets the status of this Pet. + pet status in the store + + :param status: The status of this Pet. + :type status: str + """ + allowed_values = ["available", "pending", "sold"] + if status not in allowed_values: + raise ValueError( + "Invalid value for `status` ({0}), must be one of {1}" + .format(status, allowed_values) + ) + + self._status = status + diff --git a/samples/server/petstore/flaskConnexion-python2/models/tag.py b/samples/server/petstore/flaskConnexion-python2/models/tag.py new file mode 100644 index 00000000000..e397ac90255 --- /dev/null +++ b/samples/server/petstore/flaskConnexion-python2/models/tag.py @@ -0,0 +1,90 @@ +# coding: utf-8 + +from __future__ import absolute_import +from .base_model_ import Model +from datetime import date, datetime +from typing import List, Dict +from util import deserialize_model + + +class Tag(Model): + """ + NOTE: This class is auto generated by the swagger code generator program. + Do not edit the class manually. + """ + def __init__(self, id=None, name=None): + """ + Tag - a model defined in Swagger + + :param id: The id of this Tag. + :type id: int + :param name: The name of this Tag. + :type name: str + """ + self.swagger_types = { + 'id': int, + 'name': str + } + + self.attribute_map = { + 'id': 'id', + 'name': 'name' + } + + self._id = id + self._name = name + + @classmethod + def from_dict(cls, dikt): + """ + Returns the dict as a model + + :param dikt: A dict. + :type: dict + :return: The Tag of this Tag. + :rtype: Tag + """ + return deserialize_model(dikt, cls) + + @property + def id(self): + """ + Gets the id of this Tag. + + :return: The id of this Tag. + :rtype: int + """ + return self._id + + @id.setter + def id(self, id): + """ + Sets the id of this Tag. + + :param id: The id of this Tag. + :type id: int + """ + + self._id = id + + @property + def name(self): + """ + Gets the name of this Tag. + + :return: The name of this Tag. + :rtype: str + """ + return self._name + + @name.setter + def name(self, name): + """ + Sets the name of this Tag. + + :param name: The name of this Tag. + :type name: str + """ + + self._name = name + diff --git a/samples/server/petstore/flaskConnexion-python2/models/user.py b/samples/server/petstore/flaskConnexion-python2/models/user.py new file mode 100644 index 00000000000..134dfd7a892 --- /dev/null +++ b/samples/server/petstore/flaskConnexion-python2/models/user.py @@ -0,0 +1,248 @@ +# coding: utf-8 + +from __future__ import absolute_import +from .base_model_ import Model +from datetime import date, datetime +from typing import List, Dict +from util import deserialize_model + + +class User(Model): + """ + NOTE: This class is auto generated by the swagger code generator program. + Do not edit the class manually. + """ + def __init__(self, id=None, username=None, first_name=None, last_name=None, email=None, password=None, phone=None, user_status=None): + """ + User - a model defined in Swagger + + :param id: The id of this User. + :type id: int + :param username: The username of this User. + :type username: str + :param first_name: The first_name of this User. + :type first_name: str + :param last_name: The last_name of this User. + :type last_name: str + :param email: The email of this User. + :type email: str + :param password: The password of this User. + :type password: str + :param phone: The phone of this User. + :type phone: str + :param user_status: The user_status of this User. + :type user_status: int + """ + self.swagger_types = { + 'id': int, + 'username': str, + 'first_name': str, + 'last_name': str, + 'email': str, + 'password': str, + 'phone': str, + 'user_status': int + } + + self.attribute_map = { + 'id': 'id', + 'username': 'username', + 'first_name': 'firstName', + 'last_name': 'lastName', + 'email': 'email', + 'password': 'password', + 'phone': 'phone', + 'user_status': 'userStatus' + } + + self._id = id + self._username = username + self._first_name = first_name + self._last_name = last_name + self._email = email + self._password = password + self._phone = phone + self._user_status = user_status + + @classmethod + def from_dict(cls, dikt): + """ + Returns the dict as a model + + :param dikt: A dict. + :type: dict + :return: The User of this User. + :rtype: User + """ + return deserialize_model(dikt, cls) + + @property + def id(self): + """ + Gets the id of this User. + + :return: The id of this User. + :rtype: int + """ + return self._id + + @id.setter + def id(self, id): + """ + Sets the id of this User. + + :param id: The id of this User. + :type id: int + """ + + self._id = id + + @property + def username(self): + """ + Gets the username of this User. + + :return: The username of this User. + :rtype: str + """ + return self._username + + @username.setter + def username(self, username): + """ + Sets the username of this User. + + :param username: The username of this User. + :type username: str + """ + + self._username = username + + @property + def first_name(self): + """ + Gets the first_name of this User. + + :return: The first_name of this User. + :rtype: str + """ + return self._first_name + + @first_name.setter + def first_name(self, first_name): + """ + Sets the first_name of this User. + + :param first_name: The first_name of this User. + :type first_name: str + """ + + self._first_name = first_name + + @property + def last_name(self): + """ + Gets the last_name of this User. + + :return: The last_name of this User. + :rtype: str + """ + return self._last_name + + @last_name.setter + def last_name(self, last_name): + """ + Sets the last_name of this User. + + :param last_name: The last_name of this User. + :type last_name: str + """ + + self._last_name = last_name + + @property + def email(self): + """ + Gets the email of this User. + + :return: The email of this User. + :rtype: str + """ + return self._email + + @email.setter + def email(self, email): + """ + Sets the email of this User. + + :param email: The email of this User. + :type email: str + """ + + self._email = email + + @property + def password(self): + """ + Gets the password of this User. + + :return: The password of this User. + :rtype: str + """ + return self._password + + @password.setter + def password(self, password): + """ + Sets the password of this User. + + :param password: The password of this User. + :type password: str + """ + + self._password = password + + @property + def phone(self): + """ + Gets the phone of this User. + + :return: The phone of this User. + :rtype: str + """ + return self._phone + + @phone.setter + def phone(self, phone): + """ + Sets the phone of this User. + + :param phone: The phone of this User. + :type phone: str + """ + + self._phone = phone + + @property + def user_status(self): + """ + Gets the user_status of this User. + User Status + + :return: The user_status of this User. + :rtype: int + """ + return self._user_status + + @user_status.setter + def user_status(self, user_status): + """ + Sets the user_status of this User. + User Status + + :param user_status: The user_status of this User. + :type user_status: int + """ + + self._user_status = user_status + diff --git a/samples/server/petstore/flaskConnexion-python2/swagger/swagger.yaml b/samples/server/petstore/flaskConnexion-python2/swagger/swagger.yaml index 7b412611171..9e8598b591b 100644 --- a/samples/server/petstore/flaskConnexion-python2/swagger/swagger.yaml +++ b/samples/server/petstore/flaskConnexion-python2/swagger/swagger.yaml @@ -110,11 +110,11 @@ paths: type: "array" items: type: "string" - default: "available" enum: - "available" - "pending" - "sold" + default: "available" collectionFormat: "csv" responses: 200: @@ -607,10 +607,6 @@ paths: x-tags: - tag: "user" securityDefinitions: - api_key: - type: "apiKey" - name: "api_key" - in: "header" petstore_auth: type: "oauth2" authorizationUrl: "http://petstore.swagger.io/api/oauth/dialog" @@ -618,6 +614,10 @@ securityDefinitions: scopes: write:pets: "modify pets in your account" read:pets: "read your pets" + api_key: + type: "apiKey" + name: "api_key" + in: "header" definitions: Order: type: "object" diff --git a/samples/server/petstore/flaskConnexion-python2/util.py b/samples/server/petstore/flaskConnexion-python2/util.py new file mode 100644 index 00000000000..40c72d43ebd --- /dev/null +++ b/samples/server/petstore/flaskConnexion-python2/util.py @@ -0,0 +1,149 @@ +from typing import GenericMeta +from datetime import datetime, date +from six import integer_types, iteritems + + +def _deserialize(data, klass): + """ + Deserializes dict, list, str into an object. + + :param data: dict, list or str. + :param klass: class literal, or string of class name. + + :return: object. + """ + if data is None: + return None + + if klass in integer_types or klass in (float, str, bool): + return _deserialize_primitive(data, klass) + elif klass == object: + return _deserialize_object(data) + elif klass == date: + return deserialize_date(data) + elif klass == datetime: + return deserialize_datetime(data) + elif type(klass) == GenericMeta: + if klass.__extra__ == list: + return _deserialize_list(data, klass.__args__[0]) + if klass.__extra__ == dict: + return _deserialize_dict(data, klass.__args__[1]) + else: + return deserialize_model(data, klass) + + +def _deserialize_primitive(data, klass): + """ + Deserializes to primitive type. + + :param data: data to deserialize. + :param klass: class literal. + + :return: int, long, float, str, bool. + :rtype: int | long | float | str | bool + """ + try: + value = klass(data) + except UnicodeEncodeError: + value = unicode(data) + except TypeError: + value = data + return value + + +def _deserialize_object(value): + """ + Return a original value. + + :return: object. + """ + return value + + +def deserialize_date(string): + """ + Deserializes string to date. + + :param string: str. + :type string: str + :return: date. + :rtype: date + """ + try: + from dateutil.parser import parse + return parse(string).date() + except ImportError: + return string + + +def deserialize_datetime(string): + """ + Deserializes string to datetime. + + The string should be in iso8601 datetime format. + + :param string: str. + :type string: str + :return: datetime. + :rtype: datetime + """ + try: + from dateutil.parser import parse + return parse(string) + except ImportError: + return string + + +def deserialize_model(data, klass): + """ + Deserializes list or dict to model. + + :param data: dict, list. + :type data: dict | list + :param klass: class literal. + :return: model object. + """ + instance = klass() + + if not instance.swagger_types: + return data + + for attr, attr_type in iteritems(instance.swagger_types): + if data is not None \ + and instance.attribute_map[attr] in data \ + and isinstance(data, (list, dict)): + value = data[instance.attribute_map[attr]] + setattr(instance, attr, _deserialize(value, attr_type)) + + return instance + + +def _deserialize_list(data, boxed_type): + """ + Deserializes a list and its elements. + + :param data: list to deserialize. + :type data: list + :param boxed_type: class literal. + + :return: deserialized list. + :rtype: list + """ + return [_deserialize(sub_data, boxed_type) + for sub_data in data] + + + +def _deserialize_dict(data, boxed_type): + """ + Deserializes a dict and its elements. + + :param data: dict to deserialize. + :type data: dict + :param boxed_type: class literal. + + :return: deserialized dict. + :rtype: dict + """ + return {k: _deserialize(v, boxed_type) + for k, v in iteritems(data)} diff --git a/samples/server/petstore/flaskConnexion/app.py b/samples/server/petstore/flaskConnexion/app.py index 0b3ce76dd2f..c5342f15859 100644 --- a/samples/server/petstore/flaskConnexion/app.py +++ b/samples/server/petstore/flaskConnexion/app.py @@ -1,8 +1,29 @@ #!/usr/bin/env python3 import connexion +from connexion.decorators import produces +from six import iteritems +from models.base_model_ import Model + + +class JSONEncoder(produces.JSONEncoder): + include_nulls = False + + def default(self, o): + if isinstance(o, Model): + dikt = {} + for attr, _ in iteritems(o.swagger_types): + value = getattr(o, attr) + if value is None and not self.include_nulls: + continue + attr = o.attribute_map[attr] + dikt[attr] = value + return dikt + return produces.JSONEncoder.default(self, o) + if __name__ == '__main__': app = connexion.App(__name__, specification_dir='./swagger/') + app.app.json_encoder = JSONEncoder app.add_api('swagger.yaml', arguments={'title': 'This is a sample server Petstore server. You can find out more about Swagger at [http://swagger.io](http://swagger.io) or on [irc.freenode.net, #swagger](http://swagger.io/irc/). For this sample, you can use the api key `special-key` to test the authorization filters.'}) app.run(port=8080) diff --git a/samples/server/petstore/flaskConnexion/controllers/init.py b/samples/server/petstore/flaskConnexion/controllers/init.py deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/samples/server/petstore/flaskConnexion/controllers/pet_controller.py b/samples/server/petstore/flaskConnexion/controllers/pet_controller.py index b754758b21e..461f6163a63 100644 --- a/samples/server/petstore/flaskConnexion/controllers/pet_controller.py +++ b/samples/server/petstore/flaskConnexion/controllers/pet_controller.py @@ -1,24 +1,117 @@ +import connexion +from models.pet import Pet +from models.api_response import ApiResponse +from datetime import date, datetime +from typing import List, Dict +from six import iteritems +from util import deserialize_date, deserialize_datetime -def add_pet(body) -> str: + +def add_pet(body): + """ + Add a new pet to the store + + :param body: Pet object that needs to be added to the store + :type body: dict | bytes + + :rtype: None + """ + if connexion.request.is_json: + body = Pet.from_dict(connexion.request.get_json()) return 'do some magic!' -def delete_pet(petId, apiKey = None) -> str: + +def delete_pet(petId, apiKey=None): + """ + Deletes a pet + + :param petId: Pet id to delete + :type petId: int + :param apiKey: + :type apiKey: str + + :rtype: None + """ return 'do some magic!' -def find_pets_by_status(status) -> str: + +def find_pets_by_status(status): + """ + Finds Pets by status + Multiple status values can be provided with comma separated strings + :param status: Status values that need to be considered for filter + :type status: List[str] + + :rtype: List[Pet] + """ return 'do some magic!' -def find_pets_by_tags(tags) -> str: + +def find_pets_by_tags(tags): + """ + Finds Pets by tags + Multiple tags can be provided with comma separated strings. Use tag1, tag2, tag3 for testing. + :param tags: Tags to filter by + :type tags: List[str] + + :rtype: List[Pet] + """ return 'do some magic!' -def get_pet_by_id(petId) -> str: + +def get_pet_by_id(petId): + """ + Find pet by ID + Returns a single pet + :param petId: ID of pet to return + :type petId: int + + :rtype: Pet + """ return 'do some magic!' -def update_pet(body) -> str: + +def update_pet(body): + """ + Update an existing pet + + :param body: Pet object that needs to be added to the store + :type body: dict | bytes + + :rtype: None + """ + if connexion.request.is_json: + body = Pet.from_dict(connexion.request.get_json()) return 'do some magic!' -def update_pet_with_form(petId, name = None, status = None) -> str: + +def update_pet_with_form(petId, name=None, status=None): + """ + Updates a pet in the store with form data + + :param petId: ID of pet that needs to be updated + :type petId: int + :param name: Updated name of the pet + :type name: str + :param status: Updated status of the pet + :type status: str + + :rtype: None + """ return 'do some magic!' -def upload_file(petId, additionalMetadata = None, file = None) -> str: + +def upload_file(petId, additionalMetadata=None, file=None): + """ + uploads an image + + :param petId: ID of pet to update + :type petId: int + :param additionalMetadata: Additional data to pass to server + :type additionalMetadata: str + :param file: file to upload + :type file: werkzeug.datastructures.FileStorage + + :rtype: ApiResponse + """ return 'do some magic!' diff --git a/samples/server/petstore/flaskConnexion/controllers/store_controller.py b/samples/server/petstore/flaskConnexion/controllers/store_controller.py index 5f5d893ff1e..5373cbf5f71 100644 --- a/samples/server/petstore/flaskConnexion/controllers/store_controller.py +++ b/samples/server/petstore/flaskConnexion/controllers/store_controller.py @@ -1,12 +1,54 @@ +import connexion +from models.order import Order +from datetime import date, datetime +from typing import List, Dict +from six import iteritems +from util import deserialize_date, deserialize_datetime -def delete_order(orderId) -> str: + +def delete_order(orderId): + """ + Delete purchase order by ID + For valid response try integer IDs with value < 1000. Anything above 1000 or nonintegers will generate API errors + :param orderId: ID of the order that needs to be deleted + :type orderId: str + + :rtype: None + """ return 'do some magic!' -def get_inventory() -> str: + +def get_inventory(): + """ + Returns pet inventories by status + Returns a map of status codes to quantities + + :rtype: Dict[str, int] + """ return 'do some magic!' -def get_order_by_id(orderId) -> str: + +def get_order_by_id(orderId): + """ + Find purchase order by ID + For valid response try integer IDs with value <= 5 or > 10. Other values will generated exceptions + :param orderId: ID of pet that needs to be fetched + :type orderId: int + + :rtype: Order + """ return 'do some magic!' -def place_order(body) -> str: + +def place_order(body): + """ + Place an order for a pet + + :param body: order placed for purchasing the pet + :type body: dict | bytes + + :rtype: Order + """ + if connexion.request.is_json: + body = Order.from_dict(connexion.request.get_json()) return 'do some magic!' diff --git a/samples/server/petstore/flaskConnexion/controllers/user_controller.py b/samples/server/petstore/flaskConnexion/controllers/user_controller.py index a040086a508..0e406488a7f 100644 --- a/samples/server/petstore/flaskConnexion/controllers/user_controller.py +++ b/samples/server/petstore/flaskConnexion/controllers/user_controller.py @@ -1,24 +1,112 @@ +import connexion +from models.user import User +from datetime import date, datetime +from typing import List, Dict +from six import iteritems +from util import deserialize_date, deserialize_datetime -def create_user(body) -> str: + +def create_user(body): + """ + Create user + This can only be done by the logged in user. + :param body: Created user object + :type body: dict | bytes + + :rtype: None + """ + if connexion.request.is_json: + body = User.from_dict(connexion.request.get_json()) return 'do some magic!' -def create_users_with_array_input(body) -> str: + +def create_users_with_array_input(body): + """ + Creates list of users with given input array + + :param body: List of user object + :type body: list | bytes + + :rtype: None + """ + if connexion.request.is_json: + body = [User.from_dict(d) for d in connexion.request.get_json()] return 'do some magic!' -def create_users_with_list_input(body) -> str: + +def create_users_with_list_input(body): + """ + Creates list of users with given input array + + :param body: List of user object + :type body: list | bytes + + :rtype: None + """ + if connexion.request.is_json: + body = [User.from_dict(d) for d in connexion.request.get_json()] return 'do some magic!' -def delete_user(username) -> str: + +def delete_user(username): + """ + Delete user + This can only be done by the logged in user. + :param username: The name that needs to be deleted + :type username: str + + :rtype: None + """ return 'do some magic!' -def get_user_by_name(username) -> str: + +def get_user_by_name(username): + """ + Get user by user name + + :param username: The name that needs to be fetched. Use user1 for testing. + :type username: str + + :rtype: User + """ return 'do some magic!' -def login_user(username, password) -> str: + +def login_user(username, password): + """ + Logs user into the system + + :param username: The user name for login + :type username: str + :param password: The password for login in clear text + :type password: str + + :rtype: str + """ return 'do some magic!' -def logout_user() -> str: + +def logout_user(): + """ + Logs out current logged in user session + + + :rtype: None + """ return 'do some magic!' -def update_user(username, body) -> str: + +def update_user(username, body): + """ + Updated user + This can only be done by the logged in user. + :param username: name that need to be deleted + :type username: str + :param body: Updated user object + :type body: dict | bytes + + :rtype: None + """ + if connexion.request.is_json: + body = User.from_dict(connexion.request.get_json()) return 'do some magic!' diff --git a/samples/server/petstore/flaskConnexion/init.py b/samples/server/petstore/flaskConnexion/init.py deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/samples/server/petstore/flaskConnexion/models/__init__.py b/samples/server/petstore/flaskConnexion/models/__init__.py new file mode 100644 index 00000000000..6571ad28e0f --- /dev/null +++ b/samples/server/petstore/flaskConnexion/models/__init__.py @@ -0,0 +1,10 @@ +# coding: utf-8 + +from __future__ import absolute_import +# import models into model package +from .api_response import ApiResponse +from .category import Category +from .order import Order +from .pet import Pet +from .tag import Tag +from .user import User diff --git a/samples/server/petstore/flaskConnexion/models/api_response.py b/samples/server/petstore/flaskConnexion/models/api_response.py new file mode 100644 index 00000000000..607a47e4dd4 --- /dev/null +++ b/samples/server/petstore/flaskConnexion/models/api_response.py @@ -0,0 +1,116 @@ +# coding: utf-8 + +from __future__ import absolute_import +from .base_model_ import Model +from datetime import date, datetime +from typing import List, Dict +from util import deserialize_model + + +class ApiResponse(Model): + """ + NOTE: This class is auto generated by the swagger code generator program. + Do not edit the class manually. + """ + def __init__(self, code: int=None, type: str=None, message: str=None): + """ + ApiResponse - a model defined in Swagger + + :param code: The code of this ApiResponse. + :type code: int + :param type: The type of this ApiResponse. + :type type: str + :param message: The message of this ApiResponse. + :type message: str + """ + self.swagger_types = { + 'code': int, + 'type': str, + 'message': str + } + + self.attribute_map = { + 'code': 'code', + 'type': 'type', + 'message': 'message' + } + + self._code = code + self._type = type + self._message = message + + @classmethod + def from_dict(cls, dikt) -> 'ApiResponse': + """ + Returns the dict as a model + + :param dikt: A dict. + :type: dict + :return: The ApiResponse of this ApiResponse. + :rtype: ApiResponse + """ + return deserialize_model(dikt, cls) + + @property + def code(self) -> int: + """ + Gets the code of this ApiResponse. + + :return: The code of this ApiResponse. + :rtype: int + """ + return self._code + + @code.setter + def code(self, code: int): + """ + Sets the code of this ApiResponse. + + :param code: The code of this ApiResponse. + :type code: int + """ + + self._code = code + + @property + def type(self) -> str: + """ + Gets the type of this ApiResponse. + + :return: The type of this ApiResponse. + :rtype: str + """ + return self._type + + @type.setter + def type(self, type: str): + """ + Sets the type of this ApiResponse. + + :param type: The type of this ApiResponse. + :type type: str + """ + + self._type = type + + @property + def message(self) -> str: + """ + Gets the message of this ApiResponse. + + :return: The message of this ApiResponse. + :rtype: str + """ + return self._message + + @message.setter + def message(self, message: str): + """ + Sets the message of this ApiResponse. + + :param message: The message of this ApiResponse. + :type message: str + """ + + self._message = message + diff --git a/samples/server/petstore/flaskConnexion/models/base_model_.py b/samples/server/petstore/flaskConnexion/models/base_model_.py new file mode 100644 index 00000000000..d10efa4f2c6 --- /dev/null +++ b/samples/server/petstore/flaskConnexion/models/base_model_.py @@ -0,0 +1,75 @@ +from pprint import pformat +from typing import TypeVar, Type +from six import iteritems +from util import deserialize_model + +T = TypeVar('T') + + +class Model(object): + # swaggerTypes: The key is attribute name and the value is attribute type. + swagger_types = {} + + # attributeMap: The key is attribute name and the value is json key in definition. + attribute_map = {} + + @classmethod + def from_dict(cls: Type[T], dikt) -> T: + """ + Returns the dict as a model + """ + return deserialize_model(dikt, cls) + + def to_dict(self): + """ + Returns the model properties as a dict + + :rtype: dict + """ + result = {} + + for attr, _ in iteritems(self.swagger_types): + value = getattr(self, attr) + if isinstance(value, list): + result[attr] = list(map( + lambda x: x.to_dict() if hasattr(x, "to_dict") else x, + value + )) + elif hasattr(value, "to_dict"): + result[attr] = value.to_dict() + elif isinstance(value, dict): + result[attr] = dict(map( + lambda item: (item[0], item[1].to_dict()) + if hasattr(item[1], "to_dict") else item, + value.items() + )) + else: + result[attr] = value + + return result + + def to_str(self): + """ + Returns the string representation of the model + + :rtype: str + """ + return pformat(self.to_dict()) + + def __repr__(self): + """ + For `print` and `pprint` + """ + return self.to_str() + + def __eq__(self, other): + """ + Returns true if both objects are equal + """ + return self.__dict__ == other.__dict__ + + def __ne__(self, other): + """ + Returns true if both objects are not equal + """ + return not self == other \ No newline at end of file diff --git a/samples/server/petstore/flaskConnexion/models/category.py b/samples/server/petstore/flaskConnexion/models/category.py new file mode 100644 index 00000000000..e36ffb3bffa --- /dev/null +++ b/samples/server/petstore/flaskConnexion/models/category.py @@ -0,0 +1,90 @@ +# coding: utf-8 + +from __future__ import absolute_import +from .base_model_ import Model +from datetime import date, datetime +from typing import List, Dict +from util import deserialize_model + + +class Category(Model): + """ + NOTE: This class is auto generated by the swagger code generator program. + Do not edit the class manually. + """ + def __init__(self, id: int=None, name: str=None): + """ + Category - a model defined in Swagger + + :param id: The id of this Category. + :type id: int + :param name: The name of this Category. + :type name: str + """ + self.swagger_types = { + 'id': int, + 'name': str + } + + self.attribute_map = { + 'id': 'id', + 'name': 'name' + } + + self._id = id + self._name = name + + @classmethod + def from_dict(cls, dikt) -> 'Category': + """ + Returns the dict as a model + + :param dikt: A dict. + :type: dict + :return: The Category of this Category. + :rtype: Category + """ + return deserialize_model(dikt, cls) + + @property + def id(self) -> int: + """ + Gets the id of this Category. + + :return: The id of this Category. + :rtype: int + """ + return self._id + + @id.setter + def id(self, id: int): + """ + Sets the id of this Category. + + :param id: The id of this Category. + :type id: int + """ + + self._id = id + + @property + def name(self) -> str: + """ + Gets the name of this Category. + + :return: The name of this Category. + :rtype: str + """ + return self._name + + @name.setter + def name(self, name: str): + """ + Sets the name of this Category. + + :param name: The name of this Category. + :type name: str + """ + + self._name = name + diff --git a/samples/server/petstore/flaskConnexion/models/order.py b/samples/server/petstore/flaskConnexion/models/order.py new file mode 100644 index 00000000000..1b4ad9f849d --- /dev/null +++ b/samples/server/petstore/flaskConnexion/models/order.py @@ -0,0 +1,202 @@ +# coding: utf-8 + +from __future__ import absolute_import +from .base_model_ import Model +from datetime import date, datetime +from typing import List, Dict +from util import deserialize_model + + +class Order(Model): + """ + NOTE: This class is auto generated by the swagger code generator program. + Do not edit the class manually. + """ + def __init__(self, id: int=None, pet_id: int=None, quantity: int=None, ship_date: datetime=None, status: str=None, complete: bool=False): + """ + Order - a model defined in Swagger + + :param id: The id of this Order. + :type id: int + :param pet_id: The pet_id of this Order. + :type pet_id: int + :param quantity: The quantity of this Order. + :type quantity: int + :param ship_date: The ship_date of this Order. + :type ship_date: datetime + :param status: The status of this Order. + :type status: str + :param complete: The complete of this Order. + :type complete: bool + """ + self.swagger_types = { + 'id': int, + 'pet_id': int, + 'quantity': int, + 'ship_date': datetime, + 'status': str, + 'complete': bool + } + + self.attribute_map = { + 'id': 'id', + 'pet_id': 'petId', + 'quantity': 'quantity', + 'ship_date': 'shipDate', + 'status': 'status', + 'complete': 'complete' + } + + self._id = id + self._pet_id = pet_id + self._quantity = quantity + self._ship_date = ship_date + self._status = status + self._complete = complete + + @classmethod + def from_dict(cls, dikt) -> 'Order': + """ + Returns the dict as a model + + :param dikt: A dict. + :type: dict + :return: The Order of this Order. + :rtype: Order + """ + return deserialize_model(dikt, cls) + + @property + def id(self) -> int: + """ + Gets the id of this Order. + + :return: The id of this Order. + :rtype: int + """ + return self._id + + @id.setter + def id(self, id: int): + """ + Sets the id of this Order. + + :param id: The id of this Order. + :type id: int + """ + + self._id = id + + @property + def pet_id(self) -> int: + """ + Gets the pet_id of this Order. + + :return: The pet_id of this Order. + :rtype: int + """ + return self._pet_id + + @pet_id.setter + def pet_id(self, pet_id: int): + """ + Sets the pet_id of this Order. + + :param pet_id: The pet_id of this Order. + :type pet_id: int + """ + + self._pet_id = pet_id + + @property + def quantity(self) -> int: + """ + Gets the quantity of this Order. + + :return: The quantity of this Order. + :rtype: int + """ + return self._quantity + + @quantity.setter + def quantity(self, quantity: int): + """ + Sets the quantity of this Order. + + :param quantity: The quantity of this Order. + :type quantity: int + """ + + self._quantity = quantity + + @property + def ship_date(self) -> datetime: + """ + Gets the ship_date of this Order. + + :return: The ship_date of this Order. + :rtype: datetime + """ + return self._ship_date + + @ship_date.setter + def ship_date(self, ship_date: datetime): + """ + Sets the ship_date of this Order. + + :param ship_date: The ship_date of this Order. + :type ship_date: datetime + """ + + self._ship_date = ship_date + + @property + def status(self) -> str: + """ + Gets the status of this Order. + Order Status + + :return: The status of this Order. + :rtype: str + """ + return self._status + + @status.setter + def status(self, status: str): + """ + Sets the status of this Order. + Order Status + + :param status: The status of this Order. + :type status: str + """ + allowed_values = ["placed", "approved", "delivered"] + if status not in allowed_values: + raise ValueError( + "Invalid value for `status` ({0}), must be one of {1}" + .format(status, allowed_values) + ) + + self._status = status + + @property + def complete(self) -> bool: + """ + Gets the complete of this Order. + + :return: The complete of this Order. + :rtype: bool + """ + return self._complete + + @complete.setter + def complete(self, complete: bool): + """ + Sets the complete of this Order. + + :param complete: The complete of this Order. + :type complete: bool + """ + + self._complete = complete + diff --git a/samples/server/petstore/flaskConnexion/models/pet.py b/samples/server/petstore/flaskConnexion/models/pet.py new file mode 100644 index 00000000000..11ad67f7649 --- /dev/null +++ b/samples/server/petstore/flaskConnexion/models/pet.py @@ -0,0 +1,208 @@ +# coding: utf-8 + +from __future__ import absolute_import +from models.category import Category +from models.tag import Tag +from .base_model_ import Model +from datetime import date, datetime +from typing import List, Dict +from util import deserialize_model + + +class Pet(Model): + """ + NOTE: This class is auto generated by the swagger code generator program. + Do not edit the class manually. + """ + def __init__(self, id: int=None, category: Category=None, name: str=None, photo_urls: List[str]=None, tags: List[Tag]=None, status: str=None): + """ + Pet - a model defined in Swagger + + :param id: The id of this Pet. + :type id: int + :param category: The category of this Pet. + :type category: Category + :param name: The name of this Pet. + :type name: str + :param photo_urls: The photo_urls of this Pet. + :type photo_urls: List[str] + :param tags: The tags of this Pet. + :type tags: List[Tag] + :param status: The status of this Pet. + :type status: str + """ + self.swagger_types = { + 'id': int, + 'category': Category, + 'name': str, + 'photo_urls': List[str], + 'tags': List[Tag], + 'status': str + } + + self.attribute_map = { + 'id': 'id', + 'category': 'category', + 'name': 'name', + 'photo_urls': 'photoUrls', + 'tags': 'tags', + 'status': 'status' + } + + self._id = id + self._category = category + self._name = name + self._photo_urls = photo_urls + self._tags = tags + self._status = status + + @classmethod + def from_dict(cls, dikt) -> 'Pet': + """ + Returns the dict as a model + + :param dikt: A dict. + :type: dict + :return: The Pet of this Pet. + :rtype: Pet + """ + return deserialize_model(dikt, cls) + + @property + def id(self) -> int: + """ + Gets the id of this Pet. + + :return: The id of this Pet. + :rtype: int + """ + return self._id + + @id.setter + def id(self, id: int): + """ + Sets the id of this Pet. + + :param id: The id of this Pet. + :type id: int + """ + + self._id = id + + @property + def category(self) -> Category: + """ + Gets the category of this Pet. + + :return: The category of this Pet. + :rtype: Category + """ + return self._category + + @category.setter + def category(self, category: Category): + """ + Sets the category of this Pet. + + :param category: The category of this Pet. + :type category: Category + """ + + self._category = category + + @property + def name(self) -> str: + """ + Gets the name of this Pet. + + :return: The name of this Pet. + :rtype: str + """ + return self._name + + @name.setter + def name(self, name: str): + """ + Sets the name of this Pet. + + :param name: The name of this Pet. + :type name: str + """ + if name is None: + raise ValueError("Invalid value for `name`, must not be `None`") + + self._name = name + + @property + def photo_urls(self) -> List[str]: + """ + Gets the photo_urls of this Pet. + + :return: The photo_urls of this Pet. + :rtype: List[str] + """ + return self._photo_urls + + @photo_urls.setter + def photo_urls(self, photo_urls: List[str]): + """ + Sets the photo_urls of this Pet. + + :param photo_urls: The photo_urls of this Pet. + :type photo_urls: List[str] + """ + if photo_urls is None: + raise ValueError("Invalid value for `photo_urls`, must not be `None`") + + self._photo_urls = photo_urls + + @property + def tags(self) -> List[Tag]: + """ + Gets the tags of this Pet. + + :return: The tags of this Pet. + :rtype: List[Tag] + """ + return self._tags + + @tags.setter + def tags(self, tags: List[Tag]): + """ + Sets the tags of this Pet. + + :param tags: The tags of this Pet. + :type tags: List[Tag] + """ + + self._tags = tags + + @property + def status(self) -> str: + """ + Gets the status of this Pet. + pet status in the store + + :return: The status of this Pet. + :rtype: str + """ + return self._status + + @status.setter + def status(self, status: str): + """ + Sets the status of this Pet. + pet status in the store + + :param status: The status of this Pet. + :type status: str + """ + allowed_values = ["available", "pending", "sold"] + if status not in allowed_values: + raise ValueError( + "Invalid value for `status` ({0}), must be one of {1}" + .format(status, allowed_values) + ) + + self._status = status + diff --git a/samples/server/petstore/flaskConnexion/models/tag.py b/samples/server/petstore/flaskConnexion/models/tag.py new file mode 100644 index 00000000000..41f1b024fe8 --- /dev/null +++ b/samples/server/petstore/flaskConnexion/models/tag.py @@ -0,0 +1,90 @@ +# coding: utf-8 + +from __future__ import absolute_import +from .base_model_ import Model +from datetime import date, datetime +from typing import List, Dict +from util import deserialize_model + + +class Tag(Model): + """ + NOTE: This class is auto generated by the swagger code generator program. + Do not edit the class manually. + """ + def __init__(self, id: int=None, name: str=None): + """ + Tag - a model defined in Swagger + + :param id: The id of this Tag. + :type id: int + :param name: The name of this Tag. + :type name: str + """ + self.swagger_types = { + 'id': int, + 'name': str + } + + self.attribute_map = { + 'id': 'id', + 'name': 'name' + } + + self._id = id + self._name = name + + @classmethod + def from_dict(cls, dikt) -> 'Tag': + """ + Returns the dict as a model + + :param dikt: A dict. + :type: dict + :return: The Tag of this Tag. + :rtype: Tag + """ + return deserialize_model(dikt, cls) + + @property + def id(self) -> int: + """ + Gets the id of this Tag. + + :return: The id of this Tag. + :rtype: int + """ + return self._id + + @id.setter + def id(self, id: int): + """ + Sets the id of this Tag. + + :param id: The id of this Tag. + :type id: int + """ + + self._id = id + + @property + def name(self) -> str: + """ + Gets the name of this Tag. + + :return: The name of this Tag. + :rtype: str + """ + return self._name + + @name.setter + def name(self, name: str): + """ + Sets the name of this Tag. + + :param name: The name of this Tag. + :type name: str + """ + + self._name = name + diff --git a/samples/server/petstore/flaskConnexion/models/user.py b/samples/server/petstore/flaskConnexion/models/user.py new file mode 100644 index 00000000000..77fdaa7a252 --- /dev/null +++ b/samples/server/petstore/flaskConnexion/models/user.py @@ -0,0 +1,248 @@ +# coding: utf-8 + +from __future__ import absolute_import +from .base_model_ import Model +from datetime import date, datetime +from typing import List, Dict +from util import deserialize_model + + +class User(Model): + """ + NOTE: This class is auto generated by the swagger code generator program. + Do not edit the class manually. + """ + def __init__(self, id: int=None, username: str=None, first_name: str=None, last_name: str=None, email: str=None, password: str=None, phone: str=None, user_status: int=None): + """ + User - a model defined in Swagger + + :param id: The id of this User. + :type id: int + :param username: The username of this User. + :type username: str + :param first_name: The first_name of this User. + :type first_name: str + :param last_name: The last_name of this User. + :type last_name: str + :param email: The email of this User. + :type email: str + :param password: The password of this User. + :type password: str + :param phone: The phone of this User. + :type phone: str + :param user_status: The user_status of this User. + :type user_status: int + """ + self.swagger_types = { + 'id': int, + 'username': str, + 'first_name': str, + 'last_name': str, + 'email': str, + 'password': str, + 'phone': str, + 'user_status': int + } + + self.attribute_map = { + 'id': 'id', + 'username': 'username', + 'first_name': 'firstName', + 'last_name': 'lastName', + 'email': 'email', + 'password': 'password', + 'phone': 'phone', + 'user_status': 'userStatus' + } + + self._id = id + self._username = username + self._first_name = first_name + self._last_name = last_name + self._email = email + self._password = password + self._phone = phone + self._user_status = user_status + + @classmethod + def from_dict(cls, dikt) -> 'User': + """ + Returns the dict as a model + + :param dikt: A dict. + :type: dict + :return: The User of this User. + :rtype: User + """ + return deserialize_model(dikt, cls) + + @property + def id(self) -> int: + """ + Gets the id of this User. + + :return: The id of this User. + :rtype: int + """ + return self._id + + @id.setter + def id(self, id: int): + """ + Sets the id of this User. + + :param id: The id of this User. + :type id: int + """ + + self._id = id + + @property + def username(self) -> str: + """ + Gets the username of this User. + + :return: The username of this User. + :rtype: str + """ + return self._username + + @username.setter + def username(self, username: str): + """ + Sets the username of this User. + + :param username: The username of this User. + :type username: str + """ + + self._username = username + + @property + def first_name(self) -> str: + """ + Gets the first_name of this User. + + :return: The first_name of this User. + :rtype: str + """ + return self._first_name + + @first_name.setter + def first_name(self, first_name: str): + """ + Sets the first_name of this User. + + :param first_name: The first_name of this User. + :type first_name: str + """ + + self._first_name = first_name + + @property + def last_name(self) -> str: + """ + Gets the last_name of this User. + + :return: The last_name of this User. + :rtype: str + """ + return self._last_name + + @last_name.setter + def last_name(self, last_name: str): + """ + Sets the last_name of this User. + + :param last_name: The last_name of this User. + :type last_name: str + """ + + self._last_name = last_name + + @property + def email(self) -> str: + """ + Gets the email of this User. + + :return: The email of this User. + :rtype: str + """ + return self._email + + @email.setter + def email(self, email: str): + """ + Sets the email of this User. + + :param email: The email of this User. + :type email: str + """ + + self._email = email + + @property + def password(self) -> str: + """ + Gets the password of this User. + + :return: The password of this User. + :rtype: str + """ + return self._password + + @password.setter + def password(self, password: str): + """ + Sets the password of this User. + + :param password: The password of this User. + :type password: str + """ + + self._password = password + + @property + def phone(self) -> str: + """ + Gets the phone of this User. + + :return: The phone of this User. + :rtype: str + """ + return self._phone + + @phone.setter + def phone(self, phone: str): + """ + Sets the phone of this User. + + :param phone: The phone of this User. + :type phone: str + """ + + self._phone = phone + + @property + def user_status(self) -> int: + """ + Gets the user_status of this User. + User Status + + :return: The user_status of this User. + :rtype: int + """ + return self._user_status + + @user_status.setter + def user_status(self, user_status: int): + """ + Sets the user_status of this User. + User Status + + :param user_status: The user_status of this User. + :type user_status: int + """ + + self._user_status = user_status + diff --git a/samples/server/petstore/flaskConnexion/swagger/swagger.yaml b/samples/server/petstore/flaskConnexion/swagger/swagger.yaml index 7b412611171..9e8598b591b 100644 --- a/samples/server/petstore/flaskConnexion/swagger/swagger.yaml +++ b/samples/server/petstore/flaskConnexion/swagger/swagger.yaml @@ -110,11 +110,11 @@ paths: type: "array" items: type: "string" - default: "available" enum: - "available" - "pending" - "sold" + default: "available" collectionFormat: "csv" responses: 200: @@ -607,10 +607,6 @@ paths: x-tags: - tag: "user" securityDefinitions: - api_key: - type: "apiKey" - name: "api_key" - in: "header" petstore_auth: type: "oauth2" authorizationUrl: "http://petstore.swagger.io/api/oauth/dialog" @@ -618,6 +614,10 @@ securityDefinitions: scopes: write:pets: "modify pets in your account" read:pets: "read your pets" + api_key: + type: "apiKey" + name: "api_key" + in: "header" definitions: Order: type: "object" diff --git a/samples/server/petstore/flaskConnexion/util.py b/samples/server/petstore/flaskConnexion/util.py new file mode 100644 index 00000000000..40c72d43ebd --- /dev/null +++ b/samples/server/petstore/flaskConnexion/util.py @@ -0,0 +1,149 @@ +from typing import GenericMeta +from datetime import datetime, date +from six import integer_types, iteritems + + +def _deserialize(data, klass): + """ + Deserializes dict, list, str into an object. + + :param data: dict, list or str. + :param klass: class literal, or string of class name. + + :return: object. + """ + if data is None: + return None + + if klass in integer_types or klass in (float, str, bool): + return _deserialize_primitive(data, klass) + elif klass == object: + return _deserialize_object(data) + elif klass == date: + return deserialize_date(data) + elif klass == datetime: + return deserialize_datetime(data) + elif type(klass) == GenericMeta: + if klass.__extra__ == list: + return _deserialize_list(data, klass.__args__[0]) + if klass.__extra__ == dict: + return _deserialize_dict(data, klass.__args__[1]) + else: + return deserialize_model(data, klass) + + +def _deserialize_primitive(data, klass): + """ + Deserializes to primitive type. + + :param data: data to deserialize. + :param klass: class literal. + + :return: int, long, float, str, bool. + :rtype: int | long | float | str | bool + """ + try: + value = klass(data) + except UnicodeEncodeError: + value = unicode(data) + except TypeError: + value = data + return value + + +def _deserialize_object(value): + """ + Return a original value. + + :return: object. + """ + return value + + +def deserialize_date(string): + """ + Deserializes string to date. + + :param string: str. + :type string: str + :return: date. + :rtype: date + """ + try: + from dateutil.parser import parse + return parse(string).date() + except ImportError: + return string + + +def deserialize_datetime(string): + """ + Deserializes string to datetime. + + The string should be in iso8601 datetime format. + + :param string: str. + :type string: str + :return: datetime. + :rtype: datetime + """ + try: + from dateutil.parser import parse + return parse(string) + except ImportError: + return string + + +def deserialize_model(data, klass): + """ + Deserializes list or dict to model. + + :param data: dict, list. + :type data: dict | list + :param klass: class literal. + :return: model object. + """ + instance = klass() + + if not instance.swagger_types: + return data + + for attr, attr_type in iteritems(instance.swagger_types): + if data is not None \ + and instance.attribute_map[attr] in data \ + and isinstance(data, (list, dict)): + value = data[instance.attribute_map[attr]] + setattr(instance, attr, _deserialize(value, attr_type)) + + return instance + + +def _deserialize_list(data, boxed_type): + """ + Deserializes a list and its elements. + + :param data: list to deserialize. + :type data: list + :param boxed_type: class literal. + + :return: deserialized list. + :rtype: list + """ + return [_deserialize(sub_data, boxed_type) + for sub_data in data] + + + +def _deserialize_dict(data, boxed_type): + """ + Deserializes a dict and its elements. + + :param data: dict to deserialize. + :type data: dict + :param boxed_type: class literal. + + :return: deserialized dict. + :rtype: dict + """ + return {k: _deserialize(v, boxed_type) + for k, v in iteritems(data)}