From 3a8f6308a7ce56f144ab1e1172d7611a336a0149 Mon Sep 17 00:00:00 2001
From: Artem Shubovych <ashubovych@atlassian.com>
Date: Wed, 8 Jan 2020 15:01:17 +1100
Subject: [PATCH 1/2] Fix python-flask-python2 and python-flask tests by NOT
 wrapping datetime in a string Python can't really deepcopy objects well
 https://stackoverflow.com/a/32593735/330471 The API definition contained the
 datetime and it was parsed by Python' YAML lib as an object, which caused the
 deepcopy to go nuts.

Making that timestamp a string, however, solves the issue.
---
 .../python-flask-python2/openapi_server/openapi/openapi.yaml    | 2 +-
 .../petstore/python-flask/openapi_server/openapi/openapi.yaml   | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/samples/server/petstore/python-flask-python2/openapi_server/openapi/openapi.yaml b/samples/server/petstore/python-flask-python2/openapi_server/openapi/openapi.yaml
index 122782a9b93..35848eec349 100644
--- a/samples/server/petstore/python-flask-python2/openapi_server/openapi/openapi.yaml
+++ b/samples/server/petstore/python-flask-python2/openapi_server/openapi/openapi.yaml
@@ -602,7 +602,7 @@ components:
         petId: 6
         quantity: 1
         id: 0
-        shipDate: 2000-01-23T04:56:07.000+00:00
+        shipDate: '2000-01-23T04:56:07.000+00:00'
         complete: false
         status: placed
       properties:
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 122782a9b93..35848eec349 100644
--- a/samples/server/petstore/python-flask/openapi_server/openapi/openapi.yaml
+++ b/samples/server/petstore/python-flask/openapi_server/openapi/openapi.yaml
@@ -602,7 +602,7 @@ components:
         petId: 6
         quantity: 1
         id: 0
-        shipDate: 2000-01-23T04:56:07.000+00:00
+        shipDate: '2000-01-23T04:56:07.000+00:00'
         complete: false
         status: placed
       properties:
-- 
GitLab


From 2a348226a3b0b84d3425f1dccffd8da21da8473a Mon Sep 17 00:00:00 2001
From: Artem Shubovych <ashubovych@atlassian.com>
Date: Wed, 8 Jan 2020 18:22:24 +1100
Subject: [PATCH 2/2] Add tests to show that only python2 is affected

---
 .../openapi/broken_openapi.yaml               | 785 ++++++++++++++++++
 .../openapi_server/test/test_spec_parsing.py  |  15 +
 .../openapi/broken_openapi.yaml               | 785 ++++++++++++++++++
 .../openapi_server/openapi/openapi.yaml       |   2 +-
 .../openapi_server/test/test_spec_parsing.py  |  14 +
 5 files changed, 1600 insertions(+), 1 deletion(-)
 create mode 100644 samples/server/petstore/python-flask-python2/openapi_server/openapi/broken_openapi.yaml
 create mode 100644 samples/server/petstore/python-flask-python2/openapi_server/test/test_spec_parsing.py
 create mode 100644 samples/server/petstore/python-flask/openapi_server/openapi/broken_openapi.yaml
 create mode 100644 samples/server/petstore/python-flask/openapi_server/test/test_spec_parsing.py

