Coder Social home page Coder Social logo

Comments (14)

luolingchun avatar luolingchun commented on June 2, 2024 1

I got it.

This issue as same as the #128 that will be fix by #129.

from flask-openapi3.

luolingchun avatar luolingchun commented on June 2, 2024

I can't reproduce your problem, please paste your code.

from flask-openapi3.

fluffybrain3 avatar fluffybrain3 commented on June 2, 2024

This worked in the previous version (doesn't work in this one)

class UploadFileForm(BaseModel):
    file: Optional[FileStorage]
    # other fields

It was changed by the bump-pydantic to

class UploadFileForm(BaseModel):
    file: Optional[FileStorage] = None
    # other fields

and still doesn't work.

Standard case when the field is required works fine for me:

class UploadFileForm(BaseModel):
    file: FileStorage
    # other fields

So I am not able to declare a Form field which is not required and is None by default (Field definition 4) according to the Pydantic docs here
https://docs.pydantic.dev/latest/migration/#required-optional-and-nullable-fields
because then there will be no field types in swagger.

from flask-openapi3.

luolingchun avatar luolingchun commented on June 2, 2024

f7 can solve your problem.

image

from flask-openapi3.

fluffybrain3 avatar fluffybrain3 commented on June 2, 2024

I don't understand how f7 solves the problem.
I will try to explain in a different way.
It is not possible to declare a Form field which at the same time:

  1. Is not required
  2. Has correct type shown in swagger.

When you use f7 you only achieve the 1st point and the field in swagger is just a text input for the FileStorage, boolean, etc.

from flask-openapi3.

luolingchun avatar luolingchun commented on June 2, 2024

You misunderstood, use file: FileStorage = None, not file: Any= None.

from flask-openapi3.

fluffybrain3 avatar fluffybrain3 commented on June 2, 2024

Okay, so it seems like file: FileStorage = None is the only type that works the way you describe, but others don't.
It doesn't even look like a correct field definition based on these Pydantic docs.

class RequestForm(BaseModel):
    file: FileStorage = None
    some_text: str = None
    some_bool: bool = None

image
image

I mean the issue is just that the Field Definition 4 (and 5) in Form is not properly parsed/translated by the flask-openapi3 and because of that it doesn't show a correct input type in swagger.
I see that the same problem happens with Query and Path models.

from flask-openapi3.

fluffybrain3 avatar fluffybrain3 commented on June 2, 2024

@luolingchun I updated to v3.0.1 and this problems still exists.

from flask-openapi3.

luolingchun avatar luolingchun commented on June 2, 2024

@fluffybrain3 It's worked for me!

from pydantic import BaseModel

from flask_openapi3 import OpenAPI, FileStorage

app = OpenAPI(__name__)


class RequestForm(BaseModel):
    file: FileStorage = None
    some_text: str = None
    some_bool: bool = None


@app.post('/upload/file')
def upload_file(form: RequestForm):
    print(form)

    return {"code": 0, "message": "ok"}


if __name__ == '__main__':
    app.run(debug=True)

image

from flask-openapi3.

fluffybrain3 avatar fluffybrain3 commented on June 2, 2024

Okay, now it's possible to declare a not required field in a Form this way.
But if you add the Optional type hint, it doesn't work.
According to the Pydantic docs, not required fields should be declared with the Optional.
Without the Optional you cannot tick the "Send empty value" for e.g. int, bool types, because it will throw an error "Input should be a valid boolean, unable to interpret input" which doesn't happen after adding Optional.

class RequestForm(BaseModel):
    file: Optional[FileStorage] = None
    some_text: Optional[str] = None
    some_bool: Optional[bool] = None

image

from flask-openapi3.

luolingchun avatar luolingchun commented on June 2, 2024
class RequestForm(BaseModel):
    file: FileStorage = None
    some_text: str = None
    some_bool: Optional[bool] = None

Adding Optional will add an additional type "type": "null".

I don't think Swagger UI is ready for this yet. Or rather, there is no need for multi type support.

Therefore, the best solution currently is not to use Optional and not to send empty value.

"RequestForm": {
    "properties": {
        "file": {
            "format": "binary",
            "title": "File",
            "type": "string"
        },
        "some_bool": {
            "anyOf": [
                {
                    "type": "boolean"
                },
+               {
+                   "type": "null"
+               }
            ],
            "title": "Some Bool"
        },
        "some_text": {
            "title": "Some Text",
            "type": "string"
        }
    },
    "title": "RequestForm",
    "type": "object"
}

from flask-openapi3.

fluffybrain3 avatar fluffybrain3 commented on June 2, 2024

In flask-openapi3 v2.5.4

some_bool: Optional[bool]
some_bool: Optional[bool] = None

were parsed like this

"some_bool": {
    "title": "Some Bool",
    "type": "boolean"
}

Version 3.0.0 changed it to

"some_bool": {
    "anyOf": [
        {
            "type": "boolean"
        },
        {
            "type": "null"
        }
    ],
    "title": "Some Bool"
}

So, was that change intentional?
I would say that the previous version was more practical.

from flask-openapi3.

fluffybrain3 avatar fluffybrain3 commented on June 2, 2024

I discovered another problem with Optional in v3 that didn't occur in v2.

from typing import Optional
from uuid import UUID

from flask_openapi3 import OpenAPI
from pydantic import BaseModel

app = OpenAPI(__name__)


class RequestQuery(BaseModel):
    entity_ids: Optional[list[UUID]] = None


@app.post('/entities')
def upload_file(query: RequestQuery):
    print(query)

    return {"code": 0, "message": "ok"}


if __name__ == '__main__':
    app.run(debug=True)

image
After changing POST to GET it looks like this
image
There is definitely something wrong with Optional in v3.

from flask-openapi3.

luolingchun avatar luolingchun commented on June 2, 2024

Pydantic v2 and OpenAPI 3.1 both follow JSON schema specification draft 2020-12.

https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#data-types

https://datatracker.ietf.org/doc/html/draft-bhutton-json-schema-00#section-4.2.1

Here is an issue in Pydantic v2: pydantic/pydantic#5394 (comment)

Overall, {"type": "null"} is a newly supported type.

Option[bool] and Union[None, bool] are the same, generating the same JSON schema.

"anyOf": [
        {
            "type": "boolean"
        },
        {
            "type": "null"
        }
    ]

How about Union[None, bool, str, int, ...]? That will be generating more types, Swagger UI cannot handle it.

In summary, this is the reason for the problem.

Therefore, we need to avoid using multiple types in the form (application/form) but can use them in the body (application/json).

from flask-openapi3.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.