Repository: luolingchun/flask-openapi3 (language: python)

Issue:
Error when using 'gt' or 'lt' constraints in Pydantic Field()
Environment:

- Python version: 3.12
- Operating system: Linux
- Flask version: 3.0.3
- flask-openapi3 version: 3.1.0

***

In `Schema` class `exclusiveMinimum` and `exclusiveMaximum` fields should be of type `float` instead of `bool`.
If you try to use the Pydantic `Field()` with the 'gt' or 'lt' constraint, the app crashes.
I fixed it in #149

```python
from flask_openapi3 import Info, Tag, OpenAPI
from pydantic import BaseModel, Field

info = Info(title="book API", version="1.0.0")
app = OpenAPI(__name__, info=info)
book_tag = Tag(name="book", description="Some Book")


class BookForm(BaseModel):
    year: int = Field(..., gt=2000, lt=2030)


@app.post("/book", summary="get books", tags=[book_tag])
def get_book(body: BookForm):
    return {"year": body.year}


if __name__ == "__main__":
    app.run(debug=True)
```

```
pydantic_core._pydantic_core.ValidationError: 3 validation errors for Schema
properties.year.Reference.$ref
  Field required [type=missing, input_value={'exclusiveMaximum': 2030...ear', 'type': 'integer'}, input_type=dict]
    For further information visit https://errors.pydantic.dev/2.7/v/missing
properties.year.Schema.exclusiveMaximum
  Input should be a valid boolean, unable to interpret input [type=bool_parsing, input_value=2030, input_type=int]
    For further information visit https://errors.pydantic.dev/2.7/v/bool_parsing
properties.year.Schema.exclusiveMinimum
  Input should be a valid boolean, unable to interpret input [type=bool_parsing, input_value=2000, input_type=int]
    For further information visit https://errors.pydantic.dev/2.7/v/bool_parsing
```


Discussion / hints:

Fix patch:
diff --git a/flask_openapi3/models/schema.py b/flask_openapi3/models/schema.py
index 2181aed0..07ce754a 100644
--- a/flask_openapi3/models/schema.py
+++ b/flask_openapi3/models/schema.py
@@ -20,9 +20,9 @@ class Schema(BaseModel):
     title: Optional[str] = None
     multipleOf: Optional[float] = Field(default=None, gt=0.0)
     maximum: Optional[float] = None
-    exclusiveMaximum: Optional[bool] = None
+    exclusiveMaximum: Optional[float] = None
     minimum: Optional[float] = None
-    exclusiveMinimum: Optional[bool] = None
+    exclusiveMinimum: Optional[float] = None
     maxLength: Optional[int] = Field(default=None, ge=0)
     minLength: Optional[int] = Field(default=None, ge=0)
     pattern: Optional[str] = None


Test patch:
diff --git a/tests/test_number_constraints.py b/tests/test_number_constraints.py
new file mode 100644
index 00000000..198693e5
--- /dev/null
+++ b/tests/test_number_constraints.py
@@ -0,0 +1,42 @@
+# -*- coding: utf-8 -*-
+# @Author  : llc
+# @Time    : 2024/4/19 20:53
+
+import pytest
+from pydantic import BaseModel, Field
+
+from flask_openapi3 import OpenAPI
+
+app = OpenAPI(__name__)
+app.config["TESTING"] = True
+
+
+class MyModel(BaseModel):
+    num_1: int = Field(..., ge=1, le=10)
+    num_2: int = Field(..., gt=1, lt=10)
+
+
+@app.post('/book')
+def create_book(body: MyModel):
+    return body.dict()
+
+
+@pytest.fixture
+def client():
+    client = app.test_client()
+    return client
+
+
+def test_openapi(client):
+    resp = client.get("/openapi/openapi.json")
+    assert resp.status_code == 200
+    assert resp.json == app.api_doc
+
+    model_props = resp.json['components']['schemas']['MyModel']['properties']
+    num_1_props = model_props['num_1']
+    num_2_props = model_props['num_2']
+
+    assert num_1_props['minimum'] == 1
+    assert num_1_props['maximum'] == 10
+    assert num_2_props['exclusiveMinimum'] == 1
+    assert num_2_props['exclusiveMaximum'] == 10