diff --git a/samples/server/petstore/python-flask-python2/openapi_server/openapi/broken_openapi.yaml b/samples/server/petstore/python-flask-python2/openapi_server/openapi/broken_openapi.yaml
new file mode 100644
index 00000000000..122782a9b93
--- /dev/null
+++ b/samples/server/petstore/python-flask-python2/openapi_server/openapi/broken_openapi.yaml
@@ -0,0 +1,785 @@
+openapi: 3.0.1
+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.
+  license:
+    name: Apache-2.0
+    url: http://www.apache.org/licenses/LICENSE-2.0.html
+  title: OpenAPI Petstore
+  version: 1.0.0
+servers:
+- url: http://petstore.swagger.io/v2
+tags:
+- description: Everything about your Pets
+  name: pet
+- description: Access to Petstore orders
+  name: store
+- description: Operations about user
+  name: user
+paths:
+  /pet:
+    post:
+      operationId: add_pet
+      requestBody:
+        content:
+          application/json:
+            schema:
+              $ref: '#/components/schemas/Pet'
+          application/xml:
+            schema:
+              $ref: '#/components/schemas/Pet'
+        description: Pet object that needs to be added to the store
+        required: true
+      responses:
+        405:
+          content: {}
+          description: Invalid input
+      security:
+      - petstore_auth:
+        - write:pets
+        - read:pets
+      summary: Add a new pet to the store
+      tags:
+      - pet
+      x-codegen-request-body-name: body
+      x-openapi-router-controller: openapi_server.controllers.pet_controller
+    put:
+      operationId: update_pet
+      requestBody:
+        content:
+          application/json:
+            schema:
+              $ref: '#/components/schemas/Pet'
+          application/xml:
+            schema:
+              $ref: '#/components/schemas/Pet'
+        description: Pet object that needs to be added to the store
+        required: true
+      responses:
+        400:
+          content: {}
+          description: Invalid ID supplied
+        404:
+          content: {}
+          description: Pet not found
+        405:
+          content: {}
+          description: Validation exception
+      security:
+      - petstore_auth:
+        - write:pets
+        - read:pets
+      summary: Update an existing pet
+      tags:
+      - pet
+      x-codegen-request-body-name: body
+      x-openapi-router-controller: openapi_server.controllers.pet_controller
+  /pet/findByStatus:
+    get:
+      description: Multiple status values can be provided with comma separated strings
+      operationId: find_pets_by_status
+      parameters:
+      - description: Status values that need to be considered for filter
+        explode: false
+        in: query
+        name: status
+        required: true
+        schema:
+          items:
+            default: available
+            enum:
+            - available
+            - pending
+            - sold
+            type: string
+          type: array
+        style: form
+      responses:
+        200:
+          content:
+            application/xml:
+              schema:
+                items:
+                  $ref: '#/components/schemas/Pet'
+                type: array
+            application/json:
+              schema:
+                items:
+                  $ref: '#/components/schemas/Pet'
+                type: array
+          description: successful operation
+        400:
+          content: {}
+          description: Invalid status value
+      security:
+      - petstore_auth:
+        - write:pets
+        - read:pets
+      summary: Finds Pets by status
+      tags:
+      - pet
+      x-openapi-router-controller: openapi_server.controllers.pet_controller
+  /pet/findByTags:
+    get:
+      deprecated: true
+      description: Multiple tags can be provided with comma separated strings. Use
+        tag1, tag2, tag3 for testing.
+      operationId: find_pets_by_tags
+      parameters:
+      - description: Tags to filter by
+        explode: false
+        in: query
+        name: tags
+        required: true
+        schema:
+          items:
+            type: string
+          type: array
+        style: form
+      responses:
+        200:
+          content:
+            application/xml:
+              schema:
+                items:
+                  $ref: '#/components/schemas/Pet'
+                type: array
+            application/json:
+              schema:
+                items:
+                  $ref: '#/components/schemas/Pet'
+                type: array
+          description: successful operation
+        400:
+          content: {}
+          description: Invalid tag value
+      security:
+      - petstore_auth:
+        - write:pets
+        - read:pets
+      summary: Finds Pets by tags
+      tags:
+      - pet
+      x-openapi-router-controller: openapi_server.controllers.pet_controller
+  /pet/{petId}:
+    delete:
+      operationId: delete_pet
+      parameters:
+      - in: header
+        name: api_key
+        schema:
+          type: string
+      - description: Pet id to delete
+        in: path
+        name: petId
+        required: true
+        schema:
+          format: int64
+          type: integer
+      responses:
+        400:
+          content: {}
+          description: Invalid pet value
+      security:
+      - petstore_auth:
+        - write:pets
+        - read:pets
+      summary: Deletes a pet
+      tags:
+      - pet
+      x-openapi-router-controller: openapi_server.controllers.pet_controller
+    get:
+      description: Returns a single pet
+      operationId: get_pet_by_id
+      parameters:
+      - description: ID of pet to return
+        in: path
+        name: petId
+        required: true
+        schema:
+          format: int64
+          type: integer
+      responses:
+        200:
+          content:
+            application/xml:
+              schema:
+                $ref: '#/components/schemas/Pet'
+            application/json:
+              schema:
+                $ref: '#/components/schemas/Pet'
+          description: successful operation
+        400:
+          content: {}
+          description: Invalid ID supplied
+        404:
+          content: {}
+          description: Pet not found
+      security:
+      - api_key: []
+      summary: Find pet by ID
+      tags:
+      - pet
+      x-openapi-router-controller: openapi_server.controllers.pet_controller
+    post:
+      operationId: update_pet_with_form
+      parameters:
+      - description: ID of pet that needs to be updated
+        in: path
+        name: petId
+        required: true
+        schema:
+          format: int64
+          type: integer
+      requestBody:
+        content:
+          application/x-www-form-urlencoded:
+            schema:
+              properties:
+                name:
+                  description: Updated name of the pet
+                  type: string
+                status:
+                  description: Updated status of the pet
+                  type: string
+      responses:
+        405:
+          content: {}
+          description: Invalid input
+      security:
+      - petstore_auth:
+        - write:pets
+        - read:pets
+      summary: Updates a pet in the store with form data
+      tags:
+      - pet
+      x-openapi-router-controller: openapi_server.controllers.pet_controller
+  /pet/{petId}/uploadImage:
+    post:
+      operationId: upload_file
+      parameters:
+      - description: ID of pet to update
+        in: path
+        name: petId
+        required: true
+        schema:
+          format: int64
+          type: integer
+      requestBody:
+        content:
+          multipart/form-data:
+            schema:
+              properties:
+                additionalMetadata:
+                  description: Additional data to pass to server
+                  type: string
+                file:
+                  description: file to upload
+                  format: binary
+                  type: string
+      responses:
+        200:
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/ApiResponse'
+          description: successful operation
+      security:
+      - petstore_auth:
+        - write:pets
+        - read:pets
+      summary: uploads an image
+      tags:
+      - pet
+      x-openapi-router-controller: openapi_server.controllers.pet_controller
+  /store/inventory:
+    get:
+      description: Returns a map of status codes to quantities
+      operationId: get_inventory
+      responses:
+        200:
+          content:
+            application/json:
+              schema:
+                additionalProperties:
+                  format: int32
+                  type: integer
+                type: object
+          description: successful operation
+      security:
+      - api_key: []
+      summary: Returns pet inventories by status
+      tags:
+      - store
+      x-openapi-router-controller: openapi_server.controllers.store_controller
+  /store/order:
+    post:
+      operationId: place_order
+      requestBody:
+        content:
+          '*/*':
+            schema:
+              $ref: '#/components/schemas/Order'
+        description: order placed for purchasing the pet
+        required: true
+      responses:
+        200:
+          content:
+            application/xml:
+              schema:
+                $ref: '#/components/schemas/Order'
+            application/json:
+              schema:
+                $ref: '#/components/schemas/Order'
+          description: successful operation
+        400:
+          content: {}
+          description: Invalid Order
+      summary: Place an order for a pet
+      tags:
+      - store
+      x-codegen-request-body-name: body
+      x-openapi-router-controller: openapi_server.controllers.store_controller
+  /store/order/{orderId}:
+    delete:
+      description: For valid response try integer IDs with value < 1000. Anything
+        above 1000 or nonintegers will generate API errors
+      operationId: delete_order
+      parameters:
+      - description: ID of the order that needs to be deleted
+        in: path
+        name: orderId
+        required: true
+        schema:
+          type: string
+      responses:
+        400:
+          content: {}
+          description: Invalid ID supplied
+        404:
+          content: {}
+          description: Order not found
+      summary: Delete purchase order by ID
+      tags:
+      - store
+      x-openapi-router-controller: openapi_server.controllers.store_controller
+    get:
+      description: For valid response try integer IDs with value <= 5 or > 10. Other
+        values will generated exceptions
+      operationId: get_order_by_id
+      parameters:
+      - description: ID of pet that needs to be fetched
+        in: path
+        name: orderId
+        required: true
+        schema:
+          format: int64
+          maximum: 5
+          minimum: 1
+          type: integer
+      responses:
+        200:
+          content:
+            application/xml:
+              schema:
+                $ref: '#/components/schemas/Order'
+            application/json:
+              schema:
+                $ref: '#/components/schemas/Order'
+          description: successful operation
+        400:
+          content: {}
+          description: Invalid ID supplied
+        404:
+          content: {}
+          description: Order not found
+      summary: Find purchase order by ID
+      tags:
+      - store
+      x-openapi-router-controller: openapi_server.controllers.store_controller
+  /user:
+    post:
+      description: This can only be done by the logged in user.
+      operationId: create_user
+      requestBody:
+        content:
+          '*/*':
+            schema:
+              $ref: '#/components/schemas/User'
+        description: Created user object
+        required: true
+      responses:
+        default:
+          content: {}
+          description: successful operation
+      summary: Create user
+      tags:
+      - user
+      x-codegen-request-body-name: body
+      x-openapi-router-controller: openapi_server.controllers.user_controller
+  /user/createWithArray:
+    post:
+      operationId: create_users_with_array_input
+      requestBody:
+        content:
+          '*/*':
+            schema:
+              items:
+                $ref: '#/components/schemas/User'
+              type: array
+        description: List of user object
+        required: true
+      responses:
+        default:
+          content: {}
+          description: successful operation
+      summary: Creates list of users with given input array
+      tags:
+      - user
+      x-codegen-request-body-name: body
+      x-openapi-router-controller: openapi_server.controllers.user_controller
+  /user/createWithList:
+    post:
+      operationId: create_users_with_list_input
+      requestBody:
+        content:
+          '*/*':
+            schema:
+              items:
+                $ref: '#/components/schemas/User'
+              type: array
+        description: List of user object
+        required: true
+      responses:
+        default:
+          content: {}
+          description: successful operation
+      summary: Creates list of users with given input array
+      tags:
+      - user
+      x-codegen-request-body-name: body
+      x-openapi-router-controller: openapi_server.controllers.user_controller
+  /user/login:
+    get:
+      operationId: login_user
+      parameters:
+      - description: The user name for login
+        in: query
+        name: username
+        required: true
+        schema:
+          type: string
+      - description: The password for login in clear text
+        in: query
+        name: password
+        required: true
+        schema:
+          type: string
+      responses:
+        200:
+          content:
+            application/xml:
+              schema:
+                type: string
+            application/json:
+              schema:
+                type: string
+          description: successful operation
+          headers:
+            X-Rate-Limit:
+              description: calls per hour allowed by the user
+              schema:
+                format: int32
+                type: integer
+            X-Expires-After:
+              description: date in UTC when toekn expires
+              schema:
+                format: date-time
+                type: string
+        400:
+          content: {}
+          description: Invalid username/password supplied
+      summary: Logs user into the system
+      tags:
+      - user
+      x-openapi-router-controller: openapi_server.controllers.user_controller
+  /user/logout:
+    get:
+      operationId: logout_user
+      responses:
+        default:
+          content: {}
+          description: successful operation
+      summary: Logs out current logged in user session
+      tags:
+      - user
+      x-openapi-router-controller: openapi_server.controllers.user_controller
+  /user/{username}:
+    delete:
+      description: This can only be done by the logged in user.
+      operationId: delete_user
+      parameters:
+      - description: The name that needs to be deleted
+        in: path
+        name: username
+        required: true
+        schema:
+          type: string
+      responses:
+        400:
+          content: {}
+          description: Invalid username supplied
+        404:
+          content: {}
+          description: User not found
+      summary: Delete user
+      tags:
+      - user
+      x-openapi-router-controller: openapi_server.controllers.user_controller
+    get:
+      operationId: get_user_by_name
+      parameters:
+      - description: The name that needs to be fetched. Use user1 for testing.
+        in: path
+        name: username
+        required: true
+        schema:
+          type: string
+      responses:
+        200:
+          content:
+            application/xml:
+              schema:
+                $ref: '#/components/schemas/User'
+            application/json:
+              schema:
+                $ref: '#/components/schemas/User'
+          description: successful operation
+        400:
+          content: {}
+          description: Invalid username supplied
+        404:
+          content: {}
+          description: User not found
+      summary: Get user by user name
+      tags:
+      - user
+      x-openapi-router-controller: openapi_server.controllers.user_controller
+    put:
+      description: This can only be done by the logged in user.
+      operationId: update_user
+      parameters:
+      - description: name that need to be deleted
+        in: path
+        name: username
+        required: true
+        schema:
+          type: string
+      requestBody:
+        content:
+          '*/*':
+            schema:
+              $ref: '#/components/schemas/User'
+        description: Updated user object
+        required: true
+      responses:
+        400:
+          content: {}
+          description: Invalid user supplied
+        404:
+          content: {}
+          description: User not found
+      summary: Updated user
+      tags:
+      - user
+      x-codegen-request-body-name: body
+      x-openapi-router-controller: openapi_server.controllers.user_controller
+components:
+  schemas:
+    Order:
+      description: An order for a pets from the pet store
+      example:
+        petId: 6
+        quantity: 1
+        id: 0
+        shipDate: 2000-01-23T04:56:07.000+00:00
+        complete: false
+        status: placed
+      properties:
+        id:
+          format: int64
+          type: integer
+        petId:
+          format: int64
+          type: integer
+        quantity:
+          format: int32
+          type: integer
+        shipDate:
+          format: date-time
+          type: string
+        status:
+          description: Order Status
+          enum:
+          - placed
+          - approved
+          - delivered
+          type: string
+        complete:
+          default: false
+          type: boolean
+      title: Pet Order
+      type: object
+      xml:
+        name: Order
+    Category:
+      description: A category for a pet
+      example:
+        name: name
+        id: 6
+      properties:
+        id:
+          format: int64
+          type: integer
+        name:
+          type: string
+      title: Pet category
+      type: object
+      xml:
+        name: Category
+    User:
+      description: A User who is purchasing from the pet store
+      example:
+        firstName: firstName
+        lastName: lastName
+        password: password
+        userStatus: 6
+        phone: phone
+        id: 0
+        email: email
+        username: username
+      properties:
+        id:
+          format: int64
+          type: integer
+        username:
+          type: string
+        firstName:
+          type: string
+        lastName:
+          type: string
+        email:
+          type: string
+        password:
+          type: string
+        phone:
+          type: string
+        userStatus:
+          description: User Status
+          format: int32
+          type: integer
+      title: a User
+      type: object
+      xml:
+        name: User
+    Tag:
+      description: A tag for a pet
+      example:
+        name: name
+        id: 1
+      properties:
+        id:
+          format: int64
+          type: integer
+        name:
+          type: string
+      title: Pet Tag
+      type: object
+      xml:
+        name: Tag
+    Pet:
+      description: A pet for sale in the pet store
+      example:
+        photoUrls:
+        - photoUrls
+        - photoUrls
+        name: doggie
+        id: 0
+        category:
+          name: name
+          id: 6
+        tags:
+        - name: name
+          id: 1
+        - name: name
+          id: 1
+        status: available
+      properties:
+        id:
+          format: int64
+          type: integer
+        category:
+          $ref: '#/components/schemas/Category'
+        name:
+          example: doggie
+          type: string
+        photoUrls:
+          items:
+            type: string
+          type: array
+          xml:
+            name: photoUrl
+            wrapped: true
+        tags:
+          items:
+            $ref: '#/components/schemas/Tag'
+          type: array
+          xml:
+            name: tag
+            wrapped: true
+        status:
+          description: pet status in the store
+          enum:
+          - available
+          - pending
+          - sold
+          type: string
+      required:
+      - name
+      - photoUrls
+      title: a Pet
+      type: object
+      xml:
+        name: Pet
+    ApiResponse:
+      description: Describes the result of uploading an image resource
+      example:
+        code: 0
+        type: type
+        message: message
+      properties:
+        code:
+          format: int32
+          type: integer
+        type:
+          type: string
+        message:
+          type: string
+      title: An uploaded response
+      type: object
+  securitySchemes:
+    petstore_auth:
+      flows:
+        implicit:
+          authorizationUrl: http://petstore.swagger.io/api/oauth/dialog
+          scopes:
+            write:pets: modify pets in your account
+            read:pets: read your pets
+      type: oauth2
+      x-tokenInfoFunc: openapi_server.controllers.security_controller_.info_from_petstore_auth
+      x-scopeValidateFunc: openapi_server.controllers.security_controller_.validate_scope_petstore_auth
+    api_key:
+      in: header
+      name: api_key
+      type: apiKey
+      x-apikeyInfoFunc: openapi_server.controllers.security_controller_.info_from_api_key
diff --git a/samples/server/petstore/python-flask-python2/openapi_server/test/test_spec_parsing.py b/samples/server/petstore/python-flask-python2/openapi_server/test/test_spec_parsing.py
new file mode 100644
index 00000000000..b63d86e2e38
--- /dev/null
+++ b/samples/server/petstore/python-flask-python2/openapi_server/test/test_spec_parsing.py
@@ -0,0 +1,15 @@
+# coding: utf-8
+
+import connexion
+import logging
+from openapi_server.encoder import JSONEncoder
+from unittest import TestCase
+
+class TestSpecParsing(TestCase):
+    def test(self):
+        with self.assertRaises(TypeError):
+            logging.getLogger('connexion.operation').setLevel('ERROR')
+            app = connexion.App(__name__, specification_dir='../openapi/')
+            app.app.json_encoder = JSONEncoder
+            app.add_api('broken_openapi.yaml', pythonic_params=True)
+            self.assertTrue(app.app is not None)
diff --git a/samples/server/petstore/python-flask/openapi_server/openapi/broken_openapi.yaml b/samples/server/petstore/python-flask/openapi_server/openapi/broken_openapi.yaml
new file mode 100644
index 00000000000..122782a9b93
--- /dev/null
+++ b/samples/server/petstore/python-flask/openapi_server/openapi/broken_openapi.yaml
@@ -0,0 +1,785 @@
+openapi: 3.0.1
+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.
+  license:
+    name: Apache-2.0
+    url: http://www.apache.org/licenses/LICENSE-2.0.html
+  title: OpenAPI Petstore
+  version: 1.0.0
+servers:
+- url: http://petstore.swagger.io/v2
+tags:
+- description: Everything about your Pets
+  name: pet
+- description: Access to Petstore orders
+  name: store
+- description: Operations about user
+  name: user
+paths:
+  /pet:
+    post:
+      operationId: add_pet
+      requestBody:
+        content:
+          application/json:
+            schema:
+              $ref: '#/components/schemas/Pet'
+          application/xml:
+            schema:
+              $ref: '#/components/schemas/Pet'
+        description: Pet object that needs to be added to the store
+        required: true
+      responses:
+        405:
+          content: {}
+          description: Invalid input
+      security:
+      - petstore_auth:
+        - write:pets
+        - read:pets
+      summary: Add a new pet to the store
+      tags:
+      - pet
+      x-codegen-request-body-name: body
+      x-openapi-router-controller: openapi_server.controllers.pet_controller
+    put:
+      operationId: update_pet
+      requestBody:
+        content:
+          application/json:
+            schema:
+              $ref: '#/components/schemas/Pet'
+          application/xml:
+            schema:
+              $ref: '#/components/schemas/Pet'
+        description: Pet object that needs to be added to the store
+        required: true
+      responses:
+        400:
+          content: {}
+          description: Invalid ID supplied
+        404:
+          content: {}
+          description: Pet not found
+        405:
+          content: {}
+          description: Validation exception
+      security:
+      - petstore_auth:
+        - write:pets
+        - read:pets
+      summary: Update an existing pet
+      tags:
+      - pet
+      x-codegen-request-body-name: body
+      x-openapi-router-controller: openapi_server.controllers.pet_controller
+  /pet/findByStatus:
+    get:
+      description: Multiple status values can be provided with comma separated strings
+      operationId: find_pets_by_status
+      parameters:
+      - description: Status values that need to be considered for filter
+        explode: false
+        in: query
+        name: status
+        required: true
+        schema:
+          items:
+            default: available
+            enum:
+            - available
+            - pending
+            - sold
+            type: string
+          type: array
+        style: form
+      responses:
+        200:
+          content:
+            application/xml:
+              schema:
+                items:
+                  $ref: '#/components/schemas/Pet'
+                type: array
+            application/json:
+              schema:
+                items:
+                  $ref: '#/components/schemas/Pet'
+                type: array
+          description: successful operation
+        400:
+          content: {}
+          description: Invalid status value
+      security:
+      - petstore_auth:
+        - write:pets
+        - read:pets
+      summary: Finds Pets by status
+      tags:
+      - pet
+      x-openapi-router-controller: openapi_server.controllers.pet_controller
+  /pet/findByTags:
+    get:
+      deprecated: true
+      description: Multiple tags can be provided with comma separated strings. Use
+        tag1, tag2, tag3 for testing.
+      operationId: find_pets_by_tags
+      parameters:
+      - description: Tags to filter by
+        explode: false
+        in: query
+        name: tags
+        required: true
+        schema:
+          items:
+            type: string
+          type: array
+        style: form
+      responses:
+        200:
+          content:
+            application/xml:
+              schema:
+                items:
+                  $ref: '#/components/schemas/Pet'
+                type: array
+            application/json:
+              schema:
+                items:
+                  $ref: '#/components/schemas/Pet'
+                type: array
+          description: successful operation
+        400:
+          content: {}
+          description: Invalid tag value
+      security:
+      - petstore_auth:
+        - write:pets
+        - read:pets
+      summary: Finds Pets by tags
+      tags:
+      - pet
+      x-openapi-router-controller: openapi_server.controllers.pet_controller
+  /pet/{petId}:
+    delete:
+      operationId: delete_pet
+      parameters:
+      - in: header
+        name: api_key
+        schema:
+          type: string
+      - description: Pet id to delete
+        in: path
+        name: petId
+        required: true
+        schema:
+          format: int64
+          type: integer
+      responses:
+        400:
+          content: {}
+          description: Invalid pet value
+      security:
+      - petstore_auth:
+        - write:pets
+        - read:pets
+      summary: Deletes a pet
+      tags:
+      - pet
+      x-openapi-router-controller: openapi_server.controllers.pet_controller
+    get:
+      description: Returns a single pet
+      operationId: get_pet_by_id
+      parameters:
+      - description: ID of pet to return
+        in: path
+        name: petId
+        required: true
+        schema:
+          format: int64
+          type: integer
+      responses:
+        200:
+          content:
+            application/xml:
+              schema:
+                $ref: '#/components/schemas/Pet'
+            application/json:
+              schema:
+                $ref: '#/components/schemas/Pet'
+          description: successful operation
+        400:
+          content: {}
+          description: Invalid ID supplied
+        404:
+          content: {}
+          description: Pet not found
+      security:
+      - api_key: []
+      summary: Find pet by ID
+      tags:
+      - pet
+      x-openapi-router-controller: openapi_server.controllers.pet_controller
+    post:
+      operationId: update_pet_with_form
+      parameters:
+      - description: ID of pet that needs to be updated
+        in: path
+        name: petId
+        required: true
+        schema:
+          format: int64
+          type: integer
+      requestBody:
+        content:
+          application/x-www-form-urlencoded:
+            schema:
+              properties:
+                name:
+                  description: Updated name of the pet
+                  type: string
+                status:
+                  description: Updated status of the pet
+                  type: string
+      responses:
+        405:
+          content: {}
+          description: Invalid input
+      security:
+      - petstore_auth:
+        - write:pets
+        - read:pets
+      summary: Updates a pet in the store with form data
+      tags:
+      - pet
+      x-openapi-router-controller: openapi_server.controllers.pet_controller
+  /pet/{petId}/uploadImage:
+    post:
+      operationId: upload_file
+      parameters:
+      - description: ID of pet to update
+        in: path
+        name: petId
+        required: true
+        schema:
+          format: int64
+          type: integer
+      requestBody:
+        content:
+          multipart/form-data:
+            schema:
+              properties:
+                additionalMetadata:
+                  description: Additional data to pass to server
+                  type: string
+                file:
+                  description: file to upload
+                  format: binary
+                  type: string
+      responses:
+        200:
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/ApiResponse'
+          description: successful operation
+      security:
+      - petstore_auth:
+        - write:pets
+        - read:pets
+      summary: uploads an image
+      tags:
+      - pet
+      x-openapi-router-controller: openapi_server.controllers.pet_controller
+  /store/inventory:
+    get:
+      description: Returns a map of status codes to quantities
+      operationId: get_inventory
+      responses:
+        200:
+          content:
+            application/json:
+              schema:
+                additionalProperties:
+                  format: int32
+                  type: integer
+                type: object
+          description: successful operation
+      security:
+      - api_key: []
+      summary: Returns pet inventories by status
+      tags:
+      - store
+      x-openapi-router-controller: openapi_server.controllers.store_controller
+  /store/order:
+    post:
+      operationId: place_order
+      requestBody:
+        content:
+          '*/*':
+            schema:
+              $ref: '#/components/schemas/Order'
+        description: order placed for purchasing the pet
+        required: true
+      responses:
+        200:
+          content:
+            application/xml:
+              schema:
+                $ref: '#/components/schemas/Order'
+            application/json:
+              schema:
+                $ref: '#/components/schemas/Order'
+          description: successful operation
+        400:
+          content: {}
+          description: Invalid Order
+      summary: Place an order for a pet
+      tags:
+      - store
+      x-codegen-request-body-name: body
+      x-openapi-router-controller: openapi_server.controllers.store_controller
+  /store/order/{orderId}:
+    delete:
+      description: For valid response try integer IDs with value < 1000. Anything
+        above 1000 or nonintegers will generate API errors
+      operationId: delete_order
+      parameters:
+      - description: ID of the order that needs to be deleted
+        in: path
+        name: orderId
+        required: true
+        schema:
+          type: string
+      responses:
+        400:
+          content: {}
+          description: Invalid ID supplied
+        404:
+          content: {}
+          description: Order not found
+      summary: Delete purchase order by ID
+      tags:
+      - store
+      x-openapi-router-controller: openapi_server.controllers.store_controller
+    get:
+      description: For valid response try integer IDs with value <= 5 or > 10. Other
+        values will generated exceptions
+      operationId: get_order_by_id
+      parameters:
+      - description: ID of pet that needs to be fetched
+        in: path
+        name: orderId
+        required: true
+        schema:
+          format: int64
+          maximum: 5
+          minimum: 1
+          type: integer
+      responses:
+        200:
+          content:
+            application/xml:
+              schema:
+                $ref: '#/components/schemas/Order'
+            application/json:
+              schema:
+                $ref: '#/components/schemas/Order'
+          description: successful operation
+        400:
+          content: {}
+          description: Invalid ID supplied
+        404:
+          content: {}
+          description: Order not found
+      summary: Find purchase order by ID
+      tags:
+      - store
+      x-openapi-router-controller: openapi_server.controllers.store_controller
+  /user:
+    post:
+      description: This can only be done by the logged in user.
+      operationId: create_user
+      requestBody:
+        content:
+          '*/*':
+            schema:
+              $ref: '#/components/schemas/User'
+        description: Created user object
+        required: true
+      responses:
+        default:
+          content: {}
+          description: successful operation
+      summary: Create user
+      tags:
+      - user
+      x-codegen-request-body-name: body
+      x-openapi-router-controller: openapi_server.controllers.user_controller
+  /user/createWithArray:
+    post:
+      operationId: create_users_with_array_input
+      requestBody:
+        content:
+          '*/*':
+            schema:
+              items:
+                $ref: '#/components/schemas/User'
+              type: array
+        description: List of user object
+        required: true
+      responses:
+        default:
+          content: {}
+          description: successful operation
+      summary: Creates list of users with given input array
+      tags:
+      - user
+      x-codegen-request-body-name: body
+      x-openapi-router-controller: openapi_server.controllers.user_controller
+  /user/createWithList:
+    post:
+      operationId: create_users_with_list_input
+      requestBody:
+        content:
+          '*/*':
+            schema:
+              items:
+                $ref: '#/components/schemas/User'
+              type: array
+        description: List of user object
+        required: true
+      responses:
+        default:
+          content: {}
+          description: successful operation
+      summary: Creates list of users with given input array
+      tags:
+      - user
+      x-codegen-request-body-name: body
+      x-openapi-router-controller: openapi_server.controllers.user_controller
+  /user/login:
+    get:
+      operationId: login_user
+      parameters:
+      - description: The user name for login
+        in: query
+        name: username
+        required: true
+        schema:
+          type: string
+      - description: The password for login in clear text
+        in: query
+        name: password
+        required: true
+        schema:
+          type: string
+      responses:
+        200:
+          content:
+            application/xml:
+              schema:
+                type: string
+            application/json:
+              schema:
+                type: string
+          description: successful operation
+          headers:
+            X-Rate-Limit:
+              description: calls per hour allowed by the user
+              schema:
+                format: int32
+                type: integer
+            X-Expires-After:
+              description: date in UTC when toekn expires
+              schema:
+                format: date-time
+                type: string
+        400:
+          content: {}
+          description: Invalid username/password supplied
+      summary: Logs user into the system
+      tags:
+      - user
+      x-openapi-router-controller: openapi_server.controllers.user_controller
+  /user/logout:
+    get:
+      operationId: logout_user
+      responses:
+        default:
+          content: {}
+          description: successful operation
+      summary: Logs out current logged in user session
+      tags:
+      - user
+      x-openapi-router-controller: openapi_server.controllers.user_controller
+  /user/{username}:
+    delete:
+      description: This can only be done by the logged in user.
+      operationId: delete_user
+      parameters:
+      - description: The name that needs to be deleted
+        in: path
+        name: username
+        required: true
+        schema:
+          type: string
+      responses:
+        400:
+          content: {}
+          description: Invalid username supplied
+        404:
+          content: {}
+          description: User not found
+      summary: Delete user
+      tags:
+      - user
+      x-openapi-router-controller: openapi_server.controllers.user_controller
+    get:
+      operationId: get_user_by_name
+      parameters:
+      - description: The name that needs to be fetched. Use user1 for testing.
+        in: path
+        name: username
+        required: true
+        schema:
+          type: string
+      responses:
+        200:
+          content:
+            application/xml:
+              schema:
+                $ref: '#/components/schemas/User'
+            application/json:
+              schema:
+                $ref: '#/components/schemas/User'
+          description: successful operation
+        400:
+          content: {}
+          description: Invalid username supplied
+        404:
+          content: {}
+          description: User not found
+      summary: Get user by user name
+      tags:
+      - user
+      x-openapi-router-controller: openapi_server.controllers.user_controller
+    put:
+      description: This can only be done by the logged in user.
+      operationId: update_user
+      parameters:
+      - description: name that need to be deleted
+        in: path
+        name: username
+        required: true
+        schema:
+          type: string
+      requestBody:
+        content:
+          '*/*':
+            schema:
+              $ref: '#/components/schemas/User'
+        description: Updated user object
+        required: true
+      responses:
+        400:
+          content: {}
+          description: Invalid user supplied
+        404:
+          content: {}
+          description: User not found
+      summary: Updated user
+      tags:
+      - user
+      x-codegen-request-body-name: body
+      x-openapi-router-controller: openapi_server.controllers.user_controller
+components:
+  schemas:
+    Order:
+      description: An order for a pets from the pet store
+      example:
+        petId: 6
+        quantity: 1
+        id: 0
+        shipDate: 2000-01-23T04:56:07.000+00:00
+        complete: false
+        status: placed
+      properties:
+        id:
+          format: int64
+          type: integer
+        petId:
+          format: int64
+          type: integer
+        quantity:
+          format: int32
+          type: integer
+        shipDate:
+          format: date-time
+          type: string
+        status:
+          description: Order Status
+          enum:
+          - placed
+          - approved
+          - delivered
+          type: string
+        complete:
+          default: false
+          type: boolean
+      title: Pet Order
+      type: object
+      xml:
+        name: Order
+    Category:
+      description: A category for a pet
+      example:
+        name: name
+        id: 6
+      properties:
+        id:
+          format: int64
+          type: integer
+        name:
+          type: string
+      title: Pet category
+      type: object
+      xml:
+        name: Category
+    User:
+      description: A User who is purchasing from the pet store
+      example:
+        firstName: firstName
+        lastName: lastName
+        password: password
+        userStatus: 6
+        phone: phone
+        id: 0
+        email: email
+        username: username
+      properties:
+        id:
+          format: int64
+          type: integer
+        username:
+          type: string
+        firstName:
+          type: string
+        lastName:
+          type: string
+        email:
+          type: string
+        password:
+          type: string
+        phone:
+          type: string
+        userStatus:
+          description: User Status
+          format: int32
+          type: integer
+      title: a User
+      type: object
+      xml:
+        name: User
+    Tag:
+      description: A tag for a pet
+      example:
+        name: name
+        id: 1
+      properties:
+        id:
+          format: int64
+          type: integer
+        name:
+          type: string
+      title: Pet Tag
+      type: object
+      xml:
+        name: Tag
+    Pet:
+      description: A pet for sale in the pet store
+      example:
+        photoUrls:
+        - photoUrls
+        - photoUrls
+        name: doggie
+        id: 0
+        category:
+          name: name
+          id: 6
+        tags:
+        - name: name
+          id: 1
+        - name: name
+          id: 1
+        status: available
+      properties:
+        id:
+          format: int64
+          type: integer
+        category:
+          $ref: '#/components/schemas/Category'
+        name:
+          example: doggie
+          type: string
+        photoUrls:
+          items:
+            type: string
+          type: array
+          xml:
+            name: photoUrl
+            wrapped: true
+        tags:
+          items:
+            $ref: '#/components/schemas/Tag'
+          type: array
+          xml:
+            name: tag
+            wrapped: true
+        status:
+          description: pet status in the store
+          enum:
+          - available
+          - pending
+          - sold
+          type: string
+      required:
+      - name
+      - photoUrls
+      title: a Pet
+      type: object
+      xml:
+        name: Pet
+    ApiResponse:
+      description: Describes the result of uploading an image resource
+      example:
+        code: 0
+        type: type
+        message: message
+      properties:
+        code:
+          format: int32
+          type: integer
+        type:
+          type: string
+        message:
+          type: string
+      title: An uploaded response
+      type: object
+  securitySchemes:
+    petstore_auth:
+      flows:
+        implicit:
+          authorizationUrl: http://petstore.swagger.io/api/oauth/dialog
+          scopes:
+            write:pets: modify pets in your account
+            read:pets: read your pets
+      type: oauth2
+      x-tokenInfoFunc: openapi_server.controllers.security_controller_.info_from_petstore_auth
+      x-scopeValidateFunc: openapi_server.controllers.security_controller_.validate_scope_petstore_auth
+    api_key:
+      in: header
+      name: api_key
+      type: apiKey
+      x-apikeyInfoFunc: openapi_server.controllers.security_controller_.info_from_api_key
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 35848eec349..122782a9b93 100644
--- a/samples/server/petstore/python-flask/openapi_server/openapi/openapi.yaml
+++ b/samples/server/petstore/python-flask/openapi_server/openapi/openapi.yaml
@@ -602,7 +602,7 @@ components:
         petId: 6
         quantity: 1
         id: 0
-        shipDate: '2000-01-23T04:56:07.000+00:00'
+        shipDate: 2000-01-23T04:56:07.000+00:00
         complete: false
         status: placed
       properties:
diff --git a/samples/server/petstore/python-flask/openapi_server/test/test_spec_parsing.py b/samples/server/petstore/python-flask/openapi_server/test/test_spec_parsing.py
new file mode 100644
index 00000000000..501bf306587
--- /dev/null
+++ b/samples/server/petstore/python-flask/openapi_server/test/test_spec_parsing.py
@@ -0,0 +1,14 @@
+# coding: utf-8
+
+import connexion
+import logging
+from openapi_server.encoder import JSONEncoder
+from unittest import TestCase
+
+class TestSpecParsing(TestCase):
+    def test(self):
+        logging.getLogger('connexion.operation').setLevel('ERROR')
+        app = connexion.App(__name__, specification_dir='../openapi/')
+        app.app.json_encoder = JSONEncoder
+        app.add_api('broken_openapi.yaml', pythonic_params=True)
+        self.assertTrue(app.app is not None)
\ No newline at end of file
-- 
GitLab