podhmo / swagger-marshmallow-codegen

generating marshmallow's schema from swagger definition file
MIT License
52 stars 10 forks source link

Does not support minItems on array (generate ItemsRange validator instead of Length) #97

Closed eLvErDe closed 3 years ago

eLvErDe commented 3 years ago

Hello podhmo,

First I would like to thank you for upgrading your library to support OpenAPI 3.0.0, it's working very nicely and seems to work quite nicely.

However I need to report a minor issue: minItems property on array is handled like minimum on number which is incorrect and render the generated marshmallow model unusable.

The following standalone script reproduces the issue.

"""
Generated Marshmallow models crash with TypeError: '<' not supported between instances of 'list' and 'int'
When OpenAPI uses minItems on an array definition
"""

import tempfile
import subprocess

OPENAPI_SPEC = """
openapi: 3.0.0
components:
  schemas:
    ExampleArray:
      description: Example array requiring at least one element
      type: array
      items:
        type: string
      minItems: 1
    ExampleSchema:
      type: object
      properties:
        array:
          $ref: "#/components/schemas/ExampleArray"
      required:
        - array
      additionalProperties: false
"""

def main() -> None:
    """
    Generate Marshmallow models from OpenAPI spec and attempt to use it
    """

    with tempfile.NamedTemporaryFile("w", encoding="utf-8") as temp_fh:
        temp_fh.write(OPENAPI_SPEC.strip())
        temp_fh.seek(0)
        output = subprocess.check_output(["swagger-marshmallow-codegen", temp_fh.name])

    output_str = str(output, "utf-8")

    print()
    print("Generated marshmallow model:")
    print()
    print(output_str)
    print()
    print("Please note validate=[ItemsRange(min=1 is probably incorrect")
    print("It should be using Length validator:")
    print("https://marshmallow.readthedocs.io/en/stable/marshmallow.validate.html?highlight=length#marshmallow.validate.Length")
    print()

    with open("generated_marshmallow_models.py", "w", encoding="utf-8") as path_fh:
        path_fh.write(output_str)

    print("Using the generated model with proper payload is now going to crash")
    print("with TypeError: '<' not supported between instances of 'list' and 'int'")
    print()
    print('Payload is {"array": ["string1", "string2"]}')
    print()

    from generated_marshmallow_models import ExampleSchema

    schema = ExampleSchema()
    schema.load({"array": ["string1", "string2"]})

if __name__ == "__main__":

    main()

Thanks in advance for your help,

Best regards, Adam.

PS: Add a Paypal link somewhere or send it to me, I would like to make a small donation

podhmo commented 3 years ago

Oh, ok I'l fix it.

podhmo commented 3 years ago

PS: Add a Paypal link somewhere or send it to me, I would like to make a small donation

Wow, if you want to pay for my code, that's grateful. But this is hobby work, so, instead, I suggest donating to PSF.

podhmo commented 3 years ago

fixed, and 0.6.4 is released