diff --git a/bin/configs/python-flask.yaml b/bin/configs/python-flask.yaml index c8bc1d08f5d4..570206be2bc1 100644 --- a/bin/configs/python-flask.yaml +++ b/bin/configs/python-flask.yaml @@ -1,4 +1,4 @@ generatorName: python-flask outputDir: samples/server/petstore/python-flask -inputSpec: modules/openapi-generator/src/test/resources/2_0/petstore.yaml +inputSpec: modules/openapi-generator/src/test/resources/2_0/python-flask/petstore.yaml templateDir: modules/openapi-generator/src/main/resources/python-flask diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractPythonCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractPythonCodegen.java index c571b09f6bb7..c721a3c4c282 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractPythonCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractPythonCodegen.java @@ -1981,4 +1981,17 @@ public String toEnumValue(String value, String datatype) { public String toEnumDefaultValue(String value, String datatype) { return value; } + + /** + * checks if the data should be classified as "string" in enum + * e.g. double in C# needs to be double-quoted (e.g. "2.8") by treating it as a string + * In the future, we may rename this function to "isEnumString" + * + * @param dataType data type + * @return true if it's a enum string + */ + @Override + public boolean isDataTypeString(String dataType) { + return "str".equals(dataType); + } } diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractPythonConnexionServerCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractPythonConnexionServerCodegen.java index 9fdfde04999f..a171b8f77513 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractPythonConnexionServerCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractPythonConnexionServerCodegen.java @@ -16,17 +16,9 @@ package org.openapitools.codegen.languages; -import static org.openapitools.codegen.utils.StringUtils.camelize; - import java.io.File; import java.io.IOException; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; +import java.util.*; import org.apache.commons.lang3.StringUtils; import org.openapitools.codegen.CliOption; @@ -69,6 +61,8 @@ import io.swagger.v3.oas.models.parameters.RequestBody; import io.swagger.v3.oas.models.security.SecurityScheme; +import static org.openapitools.codegen.utils.StringUtils.*; + public abstract class AbstractPythonConnexionServerCodegen extends AbstractPythonCodegen implements CodegenConfig { private static class PythonBooleanSerializer extends JsonSerializer { @Override @@ -178,7 +172,7 @@ public AbstractPythonConnexionServerCodegen(String templateDirectory, boolean fi cliOptions.add(new CliOption(USE_PYTHON_SRC_ROOT_IN_IMPORTS, "include pythonSrcRoot in import namespaces."). defaultValue("false")); cliOptions.add(new CliOption(MOVE_TESTS_UNDER_PYTHON_SRC_ROOT, "generates test under the pythonSrcRoot folder.") - .defaultValue("false")); + .defaultValue("false")); } protected void addSupportingFiles() { @@ -333,7 +327,6 @@ public String toApiName(String name) { } - @Override public String toApiTestFilename(String name) { return "test_" + toApiFilename(name); @@ -636,12 +629,6 @@ public void postProcessModelProperty(CodegenModel model, CodegenProperty propert postProcessPattern(property.pattern, property.vendorExtensions); } - @Override - public ModelsMap postProcessModels(ModelsMap objs) { - // process enum in models - return postProcessModelsEnum(objs); - } - @Override public Map postProcessAllModels(Map objs) { Map result = super.postProcessAllModels(objs); diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/PythonClientCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/PythonClientCodegen.java index b6dc45052487..68aba6465839 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/PythonClientCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/PythonClientCodegen.java @@ -464,20 +464,6 @@ protected void addAdditionPropertiesToCodeGenModel(CodegenModel codegenModel, Sc } } - - /** - * checks if the data should be classified as "string" in enum - * e.g. double in C# needs to be double-quoted (e.g. "2.8") by treating it as a string - * In the future, we may rename this function to "isEnumString" - * - * @param dataType data type - * @return true if it's a enum string - */ - @Override - public boolean isDataTypeString(String dataType) { - return "str".equals(dataType); - } - @Override public String escapeReservedWord(String name) { if (this.reservedWordsMappings().containsKey(name)) { diff --git a/modules/openapi-generator/src/main/resources/python-flask/model.mustache b/modules/openapi-generator/src/main/resources/python-flask/model.mustache index b96033456082..47394704bf96 100644 --- a/modules/openapi-generator/src/main/resources/python-flask/model.mustache +++ b/modules/openapi-generator/src/main/resources/python-flask/model.mustache @@ -29,7 +29,7 @@ class {{classname}}(Model): allowed enum values """ {{#enumVars}} - {{name}} = {{{value}}}{{^-last}} + {{{name}}} = {{{value}}}{{^-last}} {{/-last}} {{/enumVars}} {{/allowableValues}} diff --git a/modules/openapi-generator/src/test/resources/2_0/python-flask/petstore.yaml b/modules/openapi-generator/src/test/resources/2_0/python-flask/petstore.yaml new file mode 100644 index 000000000000..952104fbb701 --- /dev/null +++ b/modules/openapi-generator/src/test/resources/2_0/python-flask/petstore.yaml @@ -0,0 +1,703 @@ +swagger: '2.0' +info: + description: 'This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters.' + version: 1.0.0 + title: OpenAPI Petstore + license: + name: Apache-2.0 + url: 'https://www.apache.org/licenses/LICENSE-2.0.html' +host: petstore.swagger.io +basePath: /v2 +tags: + - name: pet + description: Everything about your Pets + - name: store + description: Access to Petstore orders + - name: user + description: Operations about user +schemes: + - http +paths: + /pet: + post: + tags: + - pet + summary: Add a new pet to the store + description: '' + operationId: addPet + consumes: + - application/json + - application/xml + produces: + - application/xml + - application/json + parameters: + - in: body + name: body + description: Pet object that needs to be added to the store + required: true + schema: + $ref: '#/definitions/Pet' + responses: + '405': + description: Invalid input + security: + - petstore_auth: + - 'write:pets' + - 'read:pets' + put: + tags: + - pet + summary: Update an existing pet + description: '' + operationId: updatePet + consumes: + - application/json + - application/xml + produces: + - application/xml + - application/json + parameters: + - in: body + name: body + description: Pet object that needs to be added to the store + required: true + schema: + $ref: '#/definitions/Pet' + responses: + '400': + description: Invalid ID supplied + '404': + description: Pet not found + '405': + description: Validation exception + security: + - petstore_auth: + - 'write:pets' + - 'read:pets' + /pet/findByStatus: + get: + tags: + - pet + summary: Finds Pets by status + description: Multiple status values can be provided with comma separated strings + operationId: findPetsByStatus + produces: + - application/xml + - application/json + parameters: + - name: status + in: query + description: Status values that need to be considered for filter + required: true + type: array + items: + type: string + enum: + - available + - pending + - sold + default: available + collectionFormat: csv + responses: + '200': + description: successful operation + schema: + type: array + items: + $ref: '#/definitions/Pet' + '400': + description: Invalid status value + security: + - petstore_auth: + - 'write:pets' + - 'read:pets' + /pet/findByTags: + get: + tags: + - pet + summary: Finds Pets by tags + description: 'Multiple tags can be provided with comma separated strings. Use tag1, tag2, tag3 for testing.' + operationId: findPetsByTags + produces: + - application/xml + - application/json + parameters: + - name: tags + in: query + description: Tags to filter by + required: true + type: array + items: + type: string + collectionFormat: csv + responses: + '200': + description: successful operation + schema: + type: array + items: + $ref: '#/definitions/Pet' + '400': + description: Invalid tag value + security: + - petstore_auth: + - 'write:pets' + - 'read:pets' + deprecated: true + '/pet/{petId}': + get: + tags: + - pet + summary: Find pet by ID + description: Returns a single pet + operationId: getPetById + produces: + - application/xml + - application/json + parameters: + - name: petId + in: path + description: ID of pet to return + required: true + type: integer + format: int64 + responses: + '200': + description: successful operation + schema: + $ref: '#/definitions/Pet' + '400': + description: Invalid ID supplied + '404': + description: Pet not found + security: + - api_key: [] + post: + tags: + - pet + summary: Updates a pet in the store with form data + description: '' + operationId: updatePetWithForm + consumes: + - application/x-www-form-urlencoded + produces: + - application/xml + - application/json + parameters: + - name: petId + in: path + description: ID of pet that needs to be updated + required: true + type: integer + format: int64 + - name: name + in: formData + description: Updated name of the pet + required: false + type: string + - name: status + in: formData + description: Updated status of the pet + required: false + type: string + responses: + '405': + description: Invalid input + security: + - petstore_auth: + - 'write:pets' + - 'read:pets' + delete: + tags: + - pet + summary: Deletes a pet + description: '' + operationId: deletePet + produces: + - application/xml + - application/json + parameters: + - name: api_key + in: header + required: false + type: string + - name: petId + in: path + description: Pet id to delete + required: true + type: integer + format: int64 + responses: + '400': + description: Invalid pet value + security: + - petstore_auth: + - 'write:pets' + - 'read:pets' + '/pet/{petId}/uploadImage': + post: + tags: + - pet + summary: uploads an image + description: '' + operationId: uploadFile + consumes: + - multipart/form-data + produces: + - application/json + parameters: + - name: petId + in: path + description: ID of pet to update + required: true + type: integer + format: int64 + - name: additionalMetadata + in: formData + description: Additional data to pass to server + required: false + type: string + - name: file + in: formData + description: file to upload + required: false + type: file + responses: + '200': + description: successful operation + schema: + $ref: '#/definitions/ApiResponse' + security: + - petstore_auth: + - 'write:pets' + - 'read:pets' + /store/inventory: + get: + tags: + - store + summary: Returns pet inventories by status + description: Returns a map of status codes to quantities + operationId: getInventory + produces: + - application/json + parameters: [] + responses: + '200': + description: successful operation + schema: + type: object + additionalProperties: + type: integer + format: int32 + security: + - api_key: [] + /store/order: + post: + tags: + - store + summary: Place an order for a pet + description: '' + operationId: placeOrder + produces: + - application/xml + - application/json + parameters: + - in: body + name: body + description: order placed for purchasing the pet + required: true + schema: + $ref: '#/definitions/Order' + responses: + '200': + description: successful operation + schema: + $ref: '#/definitions/Order' + '400': + description: Invalid Order + '/store/order/{orderId}': + get: + tags: + - store + summary: Find purchase order by ID + description: 'For valid response try integer IDs with value <= 5 or > 10. Other values will generate exceptions' + operationId: getOrderById + produces: + - application/xml + - application/json + parameters: + - name: orderId + in: path + description: ID of pet that needs to be fetched + required: true + type: integer + maximum: 5 + minimum: 1 + format: int64 + responses: + '200': + description: successful operation + schema: + $ref: '#/definitions/Order' + '400': + description: Invalid ID supplied + '404': + description: Order not found + delete: + tags: + - store + summary: Delete purchase order by ID + description: For valid response try integer IDs with value < 1000. Anything above 1000 or nonintegers will generate API errors + operationId: deleteOrder + produces: + - application/xml + - application/json + parameters: + - name: orderId + in: path + description: ID of the order that needs to be deleted + required: true + type: string + responses: + '400': + description: Invalid ID supplied + '404': + description: Order not found + /user: + post: + tags: + - user + summary: Create user + description: This can only be done by the logged in user. + operationId: createUser + produces: + - application/xml + - application/json + parameters: + - in: body + name: body + description: Created user object + required: true + schema: + $ref: '#/definitions/User' + responses: + default: + description: successful operation + /user/createWithArray: + post: + tags: + - user + summary: Creates list of users with given input array + description: '' + operationId: createUsersWithArrayInput + produces: + - application/xml + - application/json + parameters: + - in: body + name: body + description: List of user object + required: true + schema: + type: array + items: + $ref: '#/definitions/User' + responses: + default: + description: successful operation + /user/createWithList: + post: + tags: + - user + summary: Creates list of users with given input array + description: '' + operationId: createUsersWithListInput + produces: + - application/xml + - application/json + parameters: + - in: body + name: body + description: List of user object + required: true + schema: + type: array + items: + $ref: '#/definitions/User' + responses: + default: + description: successful operation + /user/login: + get: + tags: + - user + summary: Logs user into the system + description: '' + operationId: loginUser + produces: + - application/xml + - application/json + parameters: + - name: username + in: query + description: The user name for login + required: true + type: string + - name: password + in: query + description: The password for login in clear text + required: true + type: string + responses: + '200': + description: successful operation + schema: + type: string + headers: + X-Rate-Limit: + type: integer + format: int32 + description: calls per hour allowed by the user + X-Expires-After: + type: string + format: date-time + description: date in UTC when token expires + '400': + description: Invalid username/password supplied + /user/logout: + get: + tags: + - user + summary: Logs out current logged in user session + description: '' + operationId: logoutUser + produces: + - application/xml + - application/json + parameters: [] + responses: + default: + description: successful operation + '/user/{username}': + get: + tags: + - user + summary: Get user by user name + description: '' + operationId: getUserByName + produces: + - application/xml + - application/json + parameters: + - name: username + in: path + description: 'The name that needs to be fetched. Use user1 for testing.' + required: true + type: string + responses: + '200': + description: successful operation + schema: + $ref: '#/definitions/User' + '400': + description: Invalid username supplied + '404': + description: User not found + put: + tags: + - user + summary: Updated user + description: This can only be done by the logged in user. + operationId: updateUser + produces: + - application/xml + - application/json + parameters: + - name: username + in: path + description: name that need to be deleted + required: true + type: string + - in: body + name: body + description: Updated user object + required: true + schema: + $ref: '#/definitions/User' + responses: + '400': + description: Invalid user supplied + '404': + description: User not found + delete: + tags: + - user + summary: Delete user + description: This can only be done by the logged in user. + operationId: deleteUser + produces: + - application/xml + - application/json + parameters: + - name: username + in: path + description: The name that needs to be deleted + required: true + type: string + responses: + '400': + description: Invalid username supplied + '404': + description: User not found +securityDefinitions: + petstore_auth: + type: oauth2 + authorizationUrl: 'http://petstore.swagger.io/api/oauth/dialog' + flow: implicit + scopes: + 'write:pets': modify pets in your account + 'read:pets': read your pets + api_key: + type: apiKey + name: api_key + in: header +definitions: + Order: + title: Pet Order + description: An order for a pets from the pet store + type: object + properties: + id: + type: integer + format: int64 + petId: + type: integer + format: int64 + quantity: + type: integer + format: int32 + shipDate: + type: string + format: date-time + status: + type: string + description: Order Status + enum: + - placed + - approved + - delivered + complete: + type: boolean + default: false + xml: + name: Order + Category: + title: Pet category + description: A category for a pet + type: object + properties: + id: + type: integer + format: int64 + name: + type: string + xml: + name: Category + User: + title: a User + description: A User who is purchasing from the pet store + type: object + properties: + id: + type: integer + format: int64 + username: + type: string + firstName: + type: string + lastName: + type: string + email: + type: string + password: + type: string + phone: + type: string + userStatus: + type: integer + format: int32 + description: User Status + xml: + name: User + Tag: + title: Pet Tag + description: A tag for a pet + type: object + properties: + id: + type: integer + format: int64 + name: + type: string + xml: + name: Tag + Pet: + title: a Pet + description: A pet for sale in the pet store + type: object + required: + - name + - photoUrls + properties: + id: + type: integer + format: int64 + category: + $ref: '#/definitions/Category' + name: + type: string + example: doggie + photoUrls: + type: array + xml: + name: photoUrl + wrapped: true + items: + type: string + tags: + type: array + xml: + name: tag + wrapped: true + items: + $ref: '#/definitions/Tag' + status: + type: string + description: pet status in the store + enum: + - available + - pending + - sold + xml: + name: Pet + ApiResponse: + title: An uploaded response + description: Describes the result of uploading an image resource + type: object + properties: + code: + type: integer + format: int32 + type: + type: string + message: + type: string + EnumModel: + enum: + - available> + - pending< + - sold + - 1 + - 2 + type: string diff --git a/samples/server/petstore/python-flask/.openapi-generator/FILES b/samples/server/petstore/python-flask/.openapi-generator/FILES index 9dbaae5533b5..c08d341ed532 100644 --- a/samples/server/petstore/python-flask/.openapi-generator/FILES +++ b/samples/server/petstore/python-flask/.openapi-generator/FILES @@ -16,6 +16,7 @@ openapi_server/models/__init__.py openapi_server/models/api_response.py openapi_server/models/base_model.py openapi_server/models/category.py +openapi_server/models/enum_model.py openapi_server/models/order.py openapi_server/models/pet.py openapi_server/models/tag.py diff --git a/samples/server/petstore/python-flask/openapi_server/models/__init__.py b/samples/server/petstore/python-flask/openapi_server/models/__init__.py index 24ea9866d7bf..21d4d1aeb93d 100644 --- a/samples/server/petstore/python-flask/openapi_server/models/__init__.py +++ b/samples/server/petstore/python-flask/openapi_server/models/__init__.py @@ -2,6 +2,7 @@ # import models into model package from openapi_server.models.api_response import ApiResponse from openapi_server.models.category import Category +from openapi_server.models.enum_model import EnumModel from openapi_server.models.order import Order from openapi_server.models.pet import Pet from openapi_server.models.tag import Tag diff --git a/samples/server/petstore/python-flask/openapi_server/models/enum_model.py b/samples/server/petstore/python-flask/openapi_server/models/enum_model.py new file mode 100644 index 000000000000..5d60d2aaef2f --- /dev/null +++ b/samples/server/petstore/python-flask/openapi_server/models/enum_model.py @@ -0,0 +1,42 @@ +from datetime import date, datetime # noqa: F401 + +from typing import List, Dict # noqa: F401 + +from openapi_server.models.base_model import Model +from openapi_server import util + + +class EnumModel(Model): + """NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + + Do not edit the class manually. + """ + + """ + allowed enum values + """ + AVAILABLE_GREATER_THAN = 'available>' + PENDING_LESS_THAN = 'pending<' + SOLD = 'sold' + ENUM_1 = '1' + ENUM_2 = '2' + def __init__(self): # noqa: E501 + """EnumModel - a model defined in OpenAPI + + """ + self.openapi_types = { + } + + self.attribute_map = { + } + + @classmethod + def from_dict(cls, dikt) -> 'EnumModel': + """Returns the dict as a model + + :param dikt: A dict. + :type: dict + :return: The EnumModel of this EnumModel. # noqa: E501 + :rtype: EnumModel + """ + return util.deserialize_model(dikt, cls) diff --git a/samples/server/petstore/python-flask/openapi_server/openapi/openapi.yaml b/samples/server/petstore/python-flask/openapi_server/openapi/openapi.yaml index 92baa6a0525e..21e70929a17c 100644 --- a/samples/server/petstore/python-flask/openapi_server/openapi/openapi.yaml +++ b/samples/server/petstore/python-flask/openapi_server/openapi/openapi.yaml @@ -780,6 +780,14 @@ components: type: string title: An uploaded response type: object + EnumModel: + enum: + - available> + - pending< + - sold + - "1" + - "2" + type: string updatePetWithForm_request: properties: name: